playbook_ui 13.2.0 → 13.4.0.pre.alpha.PLAY973Hash1181
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/_playbook.scss +1 -0
- data/app/pb_kits/playbook/pb_body/_body.scss +5 -0
- data/app/pb_kits/playbook/pb_body/_body.tsx +4 -1
- data/app/pb_kits/playbook/pb_body/_body_mixins.scss +19 -0
- data/app/pb_kits/playbook/pb_body/body.rb +8 -1
- data/app/pb_kits/playbook/pb_button/button.html.erb +2 -2
- data/app/pb_kits/playbook/pb_button/button.rb +3 -0
- data/app/pb_kits/playbook/pb_card/card.rb +1 -1
- data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +1 -1
- data/app/pb_kits/playbook/pb_collapsible/child_kits/CollapsibleMain.tsx +5 -1
- data/app/pb_kits/playbook/pb_dashboard_value/dashboard_value.rb +2 -2
- data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +2 -2
- data/app/pb_kits/playbook/pb_file_upload/file_upload.rb +1 -1
- data/app/pb_kits/playbook/pb_kit/dateTime.ts +54 -23
- data/app/pb_kits/playbook/pb_passphrase/passphrase.rb +1 -1
- data/app/pb_kits/playbook/pb_radio/radio.rb +1 -1
- data/app/pb_kits/playbook/pb_select/select.rb +1 -1
- data/app/pb_kits/playbook/pb_selectable_card/selectable_card.rb +1 -1
- data/app/pb_kits/playbook/pb_selectable_card_icon/selectable_card_icon.rb +1 -1
- data/app/pb_kits/playbook/pb_selectable_icon/selectable_icon.rb +1 -1
- data/app/pb_kits/playbook/pb_selectable_list/selectable_list_item.rb +1 -1
- data/app/pb_kits/playbook/pb_source/source.rb +1 -1
- data/app/pb_kits/playbook/pb_table/docs/_table_header.html.erb +54 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_header.md +1 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_two_actions.jsx +3 -3
- data/app/pb_kits/playbook/pb_table/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_table/styles/_all.scss +1 -0
- data/app/pb_kits/playbook/pb_table/styles/_table_header.scss +31 -0
- data/app/pb_kits/playbook/pb_table/table_header.html.erb +64 -0
- data/app/pb_kits/playbook/pb_table/table_header.rb +53 -0
- data/app/pb_kits/playbook/pb_text_input/text_input.rb +2 -2
- data/app/pb_kits/playbook/pb_timestamp/_timestamp.tsx +14 -7
- data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_unstyled.html.erb +21 -0
- data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_unstyled.jsx +36 -0
- data/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_unstyled.md +1 -0
- data/app/pb_kits/playbook/pb_timestamp/docs/example.yml +3 -1
- data/app/pb_kits/playbook/pb_timestamp/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_timestamp/timestamp.html.erb +5 -1
- data/app/pb_kits/playbook/pb_timestamp/timestamp.rb +3 -1
- data/app/pb_kits/playbook/pb_title/_title.scss +8 -4
- data/app/pb_kits/playbook/pb_title/_title.tsx +4 -1
- data/app/pb_kits/playbook/pb_title/_title_mixin.scss +19 -0
- data/app/pb_kits/playbook/pb_title/title.rb +9 -2
- data/app/pb_kits/playbook/pb_toggle/toggle.rb +1 -1
- data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +1 -1
- data/app/pb_kits/playbook/tokens/_spacing.scss +1 -1
- data/app/pb_kits/playbook/tokens/_text_align.scss +18 -0
- data/app/pb_kits/playbook/utilities/_hover.scss +4 -0
- data/app/pb_kits/playbook/utilities/_max_width.scss +4 -0
- data/app/pb_kits/playbook/utilities/_spacing.scss +92 -49
- data/app/pb_kits/playbook/utilities/_text_align.scss +3 -0
- data/app/pb_kits/playbook/utilities/globalProps.ts +30 -2
- data/dist/playbook-rails.js +5 -5
- data/lib/playbook/classnames.rb +1 -0
- data/lib/playbook/hover.rb +6 -2
- data/lib/playbook/kit_base.rb +4 -2
- data/lib/playbook/props/hash.rb +1 -1
- data/lib/playbook/spacing.rb +13 -4
- data/lib/playbook/text_align.rb +37 -0
- data/lib/playbook/version.rb +2 -2
- metadata +18 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6d6551f1772a9fb33867a19c0226859cf491c986ccb503c2c7601588582d55c3
|
|
4
|
+
data.tar.gz: 86d1ebafb210c29139963d232e1c52d071ca862cde8aaa283420e756fc39aaab
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2aabad2326332a49ce487e0ab62d606c76c53bab395b3f04d3aa396342afca0ec57a941fb032da36a6eb13b1a73cff2a0e522256de643fb0bc3ea375f71a4088
|
|
7
|
+
data.tar.gz: 414ad28883507217cc57ed460ad78c83188d0b94d87a7ce8964409d89554af5260e5053b5ff02fbe71149bf3de1a933deff958d82d77e5192fa4db1e67813d53
|
|
@@ -37,10 +37,15 @@
|
|
|
37
37
|
font-size: $font_smaller;
|
|
38
38
|
letter-spacing: $lspace_loose;
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
&[class*=_truncate] {
|
|
42
|
+
@include body_truncate;
|
|
43
|
+
}
|
|
40
44
|
|
|
41
45
|
@each $status_name, $status_value in $pb_body_status {
|
|
42
46
|
&[class*=#{$status_name}] {
|
|
43
47
|
@include pb_body($status_value);
|
|
48
|
+
@include body_truncate;
|
|
44
49
|
}
|
|
45
50
|
}
|
|
46
51
|
|
|
@@ -19,6 +19,7 @@ type BodyProps = {
|
|
|
19
19
|
status?: 'neutral' | 'negative' | 'positive',
|
|
20
20
|
tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div',
|
|
21
21
|
text?: string,
|
|
22
|
+
truncate?: null | '1' | '2' | '3' | '4' | '5',
|
|
22
23
|
variant?: null | 'link',
|
|
23
24
|
} & GlobalProps
|
|
24
25
|
|
|
@@ -36,13 +37,15 @@ const Body = (props: BodyProps): React.ReactElement => {
|
|
|
36
37
|
status = null,
|
|
37
38
|
tag = 'div',
|
|
38
39
|
text = '',
|
|
40
|
+
truncate = null,
|
|
39
41
|
variant = null,
|
|
40
42
|
} = props
|
|
41
43
|
|
|
42
44
|
const ariaProps: {[key: string]: any} = buildAriaProps(aria)
|
|
43
45
|
const dataProps: {[key: string]: any} = buildDataProps(data)
|
|
46
|
+
const isTruncated = truncate ? `truncate_${truncate}` : ''
|
|
44
47
|
const classes = classnames(
|
|
45
|
-
buildCss('pb_body_kit', color, variant, status),
|
|
48
|
+
buildCss('pb_body_kit', color, variant, status, isTruncated),
|
|
46
49
|
globalProps(props),
|
|
47
50
|
className
|
|
48
51
|
)
|
|
@@ -36,6 +36,25 @@ $pb_body_status: (
|
|
|
36
36
|
font-family: $font-family-base;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
$pb_body_truncate: (
|
|
40
|
+
truncate_1: 1,
|
|
41
|
+
truncate_2: 2,
|
|
42
|
+
truncate_3: 3,
|
|
43
|
+
truncate_4: 4,
|
|
44
|
+
truncate_5: 5
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
@mixin body_truncate {
|
|
48
|
+
@each $name, $number in $pb_body_truncate {
|
|
49
|
+
&[class*=_#{$name}] {
|
|
50
|
+
overflow: hidden;
|
|
51
|
+
display: -webkit-box;
|
|
52
|
+
-webkit-line-clamp: $number;
|
|
53
|
+
-webkit-box-orient: vertical;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
39
58
|
|
|
40
59
|
// Colors ======================
|
|
41
60
|
@mixin pb_body_light {
|
|
@@ -18,9 +18,12 @@ module Playbook
|
|
|
18
18
|
default: false
|
|
19
19
|
prop :highlighted_text, type: Playbook::Props::Array,
|
|
20
20
|
default: []
|
|
21
|
+
prop :truncate, type: Playbook::Props::Enum,
|
|
22
|
+
values: [nil, "1", "2", "3", "4", "5"],
|
|
23
|
+
default: nil
|
|
21
24
|
|
|
22
25
|
def classname
|
|
23
|
-
generate_classname("pb_body_kit", color_class, status_class)
|
|
26
|
+
generate_classname("pb_body_kit", color_class, status_class, is_truncated)
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
def content
|
|
@@ -28,6 +31,10 @@ module Playbook
|
|
|
28
31
|
highlighting ? apply_highlight(body_text) : body_text
|
|
29
32
|
end
|
|
30
33
|
|
|
34
|
+
def is_truncated
|
|
35
|
+
truncate ? "truncate_#{truncate}" : nil
|
|
36
|
+
end
|
|
37
|
+
|
|
31
38
|
private
|
|
32
39
|
|
|
33
40
|
def apply_highlight(text)
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
<% else %>
|
|
19
19
|
<% if object.icon && !object.icon_right %>
|
|
20
20
|
<span>
|
|
21
|
-
<%= pb_rails("icon", props: { icon: "#{icon}", fixed_width: true, margin_right: "xs" }) %>
|
|
21
|
+
<%= pb_rails("icon", props: { icon: "#{icon}", fixed_width: true, margin_right: "xs", font_style: object.icon_font_family }) %>
|
|
22
22
|
</span>
|
|
23
23
|
<% end %>
|
|
24
24
|
<%= pb_rails("icon", props: { icon: "spinner", pulse: true, fixed_width: true, classname: "loading-icon" }) %>
|
|
25
25
|
<span class="pb_button_content"><%= content.presence || object.text %></span>
|
|
26
26
|
<% if object.icon && object.icon_right %>
|
|
27
27
|
<span>
|
|
28
|
-
<%= pb_rails("icon", props: { icon: "#{icon}", fixed_width: true, margin_left: "xs" }) %>
|
|
28
|
+
<%= pb_rails("icon", props: { icon: "#{icon}", fixed_width: true, margin_left: "xs", font_style: object.icon_font_family }) %>
|
|
29
29
|
</span>
|
|
30
30
|
<% end %>
|
|
31
31
|
<% end %>
|
|
@@ -4,7 +4,7 @@ module Playbook
|
|
|
4
4
|
module PbCard
|
|
5
5
|
class Card < Playbook::KitBase
|
|
6
6
|
prop :selected, type: Playbook::Props::Boolean, default: false
|
|
7
|
-
prop :highlight, type: Playbook::Props::
|
|
7
|
+
prop :highlight, type: Playbook::Props::HashProp,
|
|
8
8
|
default: {}
|
|
9
9
|
prop :tag, type: Playbook::Props::Enum,
|
|
10
10
|
values: %w[div section footer header article aside main nav],
|
|
@@ -99,8 +99,12 @@ const CollapsibleMain = ({
|
|
|
99
99
|
const mainSpacing = globalProps(props, { cursor })
|
|
100
100
|
|
|
101
101
|
const handleCollapsibleClick = () => {
|
|
102
|
+
onClick && onClick();
|
|
103
|
+
//To disable default toggling behavior return "true" in the onClick()
|
|
104
|
+
const disableToggle = onClick && onClick();
|
|
105
|
+
if (disableToggle !== true) {
|
|
102
106
|
toggle();
|
|
103
|
-
|
|
107
|
+
}
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
return (
|
|
@@ -6,10 +6,10 @@ module Playbook
|
|
|
6
6
|
prop :align, type: Playbook::Props::Enum,
|
|
7
7
|
values: %w[left center right],
|
|
8
8
|
default: "left"
|
|
9
|
-
prop :stat_change, type: Playbook::Props::
|
|
9
|
+
prop :stat_change, type: Playbook::Props::HashProp,
|
|
10
10
|
default: {}
|
|
11
11
|
prop :stat_label
|
|
12
|
-
prop :stat_value, type: Playbook::Props::
|
|
12
|
+
prop :stat_value, type: Playbook::Props::HashProp,
|
|
13
13
|
default: {}
|
|
14
14
|
|
|
15
15
|
def formatted_stat_value
|
|
@@ -34,9 +34,9 @@ module Playbook
|
|
|
34
34
|
default: false
|
|
35
35
|
prop :label, type: Playbook::Props::String,
|
|
36
36
|
default: "Date Picker"
|
|
37
|
-
prop :input_aria, type: Playbook::Props::
|
|
37
|
+
prop :input_aria, type: Playbook::Props::HashProp,
|
|
38
38
|
default: {}
|
|
39
|
-
prop :input_data, type: Playbook::Props::
|
|
39
|
+
prop :input_data, type: Playbook::Props::HashProp,
|
|
40
40
|
default: {}
|
|
41
41
|
prop :max_date, type: Playbook::Props::String
|
|
42
42
|
prop :min_date, type: Playbook::Props::String
|
|
@@ -121,30 +121,61 @@ export const toIso = (newDate: Date | string): string => {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
export const fromNow = (newDate: Date | string): string => {
|
|
124
|
-
const
|
|
125
|
-
const
|
|
124
|
+
const today = new Date()
|
|
125
|
+
const formattedDate = formatDate(newDate)
|
|
126
|
+
|
|
127
|
+
const startDate = formattedDate.getTime()
|
|
128
|
+
const endDate = today.getTime()
|
|
126
129
|
const elapsedTime = endDate - startDate
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
130
|
+
|
|
131
|
+
// For years/months, don't use elapsedTime due to rounding
|
|
132
|
+
const differenceInYears = today.getFullYear() - formattedDate.getFullYear()
|
|
133
|
+
const differenceInMonths = () => {
|
|
134
|
+
let months = differenceInYears * 12
|
|
135
|
+
months -= formattedDate.getMonth()
|
|
136
|
+
months += today.getMonth()
|
|
137
|
+
return months
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const FORTY_FIVE_SECONDS = 45000
|
|
141
|
+
const NINETY_SECONDS = 90000
|
|
142
|
+
|
|
143
|
+
const FORTY_FIVE_MINUTES = 2670000
|
|
144
|
+
const NINETY_MINUTES = 5400000
|
|
145
|
+
|
|
146
|
+
const TWENTY_TWO_HOURS = 77400000
|
|
147
|
+
const THIRTY_SIX_HOURS = 129600000
|
|
148
|
+
|
|
149
|
+
const TWENTY_SIX_DAYS = 2203200000
|
|
150
|
+
const FORTY_FIVE_DAYS = 3888000000
|
|
151
|
+
|
|
152
|
+
const TEN_AND_A_HALF_MONTHS = 27560000000
|
|
153
|
+
|
|
154
|
+
const MILLISECONDS_IN_A_MINUTE = 60000
|
|
155
|
+
const MILLISECONDS_IN_A_HOUR = 3600000
|
|
156
|
+
const MILLISECONDS_IN_A_DAY = 86400000
|
|
157
|
+
|
|
158
|
+
let elapsedTimeString = differenceInYears === 1 ? `${differenceInYears} year ago` : `${differenceInYears} years ago` // 320 days to 1+ year: "x year(s) ago"
|
|
159
|
+
|
|
160
|
+
// Inspiration: https://momentjs.com/docs/#/displaying/fromnow/
|
|
161
|
+
const intervals = [
|
|
162
|
+
{ min: 0, max: FORTY_FIVE_SECONDS, value: "a few seconds ago" }, // 0-44.99 seconds
|
|
163
|
+
{ min: FORTY_FIVE_SECONDS, max: NINETY_SECONDS, value: "a minute ago" }, // 45-89.99 seconds
|
|
164
|
+
{ min: NINETY_SECONDS, max: FORTY_FIVE_MINUTES, value: `${Math.round(elapsedTime / MILLISECONDS_IN_A_MINUTE)} minutes ago` }, // 90s-44.49 minutes: "2 minutes ago ... 44 minutes ago"
|
|
165
|
+
{ min: FORTY_FIVE_MINUTES, max: NINETY_MINUTES, value: "an hour ago" }, // 44.5-89.99 minutes
|
|
166
|
+
{ min: NINETY_MINUTES, max: TWENTY_TWO_HOURS, value: `${Math.round(elapsedTime / MILLISECONDS_IN_A_HOUR)} hours ago` }, // 90m-21.49 hours: "2 hours ago ... 21 hours ago"
|
|
167
|
+
{ min: TWENTY_TWO_HOURS, max: THIRTY_SIX_HOURS, value: "a day ago" }, // 21.5-35.99 hours
|
|
168
|
+
{ min: THIRTY_SIX_HOURS, max: TWENTY_SIX_DAYS, value: `${Math.round(elapsedTime / MILLISECONDS_IN_A_DAY)} days ago` }, // 36h-25.49 days: "2 days ago ... 25 days ago"
|
|
169
|
+
{ min: TWENTY_SIX_DAYS, max: FORTY_FIVE_DAYS, value: "a month ago" }, // 25.5-44.99 days
|
|
170
|
+
{ min: FORTY_FIVE_DAYS, max: TEN_AND_A_HALF_MONTHS, value: `${differenceInMonths()} months ago` }, // 45 days to 319 days: "2 months ago ... 10 months ago"
|
|
171
|
+
]
|
|
172
|
+
|
|
173
|
+
for (const interval of intervals) {
|
|
174
|
+
const { min, max, value } = interval
|
|
175
|
+
|
|
176
|
+
if (elapsedTime >= min && elapsedTime < max) {
|
|
177
|
+
elapsedTimeString = value
|
|
178
|
+
break
|
|
148
179
|
}
|
|
149
180
|
}
|
|
150
181
|
|
|
@@ -4,7 +4,7 @@ module Playbook
|
|
|
4
4
|
module PbPassphrase
|
|
5
5
|
class Passphrase < Playbook::KitBase
|
|
6
6
|
prop :confirmation, type: Playbook::Props::Boolean, default: false
|
|
7
|
-
prop :input_props, type: Playbook::Props::
|
|
7
|
+
prop :input_props, type: Playbook::Props::HashProp, default: {}
|
|
8
8
|
prop :label
|
|
9
9
|
prop :show_tips_below, type: Playbook::Props::Enum,
|
|
10
10
|
values: %w[always xs sm md lg xl],
|
|
@@ -11,7 +11,7 @@ module Playbook
|
|
|
11
11
|
default: false
|
|
12
12
|
prop :error, type: Playbook::Props::Boolean,
|
|
13
13
|
default: false
|
|
14
|
-
prop :input_options, type: Playbook::Props::
|
|
14
|
+
prop :input_options, type: Playbook::Props::HashProp,
|
|
15
15
|
default: {}
|
|
16
16
|
prop :name, type: Playbook::Props::String,
|
|
17
17
|
default: "radio_name"
|
|
@@ -6,7 +6,7 @@ require "action_view"
|
|
|
6
6
|
module Playbook
|
|
7
7
|
module PbSelect
|
|
8
8
|
class Select < Playbook::KitBase
|
|
9
|
-
prop :attributes, type: Playbook::Props::
|
|
9
|
+
prop :attributes, type: Playbook::Props::HashProp,
|
|
10
10
|
default: {}
|
|
11
11
|
prop :blank_selection
|
|
12
12
|
prop :compact, type: Playbook::Props::Boolean, default: false
|
|
@@ -10,7 +10,7 @@ module Playbook
|
|
|
10
10
|
prop :type, type: Playbook::Props::Enum,
|
|
11
11
|
values: %w[user retail inbound outbound prospecting events referral],
|
|
12
12
|
default: "inbound"
|
|
13
|
-
prop :user, type: Playbook::Props::
|
|
13
|
+
prop :user, type: Playbook::Props::HashProp, default: {}
|
|
14
14
|
|
|
15
15
|
def type_text
|
|
16
16
|
if type == "user" || (type == "referral" && user.present?)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<%= pb_rails("table", props: { size: "lg"} ) do %>
|
|
2
|
+
<thead>
|
|
3
|
+
<tr>
|
|
4
|
+
<%= pb_rails("table/table_header", props: {
|
|
5
|
+
id: "name",
|
|
6
|
+
colspan: 2,
|
|
7
|
+
sort_menu: [
|
|
8
|
+
{ item: "Name", link: "?q[sorts]=name+desc", active: false, direction: "desc" },
|
|
9
|
+
{ item: "Name", link: "?q[sorts]=name+asc", active: true, direction: "asc" },
|
|
10
|
+
],
|
|
11
|
+
}) %>
|
|
12
|
+
<%= pb_rails("table/table_header", props: {
|
|
13
|
+
text: "Age",
|
|
14
|
+
id: "age",
|
|
15
|
+
sort_menu: [
|
|
16
|
+
{ item: "Age", link: "?q[sorts]=age+desc", active: false, direction: "desc" },
|
|
17
|
+
{ item: "Age", link: "?q[sorts]=age+asc", active: false, direction: "asc" },
|
|
18
|
+
],
|
|
19
|
+
}) %>
|
|
20
|
+
<%= pb_rails("table/table_header", props: {
|
|
21
|
+
text: "Territory",
|
|
22
|
+
id: "territory",
|
|
23
|
+
sort_menu: [
|
|
24
|
+
{ item: "Territory", link: "?q[sorts]=territory+desc", active: false, direction: "desc" },
|
|
25
|
+
{ item: "Territory", link: "?q[sorts]=territory+asc", active: false, direction: "asc" },
|
|
26
|
+
],
|
|
27
|
+
}) %>
|
|
28
|
+
<%= pb_rails("table/table_header", props: { text: "Job Title" }) %>
|
|
29
|
+
</tr>
|
|
30
|
+
</thead>
|
|
31
|
+
<tbody>
|
|
32
|
+
<tr>
|
|
33
|
+
<td>Name 1</td>
|
|
34
|
+
<td>Name 2</td>
|
|
35
|
+
<td>Value 3</td>
|
|
36
|
+
<td>Value 4</td>
|
|
37
|
+
<td>Value 5</td>
|
|
38
|
+
</tr>
|
|
39
|
+
<tr>
|
|
40
|
+
<td>Name 1</td>
|
|
41
|
+
<td>Name 2</td>
|
|
42
|
+
<td>Value 3</td>
|
|
43
|
+
<td>Value 4</td>
|
|
44
|
+
<td>Value 5</td>
|
|
45
|
+
</tr>
|
|
46
|
+
<tr>
|
|
47
|
+
<td>Name 1</td>
|
|
48
|
+
<td>Name 2</td>
|
|
49
|
+
<td>Value 3</td>
|
|
50
|
+
<td>Value 4</td>
|
|
51
|
+
<td>Value 5</td>
|
|
52
|
+
</tr>
|
|
53
|
+
</tbody>
|
|
54
|
+
<% end %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
A kit that produces a `<th>` tag. You can also use the `sort_menu` prop to make the header a sortable link, just like <a href="https://playbook.powerapp.cloud/kits/filter#sort-only" target="_blank">our filter kit.</a>
|
|
@@ -28,7 +28,7 @@ const TableOneAction = (props) => {
|
|
|
28
28
|
<Button
|
|
29
29
|
onClick={() => alert('button clicked!')}
|
|
30
30
|
paddingLeft="none"
|
|
31
|
-
text="
|
|
31
|
+
text="Tertiary Action"
|
|
32
32
|
variant="link"
|
|
33
33
|
{...props}
|
|
34
34
|
/>
|
|
@@ -49,7 +49,7 @@ const TableOneAction = (props) => {
|
|
|
49
49
|
<Button
|
|
50
50
|
onClick={() => alert('button clicked!')}
|
|
51
51
|
paddingLeft="none"
|
|
52
|
-
text="
|
|
52
|
+
text="Tertiary Action"
|
|
53
53
|
variant="link"
|
|
54
54
|
{...props}
|
|
55
55
|
/>
|
|
@@ -70,7 +70,7 @@ const TableOneAction = (props) => {
|
|
|
70
70
|
<Button
|
|
71
71
|
onClick={() => alert('button clicked!')}
|
|
72
72
|
paddingLeft="none"
|
|
73
|
-
text="
|
|
73
|
+
text="Tertiary Action"
|
|
74
74
|
variant="link"
|
|
75
75
|
{...props}
|
|
76
76
|
/>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
$text_align_values: (
|
|
3
|
+
start: start,
|
|
4
|
+
end: end,
|
|
5
|
+
left: left,
|
|
6
|
+
right: right,
|
|
7
|
+
center: center,
|
|
8
|
+
justify: justify,
|
|
9
|
+
justify-all: justify-all,
|
|
10
|
+
match-parent: match-parent,
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
[class^=pb_table] {
|
|
14
|
+
thead {
|
|
15
|
+
[class^=pb_table_header_kit] {
|
|
16
|
+
@each $align_name, $align_value in $text_align_values {
|
|
17
|
+
&[class*=_align_#{$align_name}] {
|
|
18
|
+
text-align: $align_value;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
[class^=pb_table] {
|
|
26
|
+
thead {
|
|
27
|
+
[class^=pb_th_active] {
|
|
28
|
+
color: $primary !important;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<%= content_tag(:th,
|
|
2
|
+
colspan: object.colspan,
|
|
3
|
+
aria: object.aria,
|
|
4
|
+
class: object.classname,
|
|
5
|
+
data: object.data,
|
|
6
|
+
id: "pb-th#{object.id}") do %>
|
|
7
|
+
<% object.sort_menu.each do |item| %>
|
|
8
|
+
<% if item[:active] == true %>
|
|
9
|
+
<%= pb_rails("flex", props:{ align: object.align_content }) do %>
|
|
10
|
+
<%= content.presence || content_tag(:span, item[:item], class: "pb_th_active") %>
|
|
11
|
+
<span class="pb_th_active">
|
|
12
|
+
<%= pb_rails("icon", props: { icon: object.sort_icon(item[:direction]),
|
|
13
|
+
fixed_width: true,
|
|
14
|
+
classname: "pb_th_active",
|
|
15
|
+
padding_left: "xs" }) %>
|
|
16
|
+
</span>
|
|
17
|
+
<% end %>
|
|
18
|
+
<% end %>
|
|
19
|
+
<% end %>
|
|
20
|
+
<% if object.sort_menu.all? { |item| item[:active] == false } %>
|
|
21
|
+
<%= pb_rails("flex", props:{ align: object.align_content }) do %>
|
|
22
|
+
<%= content.presence || object.text %>
|
|
23
|
+
<%= pb_rails("icon", props: { icon: "arrow-up-arrow-down",
|
|
24
|
+
fixed_width: true,
|
|
25
|
+
padding_left: "xs" }) %>
|
|
26
|
+
<% end %>
|
|
27
|
+
<% else %>
|
|
28
|
+
<%= content.presence || object.text %>
|
|
29
|
+
<% end %>
|
|
30
|
+
<% if object.sort_menu != [{}] && object.colspan > 1 %>
|
|
31
|
+
<%= pb_rails("popover", props: { classname: "pb_filter_sort_menu",
|
|
32
|
+
close_on_click: "outside",
|
|
33
|
+
trigger_element_id: "pb-th#{object.id}",
|
|
34
|
+
tooltip_id: "sort-filter-btn-tooltip#{object.id}",
|
|
35
|
+
position: object.placement ,
|
|
36
|
+
padding: 'none'}) do %>
|
|
37
|
+
<%= pb_rails("list") do %>
|
|
38
|
+
<% object.sort_menu.each do |item| %>
|
|
39
|
+
<%= pb_rails("list/item") do %>
|
|
40
|
+
<%= pb_rails("button", props: { variant: "link" ,
|
|
41
|
+
classname: "p-0",
|
|
42
|
+
text: item[:item],
|
|
43
|
+
link: item[:link],
|
|
44
|
+
icon: sort_icon(item[:direction]),
|
|
45
|
+
icon_right: true }) %>
|
|
46
|
+
<% end %>
|
|
47
|
+
<% end %>
|
|
48
|
+
<% end %>
|
|
49
|
+
<% end %>
|
|
50
|
+
<% end %>
|
|
51
|
+
<% end %>
|
|
52
|
+
<% if object.sort_menu != [{}] && object.colspan == 1 %>
|
|
53
|
+
<script>
|
|
54
|
+
document.addEventListener("DOMContentLoaded", function() {
|
|
55
|
+
var thId = `<%= "#pb-th#{object.id}" %>`
|
|
56
|
+
var firstLink = `<%= next_link %>`
|
|
57
|
+
var thElement = document.querySelector(thId);
|
|
58
|
+
|
|
59
|
+
thElement.addEventListener("click", function() {
|
|
60
|
+
window.location.href = firstLink;
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
</script>
|
|
64
|
+
<% end %>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Playbook
|
|
4
|
+
module PbTable
|
|
5
|
+
class TableHeader < Playbook::KitBase
|
|
6
|
+
prop :align, type: Playbook::Props::Enum,
|
|
7
|
+
values: %w[start center end stretch baseline none],
|
|
8
|
+
default: "start"
|
|
9
|
+
prop :align_content, type: Playbook::Props::Enum,
|
|
10
|
+
values: %w[start center end stretch baseline none],
|
|
11
|
+
default: "center"
|
|
12
|
+
prop :colspan, type: Playbook::Props::Number,
|
|
13
|
+
default: 1
|
|
14
|
+
prop :placement, type: Playbook::Props::Enum,
|
|
15
|
+
values: %w[top bottom left right top-start top-end bottom-start bottom-end right-start right-end left-start left-end],
|
|
16
|
+
default: "bottom-start"
|
|
17
|
+
prop :sort_menu, type: Playbook::Props::HashArray,
|
|
18
|
+
default: [{}]
|
|
19
|
+
prop :text, type: Playbook::Props::String,
|
|
20
|
+
default: ""
|
|
21
|
+
|
|
22
|
+
def classname
|
|
23
|
+
generate_classname("pb_table_header_kit", align_class)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def align_class
|
|
27
|
+
align.present? ? "align_#{align}" : nil
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def next_link
|
|
31
|
+
return sort_menu[0][:link] if sort_menu.all? { |item| item[:active] == false }
|
|
32
|
+
|
|
33
|
+
sort_menu.each_with_index do |item, index|
|
|
34
|
+
if item[:active] == true
|
|
35
|
+
next_index = (index + 1) % sort_menu.length
|
|
36
|
+
sort_menu[next_index][:link]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def sort_icon(direction)
|
|
42
|
+
case direction
|
|
43
|
+
when "asc"
|
|
44
|
+
"sort-amount-up"
|
|
45
|
+
when "desc"
|
|
46
|
+
"sort-amount-down"
|
|
47
|
+
else
|
|
48
|
+
""
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|