primer_view_components 0.0.61 → 0.0.62
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +44 -2
- data/app/components/primer/alpha/border_box/header.rb +1 -2
- data/app/components/primer/alpha/button_marketing.rb +4 -4
- data/app/components/primer/alpha/tab_nav.rb +1 -1
- data/app/components/primer/alpha/tab_panels.rb +2 -2
- data/app/components/primer/alpha/underline_nav.rb +2 -1
- data/app/components/primer/alpha/underline_panels.rb +2 -2
- data/app/components/primer/base_component.rb +8 -36
- data/app/components/primer/beta/auto_complete/item.rb +1 -1
- data/app/components/primer/beta/auto_complete.rb +4 -2
- data/app/components/primer/beta/avatar.rb +1 -1
- data/app/components/primer/beta/blankslate.html.erb +2 -2
- data/app/components/primer/beta/blankslate.rb +6 -3
- data/app/components/primer/beta/breadcrumbs.rb +2 -2
- data/app/components/primer/beta/text.rb +1 -1
- data/app/components/primer/border_box_component.rb +1 -1
- data/app/components/primer/box_component.rb +3 -2
- data/app/components/primer/button_component.html.erb +3 -9
- data/app/components/primer/button_component.rb +21 -2
- data/app/components/primer/button_group.rb +1 -1
- data/app/components/primer/clipboard_copy.rb +1 -1
- data/app/components/primer/close_button.rb +1 -1
- data/app/components/primer/component.rb +71 -0
- data/app/components/primer/counter_component.rb +1 -1
- data/app/components/primer/details_component.rb +1 -1
- data/app/components/primer/dropdown/menu.rb +1 -1
- data/app/components/primer/dropdown.html.erb +0 -1
- data/app/components/primer/dropdown.rb +1 -0
- data/app/components/primer/dropdown_menu_component.rb +1 -1
- data/app/components/primer/flash_component.rb +2 -1
- data/app/components/primer/flex_component.rb +16 -16
- data/app/components/primer/flex_item_component.rb +1 -1
- data/app/components/primer/hellip_button.rb +1 -1
- data/app/components/primer/hidden_text_expander.rb +1 -1
- data/app/components/primer/image.rb +1 -1
- data/app/components/primer/image_crop.rb +2 -1
- data/app/components/primer/layout_component.rb +1 -0
- data/app/components/primer/local_time.rb +1 -1
- data/app/components/primer/markdown.rb +1 -1
- data/app/components/primer/menu_component.rb +2 -1
- data/app/components/primer/navigation/tab_component.rb +1 -0
- data/app/components/primer/octicon_symbols_component.rb +2 -2
- data/app/components/primer/popover_component.rb +1 -1
- data/app/components/primer/progress_bar_component.rb +7 -6
- data/app/components/primer/spinner_component.rb +1 -1
- data/app/components/primer/subhead_component.rb +3 -1
- data/app/components/primer/tab_container_component.rb +1 -1
- data/app/components/primer/time_ago_component.rb +1 -1
- data/app/components/primer/timeline_item_component.rb +4 -3
- data/app/components/primer/tooltip.rb +1 -0
- data/lib/primer/classify/utilities.rb +26 -23
- data/lib/primer/classify/utilities.yml +192 -68
- data/lib/primer/classify.rb +92 -178
- data/lib/primer/view_components/linters/blankslate_api_migration.rb +11 -5
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/rubocop/cop/primer/deprecated_layout_component.rb +30 -0
- data/lib/rubocop/cop/primer/primer_octicon.rb +1 -3
- data/lib/tasks/custom_utilities.yml +192 -0
- data/lib/tasks/docs.rake +1 -1
- data/lib/tasks/utilities.rake +6 -2
- data/static/classes.yml +14 -14
- data/static/constants.json +3 -3
- metadata +4 -4
- data/lib/primer/classify/cache.rb +0 -109
- data/lib/primer/classify/flex.rb +0 -111
@@ -47,38 +47,6 @@
|
|
47
47
|
- color-fg-on-emphasis
|
48
48
|
:inherit:
|
49
49
|
- color-fg-inherit
|
50
|
-
:text_primary:
|
51
|
-
- color-text-primary
|
52
|
-
:text_secondary:
|
53
|
-
- color-text-secondary
|
54
|
-
:text_tertiary:
|
55
|
-
- color-text-tertiary
|
56
|
-
:text_link:
|
57
|
-
- color-text-link
|
58
|
-
:text_success:
|
59
|
-
- color-text-success
|
60
|
-
:text_warning:
|
61
|
-
- color-text-warning
|
62
|
-
:text_danger:
|
63
|
-
- color-text-danger
|
64
|
-
:text_inverse:
|
65
|
-
- color-text-inverse
|
66
|
-
:text_white:
|
67
|
-
- color-text-white
|
68
|
-
:icon_primary:
|
69
|
-
- color-icon-primary
|
70
|
-
:icon_secondary:
|
71
|
-
- color-icon-secondary
|
72
|
-
:icon_tertiary:
|
73
|
-
- color-icon-tertiary
|
74
|
-
:icon_info:
|
75
|
-
- color-icon-info
|
76
|
-
:icon_danger:
|
77
|
-
- color-icon-danger
|
78
|
-
:icon_success:
|
79
|
-
- color-icon-success
|
80
|
-
:icon_warning:
|
81
|
-
- color-icon-warning
|
82
50
|
:bg:
|
83
51
|
:default:
|
84
52
|
- color-bg-default
|
@@ -118,30 +86,6 @@
|
|
118
86
|
- color-bg-sponsors
|
119
87
|
:sponsors_emphasis:
|
120
88
|
- color-bg-sponsors-emphasis
|
121
|
-
:canvas:
|
122
|
-
- color-bg-canvas
|
123
|
-
:canvas_inverse:
|
124
|
-
- color-bg-canvas-inverse
|
125
|
-
:canvas_inset:
|
126
|
-
- color-bg-canvas-inset
|
127
|
-
:primary:
|
128
|
-
- color-bg-primary
|
129
|
-
:secondary:
|
130
|
-
- color-bg-secondary
|
131
|
-
:tertiary:
|
132
|
-
- color-bg-tertiary
|
133
|
-
:info:
|
134
|
-
- color-bg-info
|
135
|
-
:info_inverse:
|
136
|
-
- color-bg-info-inverse
|
137
|
-
:danger_inverse:
|
138
|
-
- color-bg-danger-inverse
|
139
|
-
:success_inverse:
|
140
|
-
- color-bg-success-inverse
|
141
|
-
:warning:
|
142
|
-
- color-bg-warning
|
143
|
-
:warning_inverse:
|
144
|
-
- color-bg-warning-inverse
|
145
89
|
:border_color:
|
146
90
|
:default:
|
147
91
|
- color-border-default
|
@@ -177,18 +121,6 @@
|
|
177
121
|
- color-border-sponsors
|
178
122
|
:sponsors_emphasis:
|
179
123
|
- color-border-sponsors-emphasis
|
180
|
-
:primary:
|
181
|
-
- color-border-primary
|
182
|
-
:secondary:
|
183
|
-
- color-border-secondary
|
184
|
-
:tertiary:
|
185
|
-
- color-border-tertiary
|
186
|
-
:inverse:
|
187
|
-
- color-border-inverse
|
188
|
-
:info:
|
189
|
-
- color-border-info
|
190
|
-
:warning:
|
191
|
-
- color-border-warning
|
192
124
|
:position:
|
193
125
|
:static:
|
194
126
|
- position-static
|
@@ -1545,3 +1477,195 @@
|
|
1545
1477
|
- col-md-12
|
1546
1478
|
- col-lg-12
|
1547
1479
|
- col-xl-12
|
1480
|
+
:font_size:
|
1481
|
+
'00':
|
1482
|
+
- f00
|
1483
|
+
1:
|
1484
|
+
- f1
|
1485
|
+
2:
|
1486
|
+
- f2
|
1487
|
+
3:
|
1488
|
+
- f3
|
1489
|
+
4:
|
1490
|
+
- f4
|
1491
|
+
5:
|
1492
|
+
- f5
|
1493
|
+
6:
|
1494
|
+
- f6
|
1495
|
+
:small:
|
1496
|
+
- text-small
|
1497
|
+
:normal:
|
1498
|
+
- text-normal
|
1499
|
+
:top:
|
1500
|
+
false:
|
1501
|
+
- top-0
|
1502
|
+
:bottom:
|
1503
|
+
false:
|
1504
|
+
- bottom-0
|
1505
|
+
:left:
|
1506
|
+
false:
|
1507
|
+
- left-0
|
1508
|
+
:right:
|
1509
|
+
false:
|
1510
|
+
- right-0
|
1511
|
+
:underline:
|
1512
|
+
true:
|
1513
|
+
- text-underline
|
1514
|
+
false:
|
1515
|
+
- no-underline
|
1516
|
+
:font_family:
|
1517
|
+
:mono:
|
1518
|
+
- text-mono
|
1519
|
+
:font_style:
|
1520
|
+
:italic:
|
1521
|
+
- text-italic
|
1522
|
+
:text_transform:
|
1523
|
+
:uppercase:
|
1524
|
+
- text-uppercase
|
1525
|
+
:text_align:
|
1526
|
+
:right:
|
1527
|
+
- text-right
|
1528
|
+
:left:
|
1529
|
+
- text-left
|
1530
|
+
:center:
|
1531
|
+
- text-center
|
1532
|
+
:font_weight:
|
1533
|
+
:light:
|
1534
|
+
- text-light
|
1535
|
+
:normal:
|
1536
|
+
- text-normal
|
1537
|
+
:bold:
|
1538
|
+
- text-bold
|
1539
|
+
:semibold:
|
1540
|
+
- text-semibold
|
1541
|
+
:emphasized:
|
1542
|
+
- text-emphasized
|
1543
|
+
:box_shadow:
|
1544
|
+
true:
|
1545
|
+
- color-shadow-small
|
1546
|
+
:small:
|
1547
|
+
- color-shadow-small
|
1548
|
+
:medium:
|
1549
|
+
- color-shadow-medium
|
1550
|
+
:large:
|
1551
|
+
- color-shadow-large
|
1552
|
+
:extra_large:
|
1553
|
+
- color-shadow-extra-large
|
1554
|
+
:none:
|
1555
|
+
- box-shadow-none
|
1556
|
+
false:
|
1557
|
+
- box-shadow-none
|
1558
|
+
:border:
|
1559
|
+
:left:
|
1560
|
+
- border-left
|
1561
|
+
:top:
|
1562
|
+
- border-top
|
1563
|
+
:bottom:
|
1564
|
+
- border-bottom
|
1565
|
+
:right:
|
1566
|
+
- border-right
|
1567
|
+
:y:
|
1568
|
+
- border-y
|
1569
|
+
:x:
|
1570
|
+
- border-x
|
1571
|
+
true:
|
1572
|
+
- border
|
1573
|
+
:border_top:
|
1574
|
+
0:
|
1575
|
+
- border-top-0
|
1576
|
+
:border_bottom:
|
1577
|
+
0:
|
1578
|
+
- border-bottom-0
|
1579
|
+
:border_left:
|
1580
|
+
0:
|
1581
|
+
- border-left-0
|
1582
|
+
:border_right:
|
1583
|
+
0:
|
1584
|
+
- border-right-0
|
1585
|
+
:border_radius:
|
1586
|
+
0:
|
1587
|
+
- rounded-0
|
1588
|
+
1:
|
1589
|
+
- rounded-1
|
1590
|
+
2:
|
1591
|
+
- rounded-2
|
1592
|
+
3:
|
1593
|
+
- rounded-3
|
1594
|
+
:justify_content:
|
1595
|
+
:flex_start:
|
1596
|
+
- flex-justify-start
|
1597
|
+
:flex_end:
|
1598
|
+
- flex-justify-end
|
1599
|
+
:center:
|
1600
|
+
- flex-justify-center
|
1601
|
+
:space_between:
|
1602
|
+
- flex-justify-between
|
1603
|
+
:space_around:
|
1604
|
+
- flex-justify-around
|
1605
|
+
:align_items:
|
1606
|
+
:flex_start:
|
1607
|
+
- flex-items-start
|
1608
|
+
:flex_end:
|
1609
|
+
- flex-items-end
|
1610
|
+
:center:
|
1611
|
+
- flex-items-center
|
1612
|
+
:baseline:
|
1613
|
+
- flex-items-baseline
|
1614
|
+
:stretch:
|
1615
|
+
- flex-items-stretch
|
1616
|
+
:flex_wrap:
|
1617
|
+
:wrap:
|
1618
|
+
- flex-wrap
|
1619
|
+
:nowrap:
|
1620
|
+
- flex-nowrap
|
1621
|
+
:reverse:
|
1622
|
+
- flex-wrap-reverse
|
1623
|
+
:direction:
|
1624
|
+
:column:
|
1625
|
+
- flex-column
|
1626
|
+
- flex-sm-column
|
1627
|
+
- flex-md-column
|
1628
|
+
- flex-lg-column
|
1629
|
+
- flex-xl-column
|
1630
|
+
:column_reverse:
|
1631
|
+
- flex-column-reverse
|
1632
|
+
- flex-sm-column-reverse
|
1633
|
+
- flex-md-column-reverse
|
1634
|
+
- flex-lg-column-reverse
|
1635
|
+
- flex-xl-column-reverse
|
1636
|
+
:row:
|
1637
|
+
- flex-row
|
1638
|
+
- flex-sm-row
|
1639
|
+
- flex-md-row
|
1640
|
+
- flex-lg-row
|
1641
|
+
- flex-xl-row
|
1642
|
+
:row_reverse:
|
1643
|
+
- flex-row-reverse
|
1644
|
+
- flex-sm-row-reverse
|
1645
|
+
- flex-md-row-reverse
|
1646
|
+
- flex-lg-row-reverse
|
1647
|
+
- flex-xl-row-reverse
|
1648
|
+
:flex:
|
1649
|
+
1:
|
1650
|
+
- flex-1
|
1651
|
+
:auto:
|
1652
|
+
- flex-auto
|
1653
|
+
:align_self:
|
1654
|
+
:auto:
|
1655
|
+
- flex-self-auto
|
1656
|
+
:start:
|
1657
|
+
- flex-self-start
|
1658
|
+
:end:
|
1659
|
+
- flex-self-end
|
1660
|
+
:center:
|
1661
|
+
- flex-self-center
|
1662
|
+
:baseline:
|
1663
|
+
- flex-self-baseline
|
1664
|
+
:stretch:
|
1665
|
+
- flex-self-stretch
|
1666
|
+
:flex_grow:
|
1667
|
+
0:
|
1668
|
+
- flex-grow-0
|
1669
|
+
:flex_shrink:
|
1670
|
+
0:
|
1671
|
+
- flex-shrink-0
|
data/lib/primer/classify.rb
CHANGED
@@ -1,221 +1,135 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "classify/cache"
|
4
|
-
require_relative "classify/flex"
|
5
3
|
require_relative "classify/utilities"
|
6
4
|
require_relative "classify/validation"
|
7
5
|
|
8
6
|
module Primer
|
9
7
|
# :nodoc:
|
10
8
|
class Classify
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
BREAKPOINTS = ["", "-sm", "-md", "-lg", "-xl"].freeze
|
18
|
-
|
19
|
-
BOOLEAN_MAPPINGS = {
|
20
|
-
underline: {
|
21
|
-
mappings: [
|
22
|
-
{
|
23
|
-
value: true,
|
24
|
-
css_class: "text-underline"
|
25
|
-
},
|
26
|
-
{
|
27
|
-
value: false,
|
28
|
-
css_class: "no-underline"
|
29
|
-
}
|
30
|
-
]
|
31
|
-
},
|
32
|
-
top: {
|
33
|
-
mappings: [
|
34
|
-
{
|
35
|
-
value: false,
|
36
|
-
css_class: "top-0"
|
37
|
-
}
|
38
|
-
]
|
39
|
-
},
|
40
|
-
bottom: {
|
41
|
-
mappings: [
|
42
|
-
{
|
43
|
-
value: false,
|
44
|
-
css_class: "bottom-0"
|
45
|
-
}
|
46
|
-
]
|
47
|
-
},
|
48
|
-
left: {
|
49
|
-
mappings: [
|
50
|
-
{
|
51
|
-
value: false,
|
52
|
-
css_class: "left-0"
|
53
|
-
}
|
54
|
-
]
|
55
|
-
},
|
56
|
-
right: {
|
57
|
-
mappings: [
|
58
|
-
{
|
59
|
-
value: false,
|
60
|
-
css_class: "right-0"
|
61
|
-
}
|
62
|
-
]
|
63
|
-
}
|
9
|
+
FLEX_VALUES = [1, :auto].freeze
|
10
|
+
|
11
|
+
FLEX_WRAP_MAPPINGS = {
|
12
|
+
wrap: "flex-wrap",
|
13
|
+
nowrap: "flex-nowrap",
|
14
|
+
reverse: "flex-wrap-reverse"
|
64
15
|
}.freeze
|
65
|
-
BORDER_KEY = :border
|
66
|
-
BORDER_MARGIN_KEYS = %i[border_top border_bottom border_left border_right].freeze
|
67
|
-
BORDER_RADIUS_KEY = :border_radius
|
68
|
-
TYPOGRAPHY_KEYS = [:font_size].freeze
|
69
|
-
VALID_KEYS = (
|
70
|
-
Primer::Classify::Utilities::UTILITIES.keys +
|
71
|
-
CONCAT_KEYS +
|
72
|
-
BOOLEAN_MAPPINGS.keys +
|
73
|
-
BORDER_MARGIN_KEYS +
|
74
|
-
TYPOGRAPHY_KEYS +
|
75
|
-
TEXT_KEYS +
|
76
|
-
Primer::Classify::Flex::KEYS +
|
77
|
-
[
|
78
|
-
BORDER_KEY,
|
79
|
-
BORDER_RADIUS_KEY,
|
80
|
-
BOX_SHADOW_KEY
|
81
|
-
]
|
82
|
-
).freeze
|
83
16
|
|
84
|
-
|
85
|
-
def call(classes: "", style: nil, **args)
|
86
|
-
extract_css_attrs(args).tap do |extracted_results|
|
87
|
-
classes = +"#{validated_class_names(classes)} #{extracted_results[:class]}"
|
88
|
-
classes.strip!
|
89
|
-
extracted_results[:class] = presence(classes)
|
90
|
-
|
91
|
-
styles = "#{extracted_results[:style]}#{style}"
|
92
|
-
extracted_results[:style] = presence(styles)
|
93
|
-
end
|
94
|
-
end
|
17
|
+
FLEX_ALIGN_SELF_VALUES = [:auto, :start, :end, :center, :baseline, :stretch].freeze
|
95
18
|
|
96
|
-
|
19
|
+
FLEX_DIRECTION_VALUES = [:column, :column_reverse, :row, :row_reverse].freeze
|
97
20
|
|
98
|
-
|
99
|
-
def presence(obj)
|
100
|
-
# rubocop:disable Rails/Blank
|
101
|
-
!obj || obj.empty? ? nil : obj
|
102
|
-
# rubocop:enable Rails/Blank
|
103
|
-
end
|
21
|
+
FLEX_JUSTIFY_CONTENT_VALUES = [:flex_start, :flex_end, :center, :space_between, :space_around].freeze
|
104
22
|
|
105
|
-
|
106
|
-
return if classes.blank?
|
23
|
+
FLEX_ALIGN_ITEMS_VALUES = [:flex_start, :flex_end, :center, :baseline, :stretch].freeze
|
107
24
|
|
108
|
-
|
109
|
-
invalid_class_names =
|
110
|
-
classes.split.each_with_object([]) do |class_name, memo|
|
111
|
-
memo << class_name if Primer::Classify::Validation.invalid?(class_name)
|
112
|
-
end
|
25
|
+
LOOKUP = Primer::Classify::Utilities::UTILITIES
|
113
26
|
|
114
|
-
|
115
|
-
|
116
|
-
"instead of Primer CSS class #{'name'.pluralize(invalid_class_names.length)} #{invalid_class_names.to_sentence}. "\
|
117
|
-
"This warning will not be raised in production. Set PRIMER_WARNINGS_DISABLED=1 to disable this warning."
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
classes
|
122
|
-
end
|
123
|
-
|
124
|
-
# NOTE: This is a fairly naive implementation that we're building as we go.
|
125
|
-
# Feel free to refactor as this is thoroughly tested.
|
27
|
+
class << self
|
28
|
+
# Utility for mapping component configuration into Primer CSS class names.
|
126
29
|
#
|
127
|
-
#
|
30
|
+
# **args can contain utility keys that mimic the interface used by
|
31
|
+
# https://github.com/primer/components, as well as the special entries :classes
|
32
|
+
# and :style.
|
128
33
|
#
|
129
|
-
#
|
34
|
+
# Returns a hash containing two entries. The :classes entry is a string of
|
35
|
+
# Primer CSS class names, including any classes given in the :classes entry
|
36
|
+
# in **args. The :style entry is the value of the given :style entry given in
|
37
|
+
# **args.
|
130
38
|
#
|
131
|
-
# Returns a string of Primer CSS class names and style attributes to be added to an HTML tag.
|
132
39
|
#
|
133
40
|
# Example usage:
|
134
|
-
# extract_css_attrs({ mt: 4, py: 2 }) => "mt-4 py-2"
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
41
|
+
# extract_css_attrs({ mt: 4, py: 2 }) => { classes: "mt-4 py-2", style: nil }
|
42
|
+
# extract_css_attrs(classes: "d-flex", mt: 4, py: 2) => { classes: "d-flex mt-4 py-2", style: nil }
|
43
|
+
# extract_css_attrs(classes: "d-flex", style: "float: left", mt: 4, py: 2) => { classes: "d-flex mt-4 py-2", style: "float: left" }
|
44
|
+
#
|
45
|
+
def call(**args)
|
46
|
+
style = nil
|
47
|
+
classes = [].tap do |result|
|
48
|
+
args.each do |key, val|
|
49
|
+
case key
|
50
|
+
when :classes
|
51
|
+
# insert :classes first to avoid huge doc diffs
|
52
|
+
if (class_names = validated_class_names(val))
|
53
|
+
result.unshift(class_names)
|
54
|
+
end
|
55
|
+
next
|
56
|
+
when :style
|
57
|
+
style = val
|
58
|
+
next
|
59
|
+
end
|
142
60
|
|
143
|
-
|
144
|
-
|
61
|
+
next unless LOOKUP[key]
|
62
|
+
|
63
|
+
if val.is_a?(Array)
|
64
|
+
# A while loop is ~3.5x faster than Array#each.
|
65
|
+
brk = 0
|
66
|
+
while brk < val.size
|
67
|
+
item = val[brk]
|
68
|
+
|
69
|
+
if item.nil?
|
70
|
+
brk += 1
|
71
|
+
next
|
72
|
+
end
|
73
|
+
|
74
|
+
# Believe it or not, three calls to Hash#[] and an inline rescue
|
75
|
+
# are about 30% faster than Hash#dig. It also ensures validate is
|
76
|
+
# only called when necessary, i.e. when the class can't be found
|
77
|
+
# in the lookup table.
|
78
|
+
# rubocop:disable Style/RescueModifier
|
79
|
+
found = (LOOKUP[key][item][brk] rescue nil) || validate(key, item, brk)
|
80
|
+
# rubocop:enable Style/RescueModifier
|
81
|
+
result << found if found
|
82
|
+
brk += 1
|
83
|
+
end
|
84
|
+
else
|
85
|
+
next if val.nil?
|
86
|
+
|
87
|
+
# rubocop:disable Style/RescueModifier
|
88
|
+
found = (LOOKUP[key][val][0] rescue nil) || validate(key, val, 0)
|
89
|
+
# rubocop:enable Style/RescueModifier
|
90
|
+
result << found if found
|
145
91
|
end
|
146
|
-
else
|
147
|
-
extract_one_css_attr(classes, styles, key, value, BREAKPOINTS[0])
|
148
92
|
end
|
149
|
-
end
|
93
|
+
end.join(" ")
|
150
94
|
|
95
|
+
# This is much faster than Rails' presence method.
|
96
|
+
# rubocop:disable Rails/Blank
|
151
97
|
{
|
152
|
-
class: classes.
|
153
|
-
style:
|
98
|
+
class: !classes || classes.empty? ? nil : classes,
|
99
|
+
style: !style || style.empty? ? nil : style
|
154
100
|
}
|
101
|
+
# rubocop:enable Rails/Blank
|
155
102
|
end
|
156
103
|
|
157
|
-
|
158
|
-
found_classes = Primer::Classify::Cache.instance.fetch(breakpoint, key, val) do
|
159
|
-
classes_from(key, val, breakpoint)
|
160
|
-
end
|
161
|
-
|
162
|
-
classes << found_classes if found_classes
|
104
|
+
private
|
163
105
|
|
164
|
-
|
165
|
-
|
106
|
+
def validate(key, val, brk)
|
107
|
+
brk_str = Primer::Classify::Utilities::BREAKPOINTS[brk]
|
108
|
+
Primer::Classify::Utilities.validate(key, val, brk_str)
|
166
109
|
end
|
167
110
|
|
168
|
-
def
|
169
|
-
|
170
|
-
# Could be that way now, but it makes Rubocop unhappy.
|
171
|
-
end
|
111
|
+
def validated_class_names(classes)
|
112
|
+
return if classes.blank?
|
172
113
|
|
173
|
-
|
174
|
-
|
114
|
+
if raise_on_invalid_options? && !ENV["PRIMER_WARNINGS_DISABLED"]
|
115
|
+
invalid_class_names =
|
116
|
+
classes.split.each_with_object([]) do |class_name, memo|
|
117
|
+
memo << class_name if Primer::Classify::Validation.invalid?(class_name)
|
118
|
+
end
|
175
119
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
memo << m[:css_class] if m[:value] == val && m[:css_class].present?
|
181
|
-
end
|
182
|
-
bools.empty? ? nil : bools.join(" ")
|
183
|
-
elsif key == BORDER_KEY
|
184
|
-
if val == true
|
185
|
-
"border"
|
186
|
-
else
|
187
|
-
"border-#{val.to_s.dasherize}"
|
188
|
-
end
|
189
|
-
elsif BORDER_MARGIN_KEYS.include?(key)
|
190
|
-
"#{key.to_s.dasherize}-#{val}"
|
191
|
-
elsif key == BORDER_RADIUS_KEY
|
192
|
-
"rounded-#{val}"
|
193
|
-
elsif Primer::Classify::Flex::KEYS.include?(key)
|
194
|
-
Primer::Classify::Flex.classes(key, val, breakpoint)
|
195
|
-
elsif TEXT_KEYS.include?(key)
|
196
|
-
"text-#{val.to_s.dasherize}"
|
197
|
-
elsif TYPOGRAPHY_KEYS.include?(key)
|
198
|
-
if val == :small || val == :normal
|
199
|
-
"text-#{val.to_s.dasherize}"
|
200
|
-
else
|
201
|
-
"f#{val.to_s.dasherize}"
|
202
|
-
end
|
203
|
-
elsif key == BOX_SHADOW_KEY
|
204
|
-
if val == true
|
205
|
-
"color-shadow-small"
|
206
|
-
elsif val == :none || val.blank?
|
207
|
-
"box-shadow-none"
|
208
|
-
else
|
209
|
-
"color-shadow-#{val.to_s.dasherize}"
|
120
|
+
if invalid_class_names.any?
|
121
|
+
raise ArgumentError, "Use System Arguments (https://primer.style/view-components/system-arguments) "\
|
122
|
+
"instead of Primer CSS class #{'name'.pluralize(invalid_class_names.length)} #{invalid_class_names.to_sentence}. "\
|
123
|
+
"This warning will not be raised in production. Set PRIMER_WARNINGS_DISABLED=1 to disable this warning."
|
210
124
|
end
|
211
125
|
end
|
126
|
+
|
127
|
+
classes
|
212
128
|
end
|
213
129
|
|
214
130
|
def raise_on_invalid_options?
|
215
131
|
Rails.application.config.primer_view_components.raise_on_invalid_options
|
216
132
|
end
|
217
133
|
end
|
218
|
-
|
219
|
-
Cache.instance.preload!
|
220
134
|
end
|
221
135
|
end
|
@@ -17,7 +17,7 @@ module ERBLint
|
|
17
17
|
|
18
18
|
next unless code.include?("Primer::BlankslateComponent")
|
19
19
|
# Don't fix custom blankslates
|
20
|
-
next if code.end_with?("do")
|
20
|
+
next if code.end_with?("do", "|")
|
21
21
|
|
22
22
|
line = erb_node.loc.source_line
|
23
23
|
indent = line.split("<%=").first.size
|
@@ -61,7 +61,7 @@ module ERBLint
|
|
61
61
|
|
62
62
|
case pair.key.value.to_sym
|
63
63
|
when :title
|
64
|
-
new_blankslate[:slots][:heading][:content] = pair.value
|
64
|
+
new_blankslate[:slots][:heading][:content] = extract_value(pair.value)
|
65
65
|
when :title_tag
|
66
66
|
new_blankslate[:slots][:heading][:tag] = source_value
|
67
67
|
when :icon
|
@@ -73,15 +73,15 @@ module ERBLint
|
|
73
73
|
when :image_alt
|
74
74
|
new_blankslate[:slots][:visual_image][:alt] = source_value
|
75
75
|
when :description
|
76
|
-
new_blankslate[:slots][:description][:content] = pair.value
|
76
|
+
new_blankslate[:slots][:description][:content] = extract_value(pair.value)
|
77
77
|
when :button_text
|
78
|
-
new_blankslate[:slots][:primary_action][:content] = pair.value
|
78
|
+
new_blankslate[:slots][:primary_action][:content] = extract_value(pair.value)
|
79
79
|
when :button_url
|
80
80
|
new_blankslate[:slots][:primary_action][:href] = source_value
|
81
81
|
when :button_classes
|
82
82
|
new_blankslate[:slots][:primary_action][:classes] = source_value
|
83
83
|
when :link_text
|
84
|
-
new_blankslate[:slots][:secondary_action][:content] = pair.value
|
84
|
+
new_blankslate[:slots][:secondary_action][:content] = extract_value(pair.value)
|
85
85
|
when :link_url
|
86
86
|
new_blankslate[:slots][:secondary_action][:href] = source_value
|
87
87
|
when :large
|
@@ -141,6 +141,12 @@ module ERBLint
|
|
141
141
|
|
142
142
|
"(#{string_args})"
|
143
143
|
end
|
144
|
+
|
145
|
+
def extract_value(value)
|
146
|
+
return value.value if value.type == :str
|
147
|
+
|
148
|
+
"<%= #{value.source} %>"
|
149
|
+
end
|
144
150
|
end
|
145
151
|
end
|
146
152
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubocop"
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Cop
|
7
|
+
module Primer
|
8
|
+
# This cop ensures that the deprecated `Primer::LayoutComponent` isn't used.
|
9
|
+
#
|
10
|
+
# bad
|
11
|
+
# Primer::LayoutComponent.new(foo: :deprecated)
|
12
|
+
#
|
13
|
+
# good
|
14
|
+
# Primer::Alpha::Layout.new(foo: :deprecated)
|
15
|
+
class DeprecatedLayoutComponent < BaseCop
|
16
|
+
MSG = "Please try Primer::Alpha::Layout instead."
|
17
|
+
|
18
|
+
def_node_matcher :legacy_component?, <<~PATTERN
|
19
|
+
(send (const (const nil? :Primer) :LayoutComponent) :new ...)
|
20
|
+
PATTERN
|
21
|
+
|
22
|
+
def on_send(node)
|
23
|
+
return unless legacy_component?(node)
|
24
|
+
|
25
|
+
add_offense(node, message: MSG)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|