openproject-primer_view_components 0.52.0 → 0.52.2

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -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_list/divider.rb +4 -0
  8. data/app/components/primer/alpha/action_menu/action_menu_element.js +1 -0
  9. data/app/components/primer/alpha/action_menu/action_menu_element.ts +1 -0
  10. data/app/components/primer/alpha/dialog.css +1 -1
  11. data/app/components/primer/alpha/dialog.css.json +0 -1
  12. data/app/components/primer/alpha/dialog.css.map +1 -1
  13. data/app/components/primer/alpha/dialog.pcss +0 -5
  14. data/app/components/primer/alpha/text_field.css +1 -1
  15. data/app/components/primer/alpha/text_field.css.json +14 -0
  16. data/app/components/primer/alpha/text_field.css.map +1 -1
  17. data/app/components/primer/alpha/text_field.pcss +89 -2
  18. data/app/components/primer/open_project/danger_confirmation_dialog/confirmation_check_box.rb +1 -0
  19. data/app/components/primer/open_project/danger_confirmation_dialog/form_wrapper.rb +2 -0
  20. data/app/components/primer/open_project/danger_confirmation_dialog.html.erb +1 -1
  21. data/app/components/primer/open_project/danger_confirmation_dialog.rb +8 -8
  22. data/app/components/primer/open_project/feedback_dialog.rb +6 -4
  23. data/app/lib/primer/forms/acts_as_component.rb +32 -17
  24. data/app/lib/primer/forms/base_component.rb +5 -12
  25. data/app/lib/primer/forms/dsl/text_field_input.rb +10 -7
  26. data/app/lib/primer/forms/text_field.html.erb +5 -0
  27. data/app/lib/primer/forms/text_field.rb +37 -0
  28. data/lib/primer/classify/utilities.yml +1 -1
  29. data/lib/primer/view_components/version.rb +1 -1
  30. data/previews/primer/alpha/text_field_preview.rb +30 -0
  31. data/static/arguments.json +67 -0
  32. data/static/audited_at.json +3 -0
  33. data/static/constants.json +11 -0
  34. data/static/form_previews.json +5 -0
  35. data/static/info_arch.json +366 -15
  36. data/static/previews.json +177 -0
  37. data/static/statuses.json +3 -0
  38. metadata +2 -2
@@ -5,6 +5,8 @@ module Primer
5
5
  class DangerConfirmationDialog
6
6
  # Utility component for wrapping DangerConfirmationDialog in a form
7
7
  class FormWrapper < Primer::Component
8
+ status :open_project
9
+
8
10
  def initialize(builder: nil, action: nil, **form_arguments)
9
11
  raise ArgumentError, "Pass in either a :builder or :action argument, not both." if builder && action
10
12
 
@@ -11,7 +11,7 @@
11
11
  <% end %>
12
12
  </scrollable-region>
13
13
  <%= render(Primer::Alpha::Dialog::Footer.new(show_divider: false)) do %>
14
- <%= render(Primer::Beta::Button.new(data: { "close-dialog-id": dialog_id })) { I18n.t("button_close") } %>
14
+ <%= render(Primer::Beta::Button.new(data: { "close-dialog-id": dialog_id })) { I18n.t("button_cancel") } %>
15
15
  <%= render(Primer::Beta::Button.new(type: (@form_wrapper.shows_form? ? :submit : :button), scheme: :danger, data: { "submit-dialog-id": dialog_id })) { I18n.t("button_delete_permanently") } %>
16
16
  <% end %>
17
17
  <% end %>
@@ -12,8 +12,10 @@ module Primer
12
12
 
13
13
  # A confirmation message with some defaults that are necessary for rendering nicely.
14
14
  #
15
- # @param heading [String] the heading for the success message
16
- # @param description [String] the description for the success message
15
+ # To render the message heading (required), call the `with_heading` method, which accepts a `:tag` argument, along with the arguments accepted by <%= link_to_component(Primer::Beta::Heading) %>.
16
+ #
17
+ # To render the message description, call the `with_description` method, which accepts <%= link_to_system_arguments_docs %>
18
+ #
17
19
  # @param icon_arguments [Hash] the system_arguments for the icon
18
20
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
19
21
  renders_one :confirmation_message, lambda { |icon_arguments: {}, **system_arguments|
@@ -27,6 +29,8 @@ module Primer
27
29
 
28
30
  # A checkbox that the user is required to check in order to continue with the destructive action.
29
31
  #
32
+ # To render the checkbox label (required), pass a block that returns a String.
33
+ #
30
34
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
31
35
  renders_one :confirmation_check_box, lambda { |**system_arguments|
32
36
  system_arguments[:display] ||= :flex
@@ -38,7 +42,7 @@ module Primer
38
42
  Primer::OpenProject::DangerConfirmationDialog::ConfirmationCheckBox.new(check_box_id: check_box_id, check_box_name: @check_box_name, **system_arguments)
39
43
  }
40
44
 
41
- # Optional additional_details such as grid displaying a list of items to be deleted
45
+ # Optional additional details, such as grid displaying a list of items to be deleted
42
46
  #
43
47
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
44
48
  renders_one :additional_details, lambda { |**system_arguments|
@@ -57,11 +61,7 @@ module Primer
57
61
  Primer::BaseComponent.new(**system_arguments)
58
62
  }
59
63
 
60
- # @param form_arguments [Hash] Allows the dialog to submit a form. Pass EITHER the `builder:` option to this hash
61
- # to reuse an existing Rails form, or `action:` if you prefer the component to render the form tag itself.
62
- # `builder:` should be an instance of `ActionView::Helpers::FormBuilder`, which is created by the standard Rails
63
- # `#form_with` and `#form_for` helpers. The `name:` option is the desired name of the field that will be included
64
- # in the params sent to the server on form submission.
64
+ # @param form_arguments [Hash] Allows the dialog to submit a form. Pass EITHER the `builder:` option to this hash to reuse an existing Rails form, or `action:` if you prefer the component to render the form tag itself. `builder:` should be an instance of `ActionView::Helpers::FormBuilder`, which is created by the standard Rails `#form_with` and `#form_for` helpers. The `name:` option is the desired name of the field that will be included in the params sent to the server on form submission.
65
65
  # @param id [String] The id of the dialog.
66
66
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
67
67
  def initialize(
@@ -6,10 +6,12 @@ module Primer
6
6
  class FeedbackDialog < Primer::Component
7
7
  status :open_project
8
8
 
9
- # A feedback message with some defaults that are necessary for rendering nicely
9
+ # A feedback message with some defaults that are necessary for rendering nicely.
10
+ #
11
+ # To render the message heading (required), call the `with_heading` method, which accepts a `:tag` argument, along with the arguments accepted by <%= link_to_component(Primer::Beta::Heading) %>.
12
+ #
13
+ # To render the message description, call the `with_description` method, which accepts <%= link_to_system_arguments_docs %>
10
14
  #
11
- # @param heading [String] the heading for the success message
12
- # @param description [String] the description for the success message
13
15
  # @param icon_arguments [Hash] the system_arguments for the icon
14
16
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
15
17
  renders_one :feedback_message, lambda { |icon_arguments: {}, **system_arguments|
@@ -17,7 +19,7 @@ module Primer
17
19
  Primer::OpenProject::FeedbackMessage.new(icon_arguments: icon_arguments, **system_arguments)
18
20
  }
19
21
 
20
- # Optional additional_details like a form input or toast.
22
+ # Optional additional details, like a form input or toast.
21
23
  #
22
24
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
23
25
  renders_one :additional_details, lambda { |**system_arguments|
@@ -66,30 +66,45 @@ module Primer
66
66
  @compiled = true
67
67
  end
68
68
 
69
- private
70
-
71
69
  def template_root_path
72
70
  return @template_root_path if defined?(@template_root_path)
73
71
 
74
72
  form_path = Utils.const_source_location(self.name)
75
- @template_root_path = if form_path
76
- File.join(File.dirname(form_path), self.name.demodulize.underscore)
73
+ @template_root_path =
74
+ if form_path
75
+ File.join(File.dirname(form_path), self.name.demodulize.underscore)
76
+ end
77
+ end
78
+
79
+ def base_template_path
80
+ return @base_template_path if defined?(@base_template_path)
81
+ base_path = Utils.const_source_location(self.name)
82
+
83
+ if base_path
84
+ @base_template_path = File.dirname(base_path)
85
+ else
86
+ warn "Could not identify the template for #{self}"
77
87
  end
78
88
  end
79
89
 
90
+ private
91
+
80
92
  def template_globs
81
93
  @template_globs ||= []
82
94
  end
83
95
 
84
96
  def compile_templates_in(template_glob)
85
- pattern = if Pathname(template_glob.glob_pattern).absolute?
86
- template_glob.glob_pattern
87
- else
88
- # skip compilation for anonymous form classes, as in tests
89
- return unless template_root_path
90
-
91
- File.join(template_root_path, template_glob.glob_pattern)
92
- end
97
+ pattern = template_glob.glob_pattern
98
+ pattern = pattern.gsub("%{base_template_path}", base_template_path) if base_template_path
99
+ pattern =
100
+ if Pathname(pattern).absolute?
101
+ pattern
102
+ else
103
+ # skip compilation for anonymous form classes, as in tests
104
+ return unless template_root_path
105
+
106
+ File.join(template_root_path, pattern)
107
+ end
93
108
 
94
109
  template_paths = Dir.glob(pattern)
95
110
 
@@ -117,11 +132,11 @@ module Primer
117
132
  handler = ActionView::Template.handler_for_extension("erb")
118
133
  template = File.read(path)
119
134
  template_params = TemplateParams.new({
120
- source: template,
121
- identifier: __FILE__,
122
- type: "text/html",
123
- format: "text/html"
124
- })
135
+ source: template,
136
+ identifier: __FILE__,
137
+ type: "text/html",
138
+ format: "text/html"
139
+ })
125
140
 
126
141
  # change @output_buffer ivar to output_buffer method call
127
142
  BufferRewriter.rewrite(
@@ -7,18 +7,11 @@ module Primer
7
7
  include Primer::ClassNameHelper
8
8
  extend ActsAsComponent
9
9
 
10
- def self.compile!
11
- base_path = Utils.const_source_location(self.name)
12
-
13
- unless base_path
14
- warn "Could not identify the template for #{base}"
15
- return
16
- end
17
-
18
- dir = File.dirname(base_path)
19
- renders_template File.join(dir, "#{self.name.demodulize.underscore}.html.erb"), :render_template
20
-
21
- super
10
+ def self.inherited(base)
11
+ base.renders_template(
12
+ File.join("%{base_template_path}", "#{base.name.demodulize.underscore}.html.erb"),
13
+ :render_template
14
+ )
22
15
  end
23
16
 
24
17
  delegate :required?, :disabled?, :hidden?, to: :@input
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Primer
4
2
  module Forms
5
3
  module Dsl
@@ -7,7 +5,7 @@ module Primer
7
5
  class TextFieldInput < Input
8
6
  attr_reader(
9
7
  *%i[
10
- name label show_clear_button leading_visual leading_spinner clear_button_id
8
+ name label show_clear_button leading_visual leading_spinner trailing_visual clear_button_id
11
9
  visually_hide_label inset monospace field_wrap_classes auto_check_src
12
10
  ]
13
11
  )
@@ -20,6 +18,7 @@ module Primer
20
18
 
21
19
  @show_clear_button = system_arguments.delete(:show_clear_button)
22
20
  @leading_visual = system_arguments.delete(:leading_visual)
21
+ @trailing_visual = system_arguments.delete(:trailing_visual)
23
22
  @leading_spinner = !!system_arguments.delete(:leading_spinner)
24
23
  @clear_button_id = system_arguments.delete(:clear_button_id)
25
24
  @inset = system_arguments.delete(:inset)
@@ -48,6 +47,14 @@ module Primer
48
47
  alias inset? inset
49
48
  alias monospace? monospace
50
49
 
50
+ def trailing_visual?
51
+ !!@trailing_visual
52
+ end
53
+
54
+ def leading_visual?
55
+ !!@leading_visual
56
+ end
57
+
51
58
  def to_component
52
59
  TextField.new(input: self)
53
60
  end
@@ -60,10 +67,6 @@ module Primer
60
67
  true
61
68
  end
62
69
 
63
- def leading_visual?
64
- !!@leading_visual
65
- end
66
-
67
70
  def validation_arguments
68
71
  if auto_check_src.present?
69
72
  super.merge(
@@ -17,5 +17,10 @@
17
17
  <%= render(Primer::Beta::Octicon.new(icon: :"x-circle-fill")) %>
18
18
  </button>
19
19
  <% end %>
20
+ <% if @input.trailing_visual %>
21
+ <div class="FormControl-input-trailingVisualWrap">
22
+ <%= render(trailing_visual_component) %>
23
+ </div>
24
+ <% end %>
20
25
  <% end %>
21
26
  <% end %>
@@ -23,6 +23,7 @@ module Primer
23
23
  "FormControl-input-wrap",
24
24
  INPUT_WRAP_SIZE[input.size],
25
25
  { "FormControl-input-wrap--trailingAction": @input.show_clear_button? },
26
+ { "FormControl-input-wrap--trailingVisual": @input.trailing_visual? },
26
27
  { "FormControl-input-wrap--leadingVisual": @input.leading_visual? }
27
28
  ]
28
29
  wrap_classes << Primer::Forms::Dsl::Input::INPUT_WIDTH_MAPPINGS[@input.input_width] if @input.input_width
@@ -43,6 +44,42 @@ module Primer
43
44
  )
44
45
  end
45
46
  end
47
+
48
+ def trailing_visual_component
49
+ return @trailing_visual_component if defined?(@trailing_visual_component)
50
+ visual = @input.trailing_visual
51
+
52
+ # Render icon if specified
53
+ @trailing_visual_component =
54
+ if (icon_arguments = visual[:icon])
55
+ Primer::Beta::Octicon.new(**icon_arguments)
56
+ elsif (label_arguments = visual[:label])
57
+ # Render label if specified
58
+ label_arguments[:classes] = class_names(
59
+ label_arguments.delete(:classes),
60
+ "FormControl-input-trailingVisualLabel"
61
+ )
62
+
63
+ text = label_arguments.delete(:text)
64
+ Primer::Beta::Label.new(**label_arguments).with_content(text)
65
+ elsif (counter_arguments = visual[:counter])
66
+ # Render counter if specified
67
+ counter_arguments[:classes] = class_names(
68
+ counter_arguments.delete(:classes),
69
+ "FormControl-input-trailingVisualCounter"
70
+ )
71
+
72
+ Primer::Beta::Counter.new(**counter_arguments)
73
+ elsif (truncate_arguments = visual[:text])
74
+ # Render text if specified
75
+ truncate_arguments[:classes] = class_names(
76
+ truncate_arguments.delete(:classes),
77
+ "FormControl-input-trailingVisualText"
78
+ )
79
+ text = truncate_arguments.delete(:text)
80
+ Primer::Beta::Truncate.new(**truncate_arguments).with_content(text)
81
+ end
82
+ end
46
83
  end
47
84
  end
48
85
  end
@@ -1939,4 +1939,4 @@
1939
1939
  - overflow-y-visible
1940
1940
  - overflow-sm-y-visible
1941
1941
  - overflow-lg-y-visible
1942
- - overflow-xl-y-visible
1942
+ - overflow-xl-y-visible
@@ -6,7 +6,7 @@ module Primer
6
6
  module VERSION
7
7
  MAJOR = 0
8
8
  MINOR = 52
9
- PATCH = 0
9
+ PATCH = 2
10
10
 
11
11
  STRING = [MAJOR, MINOR, PATCH].join(".")
12
12
  end
@@ -175,6 +175,36 @@ module Primer
175
175
  render(Primer::Alpha::TextField.new(monospace: true, name: "my-text-field", label: "My text field"))
176
176
  end
177
177
 
178
+ # @label With trailing icon
179
+ # @snapshot
180
+ def with_trailing_icon
181
+ render(Primer::Alpha::TextField.new(trailing_visual: { icon: { icon: :search } }, name: "my-text-field", label: "My text field"))
182
+ end
183
+
184
+ # @label With trailing text
185
+ # @snapshot
186
+ def with_trailing_text
187
+ render(Primer::Alpha::TextField.new(trailing_visual: { text: { text: "minute" } }, name: "my-text-field", label: "My text field"))
188
+ end
189
+
190
+ # @label With trailing long text
191
+ # @snapshot
192
+ def with_trailing_long_text
193
+ render(Primer::Alpha::TextField.new(trailing_visual: { text: { text: "Long trailing text" } }, name: "my-text-field", label: "My text field"))
194
+ end
195
+
196
+ # @label With trailing counter
197
+ # @snapshot
198
+ def with_trailing_counter
199
+ render(Primer::Alpha::TextField.new(trailing_visual: { counter: { count: 5 } }, name: "my-text-field", label: "My text field"))
200
+ end
201
+
202
+ # @label With trailing label
203
+ # @snapshot
204
+ def with_trailing_label
205
+ render(Primer::Alpha::TextField.new(trailing_visual: { label: { text: "Hello" } }, name: "my-text-field", label: "My text field"))
206
+ end
207
+
178
208
  # @label With leading visual
179
209
  # @snapshot
180
210
  def with_leading_visual
@@ -5105,6 +5105,73 @@
5105
5105
  }
5106
5106
  ]
5107
5107
  },
5108
+ {
5109
+ "component": "OpenProject::DangerConfirmationDialog",
5110
+ "status": "open_project",
5111
+ "a11y_reviewed": false,
5112
+ "short_name": "OpenProjectDangerConfirmationDialog",
5113
+ "source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/danger_confirmation_dialog.rb",
5114
+ "lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/danger_confirmation_dialog/default/",
5115
+ "parameters": [
5116
+ {
5117
+ "name": "form_arguments",
5118
+ "type": "Hash",
5119
+ "default": "`{}`",
5120
+ "description": "Allows the dialog to submit a form. Pass EITHER the `builder:` option to this hash to reuse an existing Rails form, or `action:` if you prefer the component to render the form tag itself. `builder:` should be an instance of `ActionView::Helpers::FormBuilder`, which is created by the standard Rails `#form_with` and `#form_for` helpers. The `name:` option is the desired name of the field that will be included in the params sent to the server on form submission."
5121
+ },
5122
+ {
5123
+ "name": "id",
5124
+ "type": "String",
5125
+ "default": "`self.class.generate_id`",
5126
+ "description": "The id of the dialog."
5127
+ },
5128
+ {
5129
+ "name": "system_arguments",
5130
+ "type": "Hash",
5131
+ "default": "N/A",
5132
+ "description": "[System arguments](/system-arguments)"
5133
+ }
5134
+ ]
5135
+ },
5136
+ {
5137
+ "component": "OpenProject::DangerConfirmationDialog::ConfirmationCheckBox",
5138
+ "status": "open_project",
5139
+ "a11y_reviewed": false,
5140
+ "short_name": "OpenProjectDangerConfirmationDialogConfirmationCheckBox",
5141
+ "source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/danger_confirmation_dialog/confirmation_check_box.rb",
5142
+ "lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/danger_confirmation_dialog/confirmation_check_box/default/",
5143
+ "parameters": [
5144
+ {
5145
+ "name": "check_box_id",
5146
+ "type": "String",
5147
+ "default": "`self.class.generate_id`",
5148
+ "description": "The id of the check_box input."
5149
+ },
5150
+ {
5151
+ "name": "check_box_name",
5152
+ "type": "String",
5153
+ "default": "N/A",
5154
+ "description": "The name of the check_box input."
5155
+ },
5156
+ {
5157
+ "name": "system_arguments",
5158
+ "type": "Hash",
5159
+ "default": "N/A",
5160
+ "description": "[System arguments](/system-arguments)"
5161
+ }
5162
+ ]
5163
+ },
5164
+ {
5165
+ "component": "OpenProject::DangerConfirmationDialog::FormWrapper",
5166
+ "status": "open_project",
5167
+ "a11y_reviewed": false,
5168
+ "short_name": "OpenProjectDangerConfirmationDialogFormWrapper",
5169
+ "source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/danger_confirmation_dialog/form_wrapper.rb",
5170
+ "lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/danger_confirmation_dialog/form_wrapper/default/",
5171
+ "parameters": [
5172
+
5173
+ ]
5174
+ },
5108
5175
  {
5109
5176
  "component": "OpenProject::DragHandle",
5110
5177
  "status": "open_project",
@@ -118,6 +118,9 @@
118
118
  "Primer::Navigation::TabComponent": "",
119
119
  "Primer::OpenProject::BorderGrid": "",
120
120
  "Primer::OpenProject::BorderGrid::Cell": "",
121
+ "Primer::OpenProject::DangerConfirmationDialog": "",
122
+ "Primer::OpenProject::DangerConfirmationDialog::ConfirmationCheckBox": "",
123
+ "Primer::OpenProject::DangerConfirmationDialog::FormWrapper": "",
121
124
  "Primer::OpenProject::DragHandle": "",
122
125
  "Primer::OpenProject::FeedbackDialog": "",
123
126
  "Primer::OpenProject::FeedbackMessage": "",
@@ -1561,6 +1561,17 @@
1561
1561
  "Primer::OpenProject::BorderGrid::Cell": {
1562
1562
  "GeneratedSlotMethods": "Primer::OpenProject::BorderGrid::Cell::GeneratedSlotMethods"
1563
1563
  },
1564
+ "Primer::OpenProject::DangerConfirmationDialog": {
1565
+ "ConfirmationCheckBox": "Primer::OpenProject::DangerConfirmationDialog::ConfirmationCheckBox",
1566
+ "FormWrapper": "Primer::OpenProject::DangerConfirmationDialog::FormWrapper",
1567
+ "GeneratedSlotMethods": "Primer::OpenProject::DangerConfirmationDialog::GeneratedSlotMethods"
1568
+ },
1569
+ "Primer::OpenProject::DangerConfirmationDialog::ConfirmationCheckBox": {
1570
+ "GeneratedSlotMethods": "Primer::OpenProject::DangerConfirmationDialog::ConfirmationCheckBox::GeneratedSlotMethods"
1571
+ },
1572
+ "Primer::OpenProject::DangerConfirmationDialog::FormWrapper": {
1573
+ "GeneratedSlotMethods": "Primer::OpenProject::DangerConfirmationDialog::FormWrapper::GeneratedSlotMethods"
1574
+ },
1564
1575
  "Primer::OpenProject::DragHandle": {
1565
1576
  "DEFAULT_SIZE": "small",
1566
1577
  "GeneratedSlotMethods": "Primer::OpenProject::DragHandle::GeneratedSlotMethods",
@@ -13,6 +13,11 @@
13
13
  "name": "multi_text_field_form",
14
14
  "snapshot": "true"
15
15
  },
16
+ {
17
+ "preview_path": "primer/forms/custom_width_fields_form",
18
+ "name": "custom_width_fields_form",
19
+ "snapshot": "false"
20
+ },
16
21
  {
17
22
  "preview_path": "primer/forms/text_field_and_checkbox_form",
18
23
  "name": "text_field_and_checkbox_form",