openproject-primer_view_components 0.79.1 → 0.80.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- 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/open_project/fieldset.html.erb +8 -0
- data/app/components/primer/open_project/fieldset.rb +66 -0
- data/app/components/primer/open_project/inline_message.css +1 -0
- data/app/components/primer/open_project/inline_message.css.json +13 -0
- data/app/components/primer/open_project/inline_message.css.map +1 -0
- data/app/components/primer/open_project/inline_message.html.erb +4 -0
- data/app/components/primer/open_project/inline_message.pcss +42 -0
- data/app/components/primer/open_project/inline_message.rb +65 -0
- data/app/components/primer/open_project/page_header.rb +18 -1
- data/app/components/primer/primer.pcss +1 -0
- data/app/lib/primer/forms/dsl/fieldset_group_input.rb +35 -0
- data/app/lib/primer/forms/dsl/form_object.rb +4 -0
- data/app/lib/primer/forms/fieldset_group.html.erb +10 -0
- data/app/lib/primer/forms/fieldset_group.rb +54 -0
- data/lib/primer/view_components/version.rb +2 -2
- data/previews/primer/forms_preview/fieldset_group_form.html.erb +40 -0
- data/previews/primer/forms_preview.rb +3 -0
- data/previews/primer/open_project/inline_message_preview/default.html.erb +5 -0
- data/previews/primer/open_project/inline_message_preview/playground.html.erb +5 -0
- data/previews/primer/open_project/inline_message_preview.rb +22 -0
- data/static/arguments.json +65 -0
- data/static/audited_at.json +3 -0
- data/static/classes.json +6 -0
- data/static/constants.json +22 -0
- data/static/form_previews.json +5 -0
- data/static/info_arch.json +142 -0
- data/static/previews.json +34 -0
- data/static/statuses.json +3 -0
- metadata +17 -2
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module OpenProject
|
|
5
|
+
# A low-level component for building fieldsets with unopinionated styling.
|
|
6
|
+
#
|
|
7
|
+
# This component is not designed to be used directly, but rather a primitive for
|
|
8
|
+
# authors of other components and form controls.
|
|
9
|
+
class Fieldset < Primer::Component
|
|
10
|
+
status :open_project
|
|
11
|
+
|
|
12
|
+
attr_reader :legend_text
|
|
13
|
+
|
|
14
|
+
renders_one :legend, ->(**system_arguments) {
|
|
15
|
+
LegendComponent.new(visually_hide_legend: @visually_hide_legend, **system_arguments)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
# @param legend_text [String] A legend should be short and concise. The String will also be read by assistive technology.
|
|
19
|
+
# @param visually_hide_legend [Boolean] Controls if the legend is visible. If `true`, screen reader only text will be added.
|
|
20
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
|
21
|
+
def initialize(legend_text: nil, visually_hide_legend: false, **system_arguments) # rubocop:disable Lint/MissingSuper
|
|
22
|
+
@legend_text = legend_text
|
|
23
|
+
@visually_hide_legend = visually_hide_legend
|
|
24
|
+
@system_arguments = deny_tag_argument(**system_arguments)
|
|
25
|
+
@system_arguments[:tag] = :fieldset
|
|
26
|
+
|
|
27
|
+
deny_aria_key(
|
|
28
|
+
:label,
|
|
29
|
+
"instead of `aria-label`, include `legend_text` and set `visually_hide_legend` to `true` on the component initializer.",
|
|
30
|
+
**@system_arguments
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def render?
|
|
35
|
+
content? && (legend_text.present? || legend?)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class LegendComponent < Primer::Component
|
|
39
|
+
status :open_project
|
|
40
|
+
|
|
41
|
+
attr_reader :text
|
|
42
|
+
|
|
43
|
+
def initialize(text: nil, visually_hide_legend: false, **system_arguments) # rubocop:disable Lint/MissingSuper
|
|
44
|
+
@text = text
|
|
45
|
+
|
|
46
|
+
@system_arguments = deny_tag_argument(**system_arguments)
|
|
47
|
+
@system_arguments[:tag] = :legend
|
|
48
|
+
@system_arguments[:classes] = class_names(
|
|
49
|
+
@system_arguments[:classes],
|
|
50
|
+
{ "sr-only" => visually_hide_legend }
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def call
|
|
55
|
+
render(Primer::BaseComponent.new(**@system_arguments)) { legend_content }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def legend_content
|
|
61
|
+
@legend_content ||= content || text
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.InlineMessage{align-items:start;color:var(--inline-message-fgColor);column-gap:.5rem;display:grid;font-size:var(--inline-message-fontSize);grid-template-columns:auto 1fr;line-height:var(--inline-message-lineHeight)}.InlineMessage[data-size=small]{--inline-message-fontSize:var(--text-body-size-small);--inline-message-lineHeight:var(--text-body-lineHeight-small,1.6666)}.InlineMessage[data-size=medium]{--inline-message-fontSize:var(--text-body-size-medium);--inline-message-lineHeight:var(--text-body-lineHeight-medium,1.4285)}.InlineMessage[data-variant=warning]{--inline-message-fgColor:var(--fgColor-attention)}.InlineMessage[data-variant=critical]{--inline-message-fgColor:var(--fgColor-danger)}.InlineMessage[data-variant=success]{--inline-message-fgColor:var(--fgColor-success)}.InlineMessage[data-variant=unavailable]{--inline-message-fgColor:var(--fgColor-muted)}.InlineMessageIcon{min-height:calc(var(--inline-message-lineHeight)*var(--inline-message-fontSize))}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "open_project/inline_message",
|
|
3
|
+
"selectors": [
|
|
4
|
+
".InlineMessage",
|
|
5
|
+
".InlineMessage[data-size=small]",
|
|
6
|
+
".InlineMessage[data-size=medium]",
|
|
7
|
+
".InlineMessage[data-variant=warning]",
|
|
8
|
+
".InlineMessage[data-variant=critical]",
|
|
9
|
+
".InlineMessage[data-variant=success]",
|
|
10
|
+
".InlineMessage[data-variant=unavailable]",
|
|
11
|
+
".InlineMessageIcon"
|
|
12
|
+
]
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["inline_message.pcss"],"names":[],"mappings":"AAAA,eAUE,iBAAkB,CAHlB,mCAAoC,CACpC,gBAAkB,CAPlB,YAAa,CAEb,wCAAyC,CAMzC,8BAA+B,CAJ/B,4CAgCF,CAzBE,gCACE,qDAAsD,CACtD,oEACF,CAEA,iCACE,sDAAuD,CACvD,qEACF,CAEA,qCACE,iDACF,CAEA,sCACE,8CACF,CAEA,qCACE,+CACF,CAEA,yCACE,6CACF,CAGF,mBACE,gFACF","file":"inline_message.css","sourcesContent":[".InlineMessage {\n display: grid;\n /* stylelint-disable-next-line primer/typography */\n font-size: var(--inline-message-fontSize);\n /* stylelint-disable-next-line primer/typography */\n line-height: var(--inline-message-lineHeight);\n /* stylelint-disable-next-line primer/colors */\n color: var(--inline-message-fgColor);\n column-gap: 0.5rem;\n grid-template-columns: auto 1fr;\n align-items: start;\n\n &[data-size='small'] {\n --inline-message-fontSize: var(--text-body-size-small);\n --inline-message-lineHeight: var(--text-body-lineHeight-small, 1.6666);\n }\n\n &[data-size='medium'] {\n --inline-message-fontSize: var(--text-body-size-medium);\n --inline-message-lineHeight: var(--text-body-lineHeight-medium, 1.4285);\n }\n\n &[data-variant='warning'] {\n --inline-message-fgColor: var(--fgColor-attention);\n }\n\n &[data-variant='critical'] {\n --inline-message-fgColor: var(--fgColor-danger);\n }\n\n &[data-variant='success'] {\n --inline-message-fgColor: var(--fgColor-success);\n }\n\n &[data-variant='unavailable'] {\n --inline-message-fgColor: var(--fgColor-muted);\n }\n}\n\n.InlineMessageIcon {\n min-height: calc(var(--inline-message-lineHeight) * var(--inline-message-fontSize));\n}"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
.InlineMessage {
|
|
2
|
+
display: grid;
|
|
3
|
+
/* stylelint-disable-next-line primer/typography */
|
|
4
|
+
font-size: var(--inline-message-fontSize);
|
|
5
|
+
/* stylelint-disable-next-line primer/typography */
|
|
6
|
+
line-height: var(--inline-message-lineHeight);
|
|
7
|
+
/* stylelint-disable-next-line primer/colors */
|
|
8
|
+
color: var(--inline-message-fgColor);
|
|
9
|
+
column-gap: 0.5rem;
|
|
10
|
+
grid-template-columns: auto 1fr;
|
|
11
|
+
align-items: start;
|
|
12
|
+
|
|
13
|
+
&[data-size='small'] {
|
|
14
|
+
--inline-message-fontSize: var(--text-body-size-small);
|
|
15
|
+
--inline-message-lineHeight: var(--text-body-lineHeight-small, 1.6666);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
&[data-size='medium'] {
|
|
19
|
+
--inline-message-fontSize: var(--text-body-size-medium);
|
|
20
|
+
--inline-message-lineHeight: var(--text-body-lineHeight-medium, 1.4285);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&[data-variant='warning'] {
|
|
24
|
+
--inline-message-fgColor: var(--fgColor-attention);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&[data-variant='critical'] {
|
|
28
|
+
--inline-message-fgColor: var(--fgColor-danger);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&[data-variant='success'] {
|
|
32
|
+
--inline-message-fgColor: var(--fgColor-success);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&[data-variant='unavailable'] {
|
|
36
|
+
--inline-message-fgColor: var(--fgColor-muted);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.InlineMessageIcon {
|
|
41
|
+
min-height: calc(var(--inline-message-lineHeight) * var(--inline-message-fontSize));
|
|
42
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module OpenProject
|
|
5
|
+
# A simple component to render warning text.
|
|
6
|
+
#
|
|
7
|
+
# The warning text is rendered in the "attention" Primer color and
|
|
8
|
+
# uses a leading alert Octicon for additional emphasis. This component
|
|
9
|
+
# is designed to be used "inline", e.g. table cells, and in places
|
|
10
|
+
# where a Banner component might be overkill.
|
|
11
|
+
class InlineMessage < Primer::Component
|
|
12
|
+
status :open_project
|
|
13
|
+
|
|
14
|
+
SCHEME_ICON_MAPPINGS = {
|
|
15
|
+
warning: :alert,
|
|
16
|
+
critical: :alert,
|
|
17
|
+
success: :"check-circle",
|
|
18
|
+
unavailable: :alert
|
|
19
|
+
}.freeze
|
|
20
|
+
private_constant :SCHEME_ICON_MAPPINGS
|
|
21
|
+
SCHEME_OPTIONS = SCHEME_ICON_MAPPINGS.keys.freeze
|
|
22
|
+
|
|
23
|
+
SCHEME_SMALL_ICON_MAPPINGS = {
|
|
24
|
+
warning: :"alert-fill",
|
|
25
|
+
critical: :"alert-fill",
|
|
26
|
+
success: :"check-circle-fill",
|
|
27
|
+
unavailable: :"alert-fill"
|
|
28
|
+
}.freeze
|
|
29
|
+
private_constant :SCHEME_SMALL_ICON_MAPPINGS
|
|
30
|
+
DEFAULT_SIZE = :medium
|
|
31
|
+
SIZE_OPTIONS = [:small, DEFAULT_SIZE].freeze
|
|
32
|
+
|
|
33
|
+
# @param scheme [Symbol] <%= one_of(Primer::OpenProject::InlineMessage::SCHEME_OPTIONS) %>
|
|
34
|
+
# @param size [Symbol] <%= one_of(Primer::OpenProject::InlineMessage::SIZE_OPTIONS) %>
|
|
35
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
|
36
|
+
def initialize(scheme:, size: DEFAULT_SIZE, **system_arguments) # rubocop:disable Lint/MissingSuper
|
|
37
|
+
resolved_scheme = fetch_or_fallback(SCHEME_OPTIONS, scheme)
|
|
38
|
+
resolved_size = fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)
|
|
39
|
+
|
|
40
|
+
@system_arguments = system_arguments
|
|
41
|
+
@system_arguments[:tag] ||= :div
|
|
42
|
+
@system_arguments[:classes] = class_names(
|
|
43
|
+
@system_arguments[:classes],
|
|
44
|
+
"InlineMessage"
|
|
45
|
+
)
|
|
46
|
+
@system_arguments[:data] = merge_data(
|
|
47
|
+
@system_arguments,
|
|
48
|
+
{ data: { size: resolved_size, variant: resolved_scheme } }
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
@icon_arguments = { classes: "InlineMessageIcon" }
|
|
52
|
+
if resolved_size == :small
|
|
53
|
+
@icon_arguments[:icon] = SCHEME_SMALL_ICON_MAPPINGS[resolved_scheme]
|
|
54
|
+
@icon_arguments[:size] = :xsmall
|
|
55
|
+
else
|
|
56
|
+
@icon_arguments[:icon] = SCHEME_ICON_MAPPINGS[resolved_scheme]
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def render?
|
|
61
|
+
content.present?
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -25,6 +25,8 @@ module Primer
|
|
|
25
25
|
DEFAULT_PARENT_LINK_DISPLAY = [:block, :none].freeze
|
|
26
26
|
BREADCRUMB_TRUNCATE_AT = 200
|
|
27
27
|
|
|
28
|
+
DEFAULT_BUTTON_ACTION_SIZE = :medium
|
|
29
|
+
|
|
28
30
|
STATE_DEFAULT = :show
|
|
29
31
|
STATE_EDIT = :edit
|
|
30
32
|
STATE_OPTIONS = [STATE_DEFAULT, STATE_EDIT].freeze
|
|
@@ -68,6 +70,7 @@ module Primer
|
|
|
68
70
|
system_arguments[:icon] = icon
|
|
69
71
|
system_arguments[:"aria-label"] ||= label
|
|
70
72
|
system_arguments = set_action_arguments(system_arguments, scheme: scheme)
|
|
73
|
+
system_arguments = enforce_consistent_button_size!(system_arguments)
|
|
71
74
|
|
|
72
75
|
component = Primer::Beta::IconButton
|
|
73
76
|
create_mobile_alternatives(component, mobile_icon, label, scheme, **system_arguments, &block)
|
|
@@ -78,6 +81,7 @@ module Primer
|
|
|
78
81
|
deny_tag_argument(**system_arguments)
|
|
79
82
|
|
|
80
83
|
system_arguments = set_action_arguments(system_arguments, scheme: scheme)
|
|
84
|
+
system_arguments = enforce_consistent_button_size!(system_arguments)
|
|
81
85
|
|
|
82
86
|
component = Primer::Beta::Button
|
|
83
87
|
create_mobile_alternatives(component, mobile_icon, mobile_label, scheme, **system_arguments, &block)
|
|
@@ -88,6 +92,7 @@ module Primer
|
|
|
88
92
|
deny_tag_argument(**system_arguments)
|
|
89
93
|
|
|
90
94
|
system_arguments = set_action_arguments(system_arguments, scheme: DEFAULT_ACTION_SCHEME)
|
|
95
|
+
system_arguments = enforce_consistent_button_size!(system_arguments)
|
|
91
96
|
|
|
92
97
|
component = Primer::OpenProject::ZenModeButton
|
|
93
98
|
create_mobile_alternatives(component, mobile_icon, mobile_label, DEFAULT_ACTION_SCHEME, **system_arguments, &block)
|
|
@@ -120,6 +125,7 @@ module Primer
|
|
|
120
125
|
|
|
121
126
|
system_arguments[:button_arguments] ||= {}
|
|
122
127
|
system_arguments[:button_arguments] = set_action_arguments(system_arguments[:button_arguments])
|
|
128
|
+
system_arguments[:button_arguments] = enforce_consistent_button_size!(system_arguments[:button_arguments])
|
|
123
129
|
|
|
124
130
|
# Add the options individually to the mobile menu in the template
|
|
125
131
|
@desktop_menu_block = block
|
|
@@ -138,6 +144,7 @@ module Primer
|
|
|
138
144
|
system_arguments[:button_arguments] ||= {}
|
|
139
145
|
system_arguments[:button_arguments][:id] = "dialog-show-#{system_arguments[:dialog_arguments][:id]}"
|
|
140
146
|
system_arguments[:button_arguments] = set_action_arguments(system_arguments[:button_arguments])
|
|
147
|
+
system_arguments[:button_arguments] = enforce_consistent_button_size!(system_arguments[:button_arguments])
|
|
141
148
|
|
|
142
149
|
component = Primer::OpenProject::PageHeader::Dialog
|
|
143
150
|
create_mobile_alternatives(component, mobile_icon, mobile_label, :default, **system_arguments, &block)
|
|
@@ -293,7 +300,6 @@ module Primer
|
|
|
293
300
|
def set_action_arguments(system_arguments, scheme: nil)
|
|
294
301
|
system_arguments[:ml] ||= 2
|
|
295
302
|
system_arguments[:display] = %i[none flex]
|
|
296
|
-
system_arguments[:size] = :medium
|
|
297
303
|
system_arguments[:scheme] = scheme unless scheme.nil?
|
|
298
304
|
system_arguments[:classes] = class_names(
|
|
299
305
|
system_arguments[:classes],
|
|
@@ -304,6 +310,17 @@ module Primer
|
|
|
304
310
|
system_arguments
|
|
305
311
|
end
|
|
306
312
|
|
|
313
|
+
def enforce_consistent_button_size!(system_arguments)
|
|
314
|
+
size = system_arguments.fetch(:size, DEFAULT_BUTTON_ACTION_SIZE)
|
|
315
|
+
@page_header_button_action_size ||= size
|
|
316
|
+
unless size == @page_header_button_action_size
|
|
317
|
+
raise ArgumentError,
|
|
318
|
+
"PageHeader button actions must all use the same size. " \
|
|
319
|
+
"Set the same `size:` for every button-like action (or omit it to use #{DEFAULT_BUTTON_ACTION_SIZE.inspect} everywhere)."
|
|
320
|
+
end
|
|
321
|
+
system_arguments.merge(size: @page_header_button_action_size)
|
|
322
|
+
end
|
|
323
|
+
|
|
307
324
|
def create_mobile_alternatives(component, mobile_icon, mobile_label, scheme, **system_arguments, &block)
|
|
308
325
|
# All actions should collapse into a single actionMenu on mobile
|
|
309
326
|
add_option_to_mobile_menu(system_arguments, mobile_icon, mobile_label, scheme)
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
@import "./open_project/drag_handle.pcss";
|
|
51
51
|
@import "./open_project/border_grid.pcss";
|
|
52
52
|
@import "./open_project/input_group.pcss";
|
|
53
|
+
@import "./open_project/inline_message.pcss";
|
|
53
54
|
@import "./open_project/sub_header.pcss";
|
|
54
55
|
@import "./open_project/side_panel/section.pcss";
|
|
55
56
|
@import "./open_project/border_box/collapsible_header.pcss";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module Forms
|
|
5
|
+
module Dsl
|
|
6
|
+
# :nodoc:
|
|
7
|
+
class FieldsetGroupInput < Input
|
|
8
|
+
include Primer::Forms::Dsl::InputMethods
|
|
9
|
+
include InputMethods
|
|
10
|
+
|
|
11
|
+
attr_reader :builder, :form, :system_arguments
|
|
12
|
+
|
|
13
|
+
def initialize(builder:, form:, **system_arguments)
|
|
14
|
+
@builder = builder
|
|
15
|
+
@form = form
|
|
16
|
+
@system_arguments = system_arguments
|
|
17
|
+
|
|
18
|
+
yield(self) if block_given?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_component
|
|
22
|
+
FieldsetGroup.new(inputs: inputs, builder: builder, form: form, **@system_arguments)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def type
|
|
26
|
+
:group
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def input?
|
|
30
|
+
true
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -19,6 +19,10 @@ module Primer
|
|
|
19
19
|
def group(**options, &block)
|
|
20
20
|
add_input InputGroup.new(builder: @builder, form: @form, **options, &block)
|
|
21
21
|
end
|
|
22
|
+
|
|
23
|
+
def fieldset_group(**options, &block)
|
|
24
|
+
add_input FieldsetGroupInput.new(builder: @builder, form: @form, **options, &block)
|
|
25
|
+
end
|
|
22
26
|
end
|
|
23
27
|
end
|
|
24
28
|
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
|
|
2
|
+
<%= render(Primer::OpenProject::Fieldset.new(**@fieldset_arguments)) do %>
|
|
3
|
+
<%=
|
|
4
|
+
render(Primer::Beta::Subhead.new) do |component|
|
|
5
|
+
component.with_heading(**@heading_arguments).with_content(@title)
|
|
6
|
+
end
|
|
7
|
+
%>
|
|
8
|
+
<%= render(Primer::Forms::Group.new(**@group_arguments)) %>
|
|
9
|
+
<% end %>
|
|
10
|
+
<% end %>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module Forms
|
|
5
|
+
# :nodoc:
|
|
6
|
+
class FieldsetGroup < BaseComponent
|
|
7
|
+
##
|
|
8
|
+
# @param title [String] The title displayed as the heading for the fieldset
|
|
9
|
+
# @param inputs [Array<Primer::Forms::Dsl::Input>] Array of form inputs to be grouped
|
|
10
|
+
# @param builder [ActionView::Helpers::FormBuilder] The form builder instance
|
|
11
|
+
# @param form [Primer::Forms::BaseForm] The form object
|
|
12
|
+
# @param layout [Symbol] Layout style for the input group (default: :default_layout)
|
|
13
|
+
# @param heading_arguments [Hash] Arguments passed to the heading component
|
|
14
|
+
# @option heading_arguments [String] :id The ID for the heading element
|
|
15
|
+
# @option heading_arguments [Symbol] :tag The HTML tag for the heading (default: :h3)
|
|
16
|
+
# @option heading_arguments [Symbol] :size The size of the heading (default: :medium)
|
|
17
|
+
# @param group_arguments [Hash] Arguments passed to the input group component
|
|
18
|
+
# @param system_arguments [Hash] Additional system arguments passed to the section wrapper
|
|
19
|
+
def initialize( # rubocop:disable Metrics/AbcSize
|
|
20
|
+
title:,
|
|
21
|
+
inputs:,
|
|
22
|
+
builder:,
|
|
23
|
+
form:,
|
|
24
|
+
layout: Primer::Forms::Group::DEFAULT_LAYOUT,
|
|
25
|
+
heading_arguments: {},
|
|
26
|
+
group_arguments: {},
|
|
27
|
+
**system_arguments
|
|
28
|
+
)
|
|
29
|
+
super()
|
|
30
|
+
|
|
31
|
+
@title = title
|
|
32
|
+
|
|
33
|
+
@heading_arguments = heading_arguments
|
|
34
|
+
@heading_arguments[:id] ||= "subhead-#{SecureRandom.uuid}"
|
|
35
|
+
@heading_arguments[:tag] ||= :h3
|
|
36
|
+
@heading_arguments[:size] ||= :medium
|
|
37
|
+
|
|
38
|
+
@fieldset_arguments = {
|
|
39
|
+
legend_text: @title,
|
|
40
|
+
visually_hide_legend: true,
|
|
41
|
+
aria: { labelledby: @heading_arguments[:id] }
|
|
42
|
+
}
|
|
43
|
+
@group_arguments = group_arguments.merge(inputs:, builder:, form:, layout:)
|
|
44
|
+
|
|
45
|
+
@system_arguments = system_arguments
|
|
46
|
+
@system_arguments[:tag] = :section
|
|
47
|
+
@system_arguments[:mb] ||= 4
|
|
48
|
+
@system_arguments[:aria] ||= {}
|
|
49
|
+
@system_arguments[:aria][:labelledby] = @heading_arguments[:id]
|
|
50
|
+
@system_arguments[:hidden] = :none if inputs.all?(&:hidden?)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<%
|
|
2
|
+
fieldset_group_form = Class.new(ApplicationForm) do
|
|
3
|
+
form do |f|
|
|
4
|
+
f.fieldset_group(
|
|
5
|
+
title: "Delivery preferences",
|
|
6
|
+
caption: "These settings affect how we contact you"
|
|
7
|
+
) do |g|
|
|
8
|
+
g.text_field(
|
|
9
|
+
name: :ultimate_answer,
|
|
10
|
+
label: "Ultimate answer",
|
|
11
|
+
required: true,
|
|
12
|
+
caption: "The answer to life, the universe, and everything"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
g.select_list(
|
|
16
|
+
name: :window,
|
|
17
|
+
label: "Delivery window",
|
|
18
|
+
include_blank: true
|
|
19
|
+
) do |list|
|
|
20
|
+
list.option(label: "Morning", value: "morning")
|
|
21
|
+
list.option(label: "Afternoon", value: "afternoon")
|
|
22
|
+
list.option(label: "Evening", value: "evening")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
g.text_field(
|
|
26
|
+
name: :hours,
|
|
27
|
+
label: "Hours",
|
|
28
|
+
type: :number,
|
|
29
|
+
required: true,
|
|
30
|
+
trailing_visual: { text: { text: "min" } },
|
|
31
|
+
input_width: :xsmall
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
%>
|
|
37
|
+
|
|
38
|
+
<%= primer_form_with(url: "/foo") do |f| %>
|
|
39
|
+
<%= render(fieldset_group_form.new(f)) %>
|
|
40
|
+
<% end %>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module OpenProject
|
|
5
|
+
class InlineMessagePreview < ViewComponent::Preview
|
|
6
|
+
# @label Default
|
|
7
|
+
# @snapshot
|
|
8
|
+
def default
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @label Playground
|
|
12
|
+
# @param scheme [Symbol] select [warning, critical, unavailable, success]
|
|
13
|
+
# @param size [Symbol] select [small, medium]
|
|
14
|
+
def playground(
|
|
15
|
+
scheme: :warning,
|
|
16
|
+
size: :medium
|
|
17
|
+
)
|
|
18
|
+
render_with_template(locals: { scheme: scheme, size: size })
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/static/arguments.json
CHANGED
|
@@ -6058,6 +6058,43 @@
|
|
|
6058
6058
|
}
|
|
6059
6059
|
]
|
|
6060
6060
|
},
|
|
6061
|
+
{
|
|
6062
|
+
"component": "OpenProject::Fieldset",
|
|
6063
|
+
"status": "open_project",
|
|
6064
|
+
"a11y_reviewed": false,
|
|
6065
|
+
"short_name": "OpenProjectFieldset",
|
|
6066
|
+
"source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/fieldset.rb",
|
|
6067
|
+
"lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/fieldset/default/",
|
|
6068
|
+
"parameters": [
|
|
6069
|
+
{
|
|
6070
|
+
"name": "legend_text",
|
|
6071
|
+
"type": "String",
|
|
6072
|
+
"default": "`nil`",
|
|
6073
|
+
"description": "A legend should be short and concise. The String will also be read by assistive technology."
|
|
6074
|
+
},
|
|
6075
|
+
{
|
|
6076
|
+
"name": "visually_hide_legend",
|
|
6077
|
+
"type": "Boolean",
|
|
6078
|
+
"default": "`false`",
|
|
6079
|
+
"description": "Controls if the legend is visible. If `true`, screen reader only text will be added."
|
|
6080
|
+
},
|
|
6081
|
+
{
|
|
6082
|
+
"name": "system_arguments",
|
|
6083
|
+
"type": "Hash",
|
|
6084
|
+
"default": "N/A",
|
|
6085
|
+
"description": "[System arguments](/system-arguments)"
|
|
6086
|
+
}
|
|
6087
|
+
]
|
|
6088
|
+
},
|
|
6089
|
+
{
|
|
6090
|
+
"component": "OpenProject::Fieldset::Legend",
|
|
6091
|
+
"status": "open_project",
|
|
6092
|
+
"a11y_reviewed": false,
|
|
6093
|
+
"short_name": "OpenProjectFieldsetLegend",
|
|
6094
|
+
"source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/fieldset/legend_component.rb",
|
|
6095
|
+
"lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/fieldset/legend/default/",
|
|
6096
|
+
"parameters": []
|
|
6097
|
+
},
|
|
6061
6098
|
{
|
|
6062
6099
|
"component": "OpenProject::FilterableTreeView",
|
|
6063
6100
|
"status": "alpha",
|
|
@@ -6220,6 +6257,34 @@
|
|
|
6220
6257
|
}
|
|
6221
6258
|
]
|
|
6222
6259
|
},
|
|
6260
|
+
{
|
|
6261
|
+
"component": "OpenProject::InlineMessage",
|
|
6262
|
+
"status": "open_project",
|
|
6263
|
+
"a11y_reviewed": false,
|
|
6264
|
+
"short_name": "OpenProjectInlineMessage",
|
|
6265
|
+
"source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/inline_message.rb",
|
|
6266
|
+
"lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/inline_message/default/",
|
|
6267
|
+
"parameters": [
|
|
6268
|
+
{
|
|
6269
|
+
"name": "scheme",
|
|
6270
|
+
"type": "Symbol",
|
|
6271
|
+
"default": "N/A",
|
|
6272
|
+
"description": "One of `:critical`, `:success`, `:unavailable`, or `:warning`."
|
|
6273
|
+
},
|
|
6274
|
+
{
|
|
6275
|
+
"name": "size",
|
|
6276
|
+
"type": "Symbol",
|
|
6277
|
+
"default": "`:medium`",
|
|
6278
|
+
"description": "One of `:medium` or `:small`."
|
|
6279
|
+
},
|
|
6280
|
+
{
|
|
6281
|
+
"name": "system_arguments",
|
|
6282
|
+
"type": "Hash",
|
|
6283
|
+
"default": "N/A",
|
|
6284
|
+
"description": "[System arguments](/system-arguments)"
|
|
6285
|
+
}
|
|
6286
|
+
]
|
|
6287
|
+
},
|
|
6223
6288
|
{
|
|
6224
6289
|
"component": "OpenProject::InputGroup",
|
|
6225
6290
|
"status": "open_project",
|
data/static/audited_at.json
CHANGED
|
@@ -151,12 +151,15 @@
|
|
|
151
151
|
"Primer::OpenProject::DragHandle": "",
|
|
152
152
|
"Primer::OpenProject::FeedbackDialog": "",
|
|
153
153
|
"Primer::OpenProject::FeedbackMessage": "",
|
|
154
|
+
"Primer::OpenProject::Fieldset": "",
|
|
155
|
+
"Primer::OpenProject::Fieldset::LegendComponent": "",
|
|
154
156
|
"Primer::OpenProject::FilterableTreeView": "",
|
|
155
157
|
"Primer::OpenProject::FilterableTreeView::SubTree": "",
|
|
156
158
|
"Primer::OpenProject::FlexLayout": "",
|
|
157
159
|
"Primer::OpenProject::GridLayout": "",
|
|
158
160
|
"Primer::OpenProject::GridLayout::Area": "",
|
|
159
161
|
"Primer::OpenProject::Heading": "",
|
|
162
|
+
"Primer::OpenProject::InlineMessage": "",
|
|
160
163
|
"Primer::OpenProject::InputGroup": "",
|
|
161
164
|
"Primer::OpenProject::PageHeader": "",
|
|
162
165
|
"Primer::OpenProject::PageHeader::Dialog": "",
|
data/static/classes.json
CHANGED
|
@@ -352,6 +352,12 @@
|
|
|
352
352
|
"FormControl-warning": [
|
|
353
353
|
"Primer::Alpha::TextField"
|
|
354
354
|
],
|
|
355
|
+
"InlineMessage": [
|
|
356
|
+
"Primer::OpenProject::InlineMessage"
|
|
357
|
+
],
|
|
358
|
+
"InlineMessageIcon": [
|
|
359
|
+
"Primer::OpenProject::InlineMessage"
|
|
360
|
+
],
|
|
355
361
|
"InputGroup": [
|
|
356
362
|
"Primer::OpenProject::InputGroup"
|
|
357
363
|
],
|
data/static/constants.json
CHANGED
|
@@ -1751,6 +1751,13 @@
|
|
|
1751
1751
|
"Primer::OpenProject::FeedbackMessage": {
|
|
1752
1752
|
"GeneratedSlotMethods": "Primer::OpenProject::FeedbackMessage::GeneratedSlotMethods"
|
|
1753
1753
|
},
|
|
1754
|
+
"Primer::OpenProject::Fieldset": {
|
|
1755
|
+
"GeneratedSlotMethods": "Primer::OpenProject::Fieldset::GeneratedSlotMethods",
|
|
1756
|
+
"LegendComponent": "Primer::OpenProject::Fieldset::LegendComponent"
|
|
1757
|
+
},
|
|
1758
|
+
"Primer::OpenProject::Fieldset::LegendComponent": {
|
|
1759
|
+
"GeneratedSlotMethods": "Primer::OpenProject::Fieldset::LegendComponent::GeneratedSlotMethods"
|
|
1760
|
+
},
|
|
1754
1761
|
"Primer::OpenProject::FilterableTreeView": {
|
|
1755
1762
|
"DEFAULT_FILTER_INPUT_ARGUMENTS": {
|
|
1756
1763
|
"name": "filter",
|
|
@@ -1810,6 +1817,20 @@
|
|
|
1810
1817
|
"Primer::OpenProject::Heading": {
|
|
1811
1818
|
"GeneratedSlotMethods": "Primer::OpenProject::Heading::GeneratedSlotMethods"
|
|
1812
1819
|
},
|
|
1820
|
+
"Primer::OpenProject::InlineMessage": {
|
|
1821
|
+
"DEFAULT_SIZE": "medium",
|
|
1822
|
+
"GeneratedSlotMethods": "Primer::OpenProject::InlineMessage::GeneratedSlotMethods",
|
|
1823
|
+
"SCHEME_OPTIONS": [
|
|
1824
|
+
"warning",
|
|
1825
|
+
"critical",
|
|
1826
|
+
"success",
|
|
1827
|
+
"unavailable"
|
|
1828
|
+
],
|
|
1829
|
+
"SIZE_OPTIONS": [
|
|
1830
|
+
"small",
|
|
1831
|
+
"medium"
|
|
1832
|
+
]
|
|
1833
|
+
},
|
|
1813
1834
|
"Primer::OpenProject::InputGroup": {
|
|
1814
1835
|
"DEFAULT_INPUT_WIDTH": "auto",
|
|
1815
1836
|
"GeneratedSlotMethods": "Primer::OpenProject::InputGroup::GeneratedSlotMethods",
|
|
@@ -1845,6 +1866,7 @@
|
|
|
1845
1866
|
"none",
|
|
1846
1867
|
"flex"
|
|
1847
1868
|
],
|
|
1869
|
+
"DEFAULT_BUTTON_ACTION_SIZE": "medium",
|
|
1848
1870
|
"DEFAULT_HEADER_VARIANT": "medium",
|
|
1849
1871
|
"DEFAULT_LEADING_ACTION_DISPLAY": [
|
|
1850
1872
|
"none",
|