openproject-primer_view_components 0.49.2 → 0.50.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/app/assets/javascripts/primer_view_components.js +1 -1
  4. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  5. data/app/assets/styles/primer_view_components.css +1 -1
  6. data/app/assets/styles/primer_view_components.css.map +1 -1
  7. data/app/components/primer/alpha/action_bar.rb +2 -2
  8. data/app/components/primer/alpha/action_bar_element.js +0 -7
  9. data/app/components/primer/alpha/action_bar_element.ts +0 -8
  10. data/app/components/primer/base_component.rb +4 -1
  11. data/app/components/primer/beta/auto_complete.rb +1 -0
  12. data/app/components/primer/beta/button.rb +0 -11
  13. data/app/components/primer/beta/link.css +1 -1
  14. data/app/components/primer/beta/link.css.json +2 -1
  15. data/app/components/primer/beta/link.css.map +1 -1
  16. data/app/components/primer/beta/link.html.erb +18 -0
  17. data/app/components/primer/beta/link.pcss +9 -0
  18. data/app/components/primer/beta/link.rb +26 -14
  19. data/app/components/primer/button_component.rb +0 -11
  20. data/app/components/primer/component.rb +7 -0
  21. data/app/components/primer/conditional_wrapper.rb +5 -2
  22. data/app/forms/horizontal_form.rb +2 -0
  23. data/app/lib/primer/forms/auto_complete.rb +2 -1
  24. data/app/lib/primer/forms/dsl/hidden_input.rb +4 -0
  25. data/app/lib/primer/forms/group.rb +4 -1
  26. data/lib/primer/classify/utilities.yml +63 -0
  27. data/lib/primer/classify.rb +1 -26
  28. data/lib/primer/forms/primer_multi_input.d.ts +10 -0
  29. data/lib/primer/forms/primer_multi_input.js +44 -0
  30. data/lib/primer/forms/primer_text_field.d.ts +28 -0
  31. data/lib/primer/forms/primer_text_field.js +119 -0
  32. data/lib/primer/forms/toggle_switch_input.d.ts +5 -0
  33. data/lib/primer/forms/toggle_switch_input.js +34 -0
  34. data/lib/primer/static/generate_form_previews.rb +44 -0
  35. data/lib/primer/static.rb +8 -0
  36. data/lib/primer/view_components/version.rb +2 -2
  37. data/lib/rubocop/config/default.yml +0 -3
  38. data/lib/tasks/custom_utilities.yml +63 -0
  39. data/previews/primer/beta/link_preview.rb +24 -2
  40. data/previews/primer/forms_preview.rb +21 -0
  41. data/static/classes.json +3 -0
  42. data/static/form_previews.json +113 -0
  43. metadata +11 -3
  44. data/lib/rubocop/cop/primer/system_argument_instead_of_class.rb +0 -57
@@ -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}
@@ -13,6 +13,7 @@
13
13
  ".Link--muted",
14
14
  ".Link--muted:hover",
15
15
  ".Link--onHover:hover",
16
- ":is(.Link--secondary,.Link--primary,.Link--muted):hover [class*=color-fg]"
16
+ ":is(.Link--secondary,.Link--primary,.Link--muted):hover [class*=color-fg]",
17
+ ".Link-content"
17
18
  ]
18
19
  }
@@ -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 %>
@@ -67,3 +67,12 @@
67
67
  color: inherit !important;
68
68
  }
69
69
  }
70
+
71
+ .Link-content {
72
+ display: inline-flex;
73
+ align-items: center;
74
+ /* stylelint-disable-next-line primer/typography */
75
+ line-height: normal;
76
+ gap: var(--base-size-4);
77
+ text-decoration: inherit;
78
+ }
@@ -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
- return content unless @condition
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
@@ -3,6 +3,8 @@
3
3
  # :nodoc:
4
4
  class HorizontalForm < ApplicationForm
5
5
  form do |my_form|
6
+ my_form.hidden(name: :token, value: "abc123")
7
+
6
8
  my_form.group(layout: :horizontal) do |name_group|
7
9
  name_group.text_field(
8
10
  name: :first_name,
@@ -40,7 +40,8 @@ module Primer
40
40
  input_name: all_args[:name],
41
41
  input_id: all_args[:id],
42
42
  label_text: @input.label,
43
- list_id: "#{all_args[:id]}-list"
43
+ list_id: "#{all_args[:id]}-list",
44
+ full_width: @input.full_width?
44
45
  )
45
46
  end
46
47
 
@@ -27,6 +27,10 @@ module Primer
27
27
  def supports_validation?
28
28
  false
29
29
  end
30
+
31
+ def hidden?
32
+ true
33
+ end
30
34
  end
31
35
  end
32
36
  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
@@ -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
- if (class_names = validated_class_names(val))
53
- result.unshift(class_names)
54
- end
52
+ result.unshift(val) unless val.blank?
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 };
@@ -0,0 +1,5 @@
1
+ export declare class ToggleSwitchInputElement extends HTMLElement {
2
+ validationElement: HTMLElement;
3
+ validationMessageElement: HTMLElement;
4
+ connectedCallback(): void;
5
+ }