openproject-primer_view_components 0.49.2 → 0.50.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/assets/styles/primer_view_components.css +1 -1
- data/app/assets/styles/primer_view_components.css.map +1 -1
- data/app/components/primer/alpha/action_bar.rb +2 -2
- data/app/components/primer/alpha/action_bar_element.js +0 -7
- data/app/components/primer/alpha/action_bar_element.ts +0 -8
- data/app/components/primer/base_component.rb +4 -1
- data/app/components/primer/beta/auto_complete.rb +1 -0
- data/app/components/primer/beta/button.rb +0 -11
- data/app/components/primer/beta/link.css +1 -1
- data/app/components/primer/beta/link.css.json +2 -1
- data/app/components/primer/beta/link.css.map +1 -1
- data/app/components/primer/beta/link.html.erb +18 -0
- data/app/components/primer/beta/link.pcss +9 -0
- data/app/components/primer/beta/link.rb +26 -14
- data/app/components/primer/button_component.rb +0 -11
- data/app/components/primer/component.rb +7 -0
- data/app/components/primer/conditional_wrapper.rb +5 -2
- data/app/forms/horizontal_form.rb +2 -0
- data/app/lib/primer/forms/auto_complete.rb +2 -1
- data/app/lib/primer/forms/dsl/hidden_input.rb +4 -0
- data/app/lib/primer/forms/group.rb +4 -1
- data/lib/primer/classify/utilities.yml +63 -0
- data/lib/primer/classify.rb +1 -26
- data/lib/primer/forms/primer_multi_input.d.ts +10 -0
- data/lib/primer/forms/primer_multi_input.js +44 -0
- data/lib/primer/forms/primer_text_field.d.ts +28 -0
- data/lib/primer/forms/primer_text_field.js +119 -0
- data/lib/primer/forms/toggle_switch_input.d.ts +5 -0
- data/lib/primer/forms/toggle_switch_input.js +34 -0
- data/lib/primer/static/generate_form_previews.rb +44 -0
- data/lib/primer/static.rb +8 -0
- data/lib/primer/view_components/version.rb +2 -2
- data/lib/tasks/custom_utilities.yml +63 -0
- data/previews/primer/beta/link_preview.rb +24 -2
- data/previews/primer/forms_preview.rb +21 -0
- data/static/classes.json +3 -0
- data/static/form_previews.json +113 -0
- metadata +11 -2
@@ -88,9 +88,9 @@ module Primer
|
|
88
88
|
def before_render
|
89
89
|
@system_arguments[:tag] = render_overflow_menu? ? :"action-bar" : :div
|
90
90
|
@system_arguments[:classes] = class_names(
|
91
|
-
@system_arguments[:classes]
|
92
|
-
"overflow-visible": !render_overflow_menu?
|
91
|
+
@system_arguments[:classes]
|
93
92
|
)
|
93
|
+
@system_arguments[:overflow] = :visible if render_overflow_menu?
|
94
94
|
content
|
95
95
|
end
|
96
96
|
end
|
@@ -47,13 +47,6 @@ let ActionBarElement = class ActionBarElement extends HTMLElement {
|
|
47
47
|
_ActionBarElement_focusZoneAbortController.set(this, null);
|
48
48
|
}
|
49
49
|
connectedCallback() {
|
50
|
-
// Calculate the width of all the items before hiding anything
|
51
|
-
for (const item of this.items) {
|
52
|
-
const width = item.getBoundingClientRect().width;
|
53
|
-
const marginLeft = parseInt(window.getComputedStyle(item)?.marginLeft, 10);
|
54
|
-
const marginRight = parseInt(window.getComputedStyle(item)?.marginRight, 10);
|
55
|
-
item.setAttribute('data-offset-width', `${width + marginLeft + marginRight}`);
|
56
|
-
}
|
57
50
|
resizeObserver.observe(this);
|
58
51
|
instersectionObserver.observe(this);
|
59
52
|
requestAnimationFrame(() => {
|
@@ -36,14 +36,6 @@ class ActionBarElement extends HTMLElement {
|
|
36
36
|
#focusZoneAbortController: AbortController | null = null
|
37
37
|
|
38
38
|
connectedCallback() {
|
39
|
-
// Calculate the width of all the items before hiding anything
|
40
|
-
for (const item of this.items) {
|
41
|
-
const width = item.getBoundingClientRect().width
|
42
|
-
const marginLeft = parseInt(window.getComputedStyle(item)?.marginLeft, 10)
|
43
|
-
const marginRight = parseInt(window.getComputedStyle(item)?.marginRight, 10)
|
44
|
-
item.setAttribute('data-offset-width', `${width + marginLeft + marginRight}`)
|
45
|
-
}
|
46
|
-
|
47
39
|
resizeObserver.observe(this)
|
48
40
|
instersectionObserver.observe(this)
|
49
41
|
|
@@ -151,6 +151,7 @@ module Primer
|
|
151
151
|
# | :- | :- | :- |
|
152
152
|
# | classes | String | CSS class name value to be concatenated with generated Primer CSS classes. |
|
153
153
|
# | test_selector | String | Adds `data-test-selector='given value'` in non-Production environments for testing purposes. |
|
154
|
+
# | trim | Boolean | Calls `strip` on the content to remove trailing and leading white spaces. |
|
154
155
|
def initialize(tag:, classes: nil, **system_arguments)
|
155
156
|
@tag = tag
|
156
157
|
|
@@ -158,6 +159,8 @@ module Primer
|
|
158
159
|
|
159
160
|
@result = Primer::Classify.call(**@system_arguments.merge(classes: classes))
|
160
161
|
|
162
|
+
@trim = !!@system_arguments.delete(:trim)
|
163
|
+
|
161
164
|
@system_arguments[:"data-view-component"] = true
|
162
165
|
# Filter out Primer keys so they don't get assigned as HTML attributes
|
163
166
|
@content_tag_args = add_test_selector(@system_arguments).except(*Primer::Classify::Utilities::UTILITIES.keys)
|
@@ -167,7 +170,7 @@ module Primer
|
|
167
170
|
if SELF_CLOSING_TAGS.include?(@tag)
|
168
171
|
tag(@tag, @content_tag_args.merge(@result))
|
169
172
|
else
|
170
|
-
content_tag(@tag, content, @content_tag_args.merge(@result))
|
173
|
+
content_tag(@tag, @trim ? trimmed_content : content, @content_tag_args.merge(@result))
|
171
174
|
end
|
172
175
|
end
|
173
176
|
end
|
@@ -44,6 +44,7 @@ module Primer
|
|
44
44
|
system_arguments[:"allow-out-of-bounds"] = ""
|
45
45
|
system_arguments[:id] = @list_id
|
46
46
|
system_arguments[:popover] = ""
|
47
|
+
system_arguments[:overflow_y] = :auto
|
47
48
|
system_arguments[:classes] = class_names(
|
48
49
|
"ActionListWrap ActionListWrap--inset",
|
49
50
|
@overlay_classes,
|
@@ -159,17 +159,6 @@ module Primer
|
|
159
159
|
"Button--invisible-noVisuals"
|
160
160
|
)
|
161
161
|
end
|
162
|
-
|
163
|
-
def trimmed_content
|
164
|
-
return if content.blank?
|
165
|
-
|
166
|
-
trimmed_content = content.strip
|
167
|
-
|
168
|
-
return trimmed_content unless content.html_safe?
|
169
|
-
|
170
|
-
# strip unsets `html_safe`, so we have to set it back again to guarantee that HTML blocks won't break
|
171
|
-
trimmed_content.html_safe # rubocop:disable Rails/OutputSafety
|
172
|
-
end
|
173
162
|
end
|
174
163
|
end
|
175
164
|
end
|
@@ -1 +1 @@
|
|
1
|
-
.Link{color:var(--fgColor-accent);-webkit-text-decoration:none;text-decoration:none}.Link:hover{cursor:pointer}.Link:focus,.Link:hover{-webkit-text-decoration:underline;text-decoration:underline}.Link:focus,.Link:focus-visible{outline-offset:0}.Link--underline{-webkit-text-decoration:underline;text-decoration:underline}.Link--primary{color:var(--fgColor-default)!important}.Link--primary:hover{color:var(--fgColor-accent)!important}.Link--secondary{color:var(--fgColor-muted)!important}.Link--secondary:hover{color:var(--fgColor-accent)!important}.Link--muted{color:var(--fgColor-muted)!important}.Link--muted:hover{color:var(--fgColor-accent)!important;-webkit-text-decoration:none;text-decoration:none}.Link--onHover:hover{color:var(--fgColor-accent)!important;cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline}:is(.Link--secondary,.Link--primary,.Link--muted):hover [class*=color-fg]{color:inherit!important}
|
1
|
+
.Link{color:var(--fgColor-accent);-webkit-text-decoration:none;text-decoration:none}.Link:hover{cursor:pointer}.Link:focus,.Link:hover{-webkit-text-decoration:underline;text-decoration:underline}.Link:focus,.Link:focus-visible{outline-offset:0}.Link--underline{-webkit-text-decoration:underline;text-decoration:underline}.Link--primary{color:var(--fgColor-default)!important}.Link--primary:hover{color:var(--fgColor-accent)!important}.Link--secondary{color:var(--fgColor-muted)!important}.Link--secondary:hover{color:var(--fgColor-accent)!important}.Link--muted{color:var(--fgColor-muted)!important}.Link--muted:hover{color:var(--fgColor-accent)!important;-webkit-text-decoration:none;text-decoration:none}.Link--onHover:hover{color:var(--fgColor-accent)!important;cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline}:is(.Link--secondary,.Link--primary,.Link--muted):hover [class*=color-fg]{color:inherit!important}.Link-content{align-items:center;display:inline-flex;gap:var(--base-size-4);line-height:normal;text-decoration:inherit}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["link.pcss"],"names":[],"mappings":"AAEA,MACE,2BAA4B,CAC5B,4BAAqB,CAArB,oBAeF,CAbE,YAEE,cACF,CAEA,wBAJE,iCAA0B,CAA1B,yBAMF,CAEA,gCAEE,gBACF,CAGF,iBACE,iCAA0B,CAA1B,yBACF,CAEA,eACE,sCAKF,CAHE,qBACE,qCACF,CAGF,iBACE,oCAKF,CAHE,uBACE,qCACF,CAGF,aACE,oCAMF,CAJE,mBACE,qCAAuC,CACvC,4BAAqB,CAArB,oBACF,CAMA,qBACE,qCAAuC,CAEvC,cAAe,CADf,iCAA0B,CAA1B,yBAEF,CAQA,0EACE,uBACF","file":"link.css","sourcesContent":["/* Links */\n\n.Link {\n color: var(--fgColor-accent);\n text-decoration: none;\n\n &:hover {\n text-decoration: underline;\n cursor: pointer;\n }\n\n &:focus {\n text-decoration: underline;\n }\n\n &:focus,\n &:focus-visible {\n outline-offset: 0;\n }\n}\n\n.Link--underline {\n text-decoration: underline;\n}\n\n.Link--primary {\n color: var(--fgColor-default) !important;\n\n &:hover {\n color: var(--fgColor-accent) !important;\n }\n}\n\n.Link--secondary {\n color: var(--fgColor-muted) !important;\n\n &:hover {\n color: var(--fgColor-accent) !important;\n }\n}\n\n.Link--muted {\n color: var(--fgColor-muted) !important;\n\n &:hover {\n color: var(--fgColor-accent) !important;\n text-decoration: none;\n }\n}\n\n/* Set the link color only on hover\n Useful when you want only part of a link to turn blue on hover */\n.Link--onHover {\n &:hover {\n color: var(--fgColor-accent) !important;\n text-decoration: underline;\n cursor: pointer;\n }\n}\n\n/* When using a color utility class inside of a link class\n color should change with link on hover. */\n.Link--secondary,\n.Link--primary,\n.Link--muted {\n &:hover [class*='color-fg'] {\n color: inherit !important;\n }\n}\n"]}
|
1
|
+
{"version":3,"sources":["link.pcss"],"names":[],"mappings":"AAEA,MACE,2BAA4B,CAC5B,4BAAqB,CAArB,oBAeF,CAbE,YAEE,cACF,CAEA,wBAJE,iCAA0B,CAA1B,yBAMF,CAEA,gCAEE,gBACF,CAGF,iBACE,iCAA0B,CAA1B,yBACF,CAEA,eACE,sCAKF,CAHE,qBACE,qCACF,CAGF,iBACE,oCAKF,CAHE,uBACE,qCACF,CAGF,aACE,oCAMF,CAJE,mBACE,qCAAuC,CACvC,4BAAqB,CAArB,oBACF,CAMA,qBACE,qCAAuC,CAEvC,cAAe,CADf,iCAA0B,CAA1B,yBAEF,CAQA,0EACE,uBACF,CAGF,cAEE,kBAAmB,CADnB,mBAAoB,CAIpB,sBAAuB,CADvB,kBAAmB,CAEnB,uBACF","file":"link.css","sourcesContent":["/* Links */\n\n.Link {\n color: var(--fgColor-accent);\n text-decoration: none;\n\n &:hover {\n text-decoration: underline;\n cursor: pointer;\n }\n\n &:focus {\n text-decoration: underline;\n }\n\n &:focus,\n &:focus-visible {\n outline-offset: 0;\n }\n}\n\n.Link--underline {\n text-decoration: underline;\n}\n\n.Link--primary {\n color: var(--fgColor-default) !important;\n\n &:hover {\n color: var(--fgColor-accent) !important;\n }\n}\n\n.Link--secondary {\n color: var(--fgColor-muted) !important;\n\n &:hover {\n color: var(--fgColor-accent) !important;\n }\n}\n\n.Link--muted {\n color: var(--fgColor-muted) !important;\n\n &:hover {\n color: var(--fgColor-accent) !important;\n text-decoration: none;\n }\n}\n\n/* Set the link color only on hover\n Useful when you want only part of a link to turn blue on hover */\n.Link--onHover {\n &:hover {\n color: var(--fgColor-accent) !important;\n text-decoration: underline;\n cursor: pointer;\n }\n}\n\n/* When using a color utility class inside of a link class\n color should change with link on hover. */\n.Link--secondary,\n.Link--primary,\n.Link--muted {\n &:hover [class*='color-fg'] {\n color: inherit !important;\n }\n}\n\n.Link-content {\n display: inline-flex;\n align-items: center;\n /* stylelint-disable-next-line primer/typography */\n line-height: normal;\n gap: var(--base-size-4);\n text-decoration: inherit;\n}\n"]}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<%= render Primer::ConditionalWrapper.new(condition: tooltip?, trim: true, tag: :span, position: :relative) do %>
|
2
|
+
<%= render(Primer::BaseComponent.new(trim: true, **@system_arguments)) do %>
|
3
|
+
<% if leading_visual || trailing_visual %>
|
4
|
+
<%= render(Primer::BaseComponent.new(tag: :span, classes: "Link-content", trim: true)) do %>
|
5
|
+
<% if leading_visual %>
|
6
|
+
<%= leading_visual %>
|
7
|
+
<% end %>
|
8
|
+
<%= content %>
|
9
|
+
<% if trailing_visual %>
|
10
|
+
<%= trailing_visual %>
|
11
|
+
<% end %>
|
12
|
+
<% end %>
|
13
|
+
<% else %>
|
14
|
+
<%= content %>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
<%= tooltip if tooltip? %>
|
18
|
+
<% end %>
|
@@ -30,6 +30,32 @@ module Primer
|
|
30
30
|
Primer::Alpha::Tooltip.new(**system_arguments)
|
31
31
|
}
|
32
32
|
|
33
|
+
# Leading visuals appear to the left of the link text.
|
34
|
+
#
|
35
|
+
# Use:
|
36
|
+
#
|
37
|
+
# - `leading_visual_icon` which accepts the arguments accepted by <%= link_to_component(Primer::Beta::Octicon) %>.
|
38
|
+
#
|
39
|
+
# @param system_arguments [Hash] Same arguments as <%= link_to_component(Primer::Beta::Octicon) %>.
|
40
|
+
renders_one :leading_visual, types: {
|
41
|
+
icon: lambda { |**system_arguments|
|
42
|
+
Primer::Beta::Octicon.new(**system_arguments)
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
# Trailing visuals appear to the right of the link text.
|
47
|
+
#
|
48
|
+
# Use:
|
49
|
+
#
|
50
|
+
# - `trailing_visual_icon` which accepts the arguments accepted by <%= link_to_component(Primer::Beta::Octicon) %>.
|
51
|
+
#
|
52
|
+
# @param system_arguments [Hash] Same arguments as <%= link_to_component(Primer::Beta::Octicon) %>.
|
53
|
+
renders_one :trailing_visual, types: {
|
54
|
+
icon: lambda { |**system_arguments|
|
55
|
+
Primer::Beta::Octicon.new(**system_arguments)
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
33
59
|
# @param href [String] URL to be used for the Link. Required. If the requirements are not met an error will be raised in non production environments. In production, an empty link element will be rendered.
|
34
60
|
# @param scheme [Symbol] <%= one_of(Primer::Beta::Link::SCHEME_MAPPINGS.keys) %>
|
35
61
|
# @param muted [Boolean] Uses light gray for Link color, and blue on hover.
|
@@ -54,20 +80,6 @@ module Primer
|
|
54
80
|
def before_render
|
55
81
|
raise ArgumentError, "href is required" if @system_arguments[:href].nil? && !Rails.env.production?
|
56
82
|
end
|
57
|
-
|
58
|
-
def call
|
59
|
-
if tooltip.present?
|
60
|
-
render Primer::BaseComponent.new(tag: :span, position: :relative) do
|
61
|
-
render(Primer::BaseComponent.new(**@system_arguments)) do
|
62
|
-
content
|
63
|
-
end.to_s + tooltip.to_s
|
64
|
-
end
|
65
|
-
else
|
66
|
-
render(Primer::BaseComponent.new(**@system_arguments)) do
|
67
|
-
content
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
83
|
end
|
72
84
|
end
|
73
85
|
end
|
@@ -111,16 +111,5 @@ module Primer
|
|
111
111
|
def link?
|
112
112
|
@scheme == LINK_SCHEME
|
113
113
|
end
|
114
|
-
|
115
|
-
def trimmed_content
|
116
|
-
return if content.blank?
|
117
|
-
|
118
|
-
trimmed_content = content.strip
|
119
|
-
|
120
|
-
return trimmed_content unless content.html_safe?
|
121
|
-
|
122
|
-
# strip unsets `html_safe`, so we have to set it back again to guarantee that HTML blocks won't break
|
123
|
-
trimmed_content.html_safe # rubocop:disable Rails/OutputSafety
|
124
|
-
end
|
125
114
|
end
|
126
115
|
end
|
@@ -148,5 +148,12 @@ module Primer
|
|
148
148
|
def should_raise_aria_error?
|
149
149
|
!Rails.env.production? && raise_on_invalid_aria? && !ENV["PRIMER_WARNINGS_DISABLED"]
|
150
150
|
end
|
151
|
+
|
152
|
+
def trimmed_content
|
153
|
+
return content unless content.present?
|
154
|
+
|
155
|
+
# strip unsets `html_safe`, so we have to set it back again to guarantee that HTML blocks won't break
|
156
|
+
content.html_safe? ? content.strip.html_safe : content.strip # rubocop:disable Rails/OutputSafety
|
157
|
+
end
|
151
158
|
end
|
152
159
|
end
|
@@ -10,12 +10,15 @@ module Primer
|
|
10
10
|
def initialize(condition:, **base_component_arguments)
|
11
11
|
@condition = condition
|
12
12
|
@base_component_arguments = base_component_arguments
|
13
|
+
@trim = !!@base_component_arguments.delete(:trim)
|
13
14
|
end
|
14
15
|
|
15
16
|
def call
|
16
|
-
|
17
|
+
unless @condition
|
18
|
+
return @trim ? trimmed_content : content
|
19
|
+
end
|
17
20
|
|
18
|
-
BaseComponent.new(**@base_component_arguments).render_in(self) { content }
|
21
|
+
BaseComponent.new(trim: @trim, **@base_component_arguments).render_in(self) { content }
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
@@ -18,9 +18,12 @@ module Primer
|
|
18
18
|
@layout = layout
|
19
19
|
@system_arguments = system_arguments
|
20
20
|
|
21
|
+
@system_arguments[:display] = :none if inputs.all?(&:hidden?)
|
22
|
+
|
21
23
|
@system_arguments[:classes] = class_names(
|
22
24
|
@system_arguments.delete(:classes),
|
23
|
-
"FormControl-horizontalGroup" => horizontal
|
25
|
+
"FormControl-horizontalGroup" => horizontal?,
|
26
|
+
"FormControl-spacingWrapper" => !horizontal? && inputs.size > 1
|
24
27
|
)
|
25
28
|
end
|
26
29
|
|
@@ -1877,3 +1877,66 @@
|
|
1877
1877
|
- flex-md-shrink-0
|
1878
1878
|
- flex-lg-shrink-0
|
1879
1879
|
- flex-xl-shrink-0
|
1880
|
+
:overflow:
|
1881
|
+
:auto:
|
1882
|
+
- overflow-auto
|
1883
|
+
- overflow-sm-auto
|
1884
|
+
- overflow-lg-auto
|
1885
|
+
- overflow-xl-auto
|
1886
|
+
:hidden:
|
1887
|
+
- overflow-hidden
|
1888
|
+
- overflow-sm-hidden
|
1889
|
+
- overflow-lg-hidden
|
1890
|
+
- overflow-xl-hidden
|
1891
|
+
:scroll:
|
1892
|
+
- overflow-scroll
|
1893
|
+
- overflow-sm-scroll
|
1894
|
+
- overflow-lg-scroll
|
1895
|
+
- overflow-xl-scroll
|
1896
|
+
:visible:
|
1897
|
+
- overflow-visible
|
1898
|
+
- overflow-sm-visible
|
1899
|
+
- overflow-lg-visible
|
1900
|
+
- overflow-xl-visible
|
1901
|
+
:overflow_x:
|
1902
|
+
:auto:
|
1903
|
+
- overflow-x-auto
|
1904
|
+
- overflow-sm-x-auto
|
1905
|
+
- overflow-lg-x-auto
|
1906
|
+
- overflow-xl-x-auto
|
1907
|
+
:hidden:
|
1908
|
+
- overflow-x-hidden
|
1909
|
+
- overflow-sm-x-hidden
|
1910
|
+
- overflow-lg-x-hidden
|
1911
|
+
- overflow-xl-x-hidden
|
1912
|
+
:scroll:
|
1913
|
+
- overflow-x-scroll
|
1914
|
+
- overflow-sm-x-scroll
|
1915
|
+
- overflow-lg-x-scroll
|
1916
|
+
- overflow-xl-x-scroll
|
1917
|
+
:visible:
|
1918
|
+
- overflow-x-visible
|
1919
|
+
- overflow-sm-x-visible
|
1920
|
+
- overflow-lg-x-visible
|
1921
|
+
- overflow-xl-x-visible
|
1922
|
+
:overflow_y:
|
1923
|
+
:auto:
|
1924
|
+
- overflow-y-auto
|
1925
|
+
- overflow-sm-y-auto
|
1926
|
+
- overflow-lg-y-auto
|
1927
|
+
- overflow-xl-y-auto
|
1928
|
+
:hidden:
|
1929
|
+
- overflow-y-hidden
|
1930
|
+
- overflow-sm-y-hidden
|
1931
|
+
- overflow-lg-y-hidden
|
1932
|
+
- overflow-xl-y-hidden
|
1933
|
+
:scroll:
|
1934
|
+
- overflow-y-scroll
|
1935
|
+
- overflow-sm-y-scroll
|
1936
|
+
- overflow-lg-y-scroll
|
1937
|
+
- overflow-xl-y-scroll
|
1938
|
+
:visible:
|
1939
|
+
- overflow-y-visible
|
1940
|
+
- overflow-sm-y-visible
|
1941
|
+
- overflow-lg-y-visible
|
1942
|
+
- overflow-xl-y-visible
|
data/lib/primer/classify.rb
CHANGED
@@ -49,9 +49,7 @@ module Primer
|
|
49
49
|
case key
|
50
50
|
when :classes
|
51
51
|
# insert :classes first to avoid huge doc diffs
|
52
|
-
|
53
|
-
result.unshift(class_names)
|
54
|
-
end
|
52
|
+
result.unshift(val)
|
55
53
|
next
|
56
54
|
when :style
|
57
55
|
style = val
|
@@ -105,29 +103,6 @@ module Primer
|
|
105
103
|
brk_str = Primer::Classify::Utilities::BREAKPOINTS[brk]
|
106
104
|
Primer::Classify::Utilities.validate(key, val, brk_str)
|
107
105
|
end
|
108
|
-
|
109
|
-
def validated_class_names(classes)
|
110
|
-
return if classes.blank?
|
111
|
-
|
112
|
-
if raise_on_invalid_options? && !ENV["PRIMER_WARNINGS_DISABLED"]
|
113
|
-
invalid_class_names =
|
114
|
-
classes.split.each_with_object([]) do |class_name, memo|
|
115
|
-
memo << class_name if Primer::Classify::Validation.invalid?(class_name)
|
116
|
-
end
|
117
|
-
|
118
|
-
if invalid_class_names.any?
|
119
|
-
raise ArgumentError, "Use System Arguments (https://primer.style/view-components/system-arguments) "\
|
120
|
-
"instead of Primer CSS class #{'name'.pluralize(invalid_class_names.length)} #{invalid_class_names.to_sentence}. "\
|
121
|
-
"This warning will not be raised in production. Set PRIMER_WARNINGS_DISABLED=1 to disable this warning."
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
classes
|
126
|
-
end
|
127
|
-
|
128
|
-
def raise_on_invalid_options?
|
129
|
-
Rails.application.config.primer_view_components.raise_on_invalid_options
|
130
|
-
end
|
131
106
|
end
|
132
107
|
end
|
133
108
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
export declare class PrimerMultiInputElement extends HTMLElement {
|
2
|
+
fields: HTMLInputElement[];
|
3
|
+
activateField(name: string): void;
|
4
|
+
private findField;
|
5
|
+
}
|
6
|
+
declare global {
|
7
|
+
interface Window {
|
8
|
+
PrimerMultiInputElement: typeof PrimerMultiInputElement;
|
9
|
+
}
|
10
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
6
|
+
};
|
7
|
+
/* eslint-disable custom-elements/expose-class-on-global */
|
8
|
+
import { controller, targets } from '@github/catalyst';
|
9
|
+
let PrimerMultiInputElement = class PrimerMultiInputElement extends HTMLElement {
|
10
|
+
activateField(name) {
|
11
|
+
const fieldWithName = this.findField(name);
|
12
|
+
if (!fieldWithName)
|
13
|
+
return;
|
14
|
+
for (const field of this.fields) {
|
15
|
+
if (field === fieldWithName)
|
16
|
+
continue;
|
17
|
+
field.setAttribute('disabled', 'disabled');
|
18
|
+
field.setAttribute('hidden', 'hidden');
|
19
|
+
field.parentElement?.setAttribute('hidden', 'hidden');
|
20
|
+
}
|
21
|
+
fieldWithName.removeAttribute('disabled');
|
22
|
+
fieldWithName.removeAttribute('hidden');
|
23
|
+
fieldWithName.parentElement?.removeAttribute('hidden');
|
24
|
+
}
|
25
|
+
findField(name) {
|
26
|
+
for (const field of this.fields) {
|
27
|
+
if (field.getAttribute('data-name') === name) {
|
28
|
+
return field;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
return null;
|
32
|
+
}
|
33
|
+
};
|
34
|
+
__decorate([
|
35
|
+
targets
|
36
|
+
], PrimerMultiInputElement.prototype, "fields", void 0);
|
37
|
+
PrimerMultiInputElement = __decorate([
|
38
|
+
controller
|
39
|
+
], PrimerMultiInputElement);
|
40
|
+
export { PrimerMultiInputElement };
|
41
|
+
if (!window.customElements.get('primer-multi-input')) {
|
42
|
+
Object.assign(window, { PrimerMultiInputElement });
|
43
|
+
window.customElements.define('primer-multi-input', PrimerMultiInputElement);
|
44
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import '@github/auto-check-element';
|
2
|
+
import type { AutoCheckErrorEvent, AutoCheckSuccessEvent } from '@github/auto-check-element';
|
3
|
+
declare global {
|
4
|
+
interface HTMLElementEventMap {
|
5
|
+
'auto-check-success': AutoCheckSuccessEvent;
|
6
|
+
'auto-check-error': AutoCheckErrorEvent;
|
7
|
+
}
|
8
|
+
}
|
9
|
+
export declare class PrimerTextFieldElement extends HTMLElement {
|
10
|
+
#private;
|
11
|
+
inputElement: HTMLInputElement;
|
12
|
+
validationElement: HTMLElement;
|
13
|
+
validationMessageElement: HTMLElement;
|
14
|
+
validationSuccessIcon: HTMLElement;
|
15
|
+
validationErrorIcon: HTMLElement;
|
16
|
+
leadingVisual: HTMLElement;
|
17
|
+
leadingSpinner: HTMLElement;
|
18
|
+
connectedCallback(): void;
|
19
|
+
disconnectedCallback(): void;
|
20
|
+
clearContents(): void;
|
21
|
+
clearError(): void;
|
22
|
+
setValidationMessage(message: string): void;
|
23
|
+
toggleValidationStyling(isError: boolean): void;
|
24
|
+
setSuccess(message: string): void;
|
25
|
+
setError(message: string): void;
|
26
|
+
showLeadingSpinner(): void;
|
27
|
+
hideLeadingSpinner(): void;
|
28
|
+
}
|
@@ -0,0 +1,119 @@
|
|
1
|
+
/* eslint-disable custom-elements/expose-class-on-global */
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
7
|
+
};
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
12
|
+
};
|
13
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
14
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
15
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
16
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
17
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
18
|
+
};
|
19
|
+
var _PrimerTextFieldElement_abortController;
|
20
|
+
import '@github/auto-check-element';
|
21
|
+
import { controller, target } from '@github/catalyst';
|
22
|
+
let PrimerTextFieldElement = class PrimerTextFieldElement extends HTMLElement {
|
23
|
+
constructor() {
|
24
|
+
super(...arguments);
|
25
|
+
_PrimerTextFieldElement_abortController.set(this, void 0);
|
26
|
+
}
|
27
|
+
connectedCallback() {
|
28
|
+
__classPrivateFieldGet(this, _PrimerTextFieldElement_abortController, "f")?.abort();
|
29
|
+
const { signal } = (__classPrivateFieldSet(this, _PrimerTextFieldElement_abortController, new AbortController(), "f"));
|
30
|
+
this.addEventListener('auto-check-success', async (event) => {
|
31
|
+
const message = await event.detail.response.text();
|
32
|
+
if (message && message.length > 0) {
|
33
|
+
this.setSuccess(message);
|
34
|
+
}
|
35
|
+
else {
|
36
|
+
this.clearError();
|
37
|
+
}
|
38
|
+
}, { signal });
|
39
|
+
this.addEventListener('auto-check-error', async (event) => {
|
40
|
+
const errorMessage = await event.detail.response.text();
|
41
|
+
this.setError(errorMessage);
|
42
|
+
}, { signal });
|
43
|
+
}
|
44
|
+
disconnectedCallback() {
|
45
|
+
__classPrivateFieldGet(this, _PrimerTextFieldElement_abortController, "f")?.abort();
|
46
|
+
}
|
47
|
+
clearContents() {
|
48
|
+
this.inputElement.value = '';
|
49
|
+
this.inputElement.focus();
|
50
|
+
this.inputElement.dispatchEvent(new Event('input', { bubbles: true, cancelable: false }));
|
51
|
+
}
|
52
|
+
clearError() {
|
53
|
+
this.inputElement.removeAttribute('invalid');
|
54
|
+
this.validationElement.hidden = true;
|
55
|
+
this.validationMessageElement.replaceChildren();
|
56
|
+
}
|
57
|
+
setValidationMessage(message) {
|
58
|
+
const template = document.createElement('template');
|
59
|
+
// eslint-disable-next-line github/no-inner-html
|
60
|
+
template.innerHTML = message;
|
61
|
+
const fragment = document.importNode(template.content, true);
|
62
|
+
this.validationMessageElement.replaceChildren(fragment);
|
63
|
+
}
|
64
|
+
toggleValidationStyling(isError) {
|
65
|
+
if (isError) {
|
66
|
+
this.validationElement.classList.remove('FormControl-inlineValidation--success');
|
67
|
+
}
|
68
|
+
else {
|
69
|
+
this.validationElement.classList.add('FormControl-inlineValidation--success');
|
70
|
+
}
|
71
|
+
this.validationSuccessIcon.hidden = isError;
|
72
|
+
this.validationErrorIcon.hidden = !isError;
|
73
|
+
this.inputElement.setAttribute('invalid', isError ? 'true' : 'false');
|
74
|
+
}
|
75
|
+
setSuccess(message) {
|
76
|
+
this.toggleValidationStyling(false);
|
77
|
+
this.setValidationMessage(message);
|
78
|
+
this.validationElement.hidden = false;
|
79
|
+
}
|
80
|
+
setError(message) {
|
81
|
+
this.toggleValidationStyling(true);
|
82
|
+
this.setValidationMessage(message);
|
83
|
+
this.validationElement.hidden = false;
|
84
|
+
}
|
85
|
+
showLeadingSpinner() {
|
86
|
+
this.leadingSpinner?.removeAttribute('hidden');
|
87
|
+
this.leadingVisual?.setAttribute('hidden', '');
|
88
|
+
}
|
89
|
+
hideLeadingSpinner() {
|
90
|
+
this.leadingSpinner?.setAttribute('hidden', '');
|
91
|
+
this.leadingVisual?.removeAttribute('hidden');
|
92
|
+
}
|
93
|
+
};
|
94
|
+
_PrimerTextFieldElement_abortController = new WeakMap();
|
95
|
+
__decorate([
|
96
|
+
target
|
97
|
+
], PrimerTextFieldElement.prototype, "inputElement", void 0);
|
98
|
+
__decorate([
|
99
|
+
target
|
100
|
+
], PrimerTextFieldElement.prototype, "validationElement", void 0);
|
101
|
+
__decorate([
|
102
|
+
target
|
103
|
+
], PrimerTextFieldElement.prototype, "validationMessageElement", void 0);
|
104
|
+
__decorate([
|
105
|
+
target
|
106
|
+
], PrimerTextFieldElement.prototype, "validationSuccessIcon", void 0);
|
107
|
+
__decorate([
|
108
|
+
target
|
109
|
+
], PrimerTextFieldElement.prototype, "validationErrorIcon", void 0);
|
110
|
+
__decorate([
|
111
|
+
target
|
112
|
+
], PrimerTextFieldElement.prototype, "leadingVisual", void 0);
|
113
|
+
__decorate([
|
114
|
+
target
|
115
|
+
], PrimerTextFieldElement.prototype, "leadingSpinner", void 0);
|
116
|
+
PrimerTextFieldElement = __decorate([
|
117
|
+
controller
|
118
|
+
], PrimerTextFieldElement);
|
119
|
+
export { PrimerTextFieldElement };
|