openproject-primer_view_components 0.91.4 → 0.93.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 +16 -0
- data/README.md +0 -19
- 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/open_project/color_field.css +1 -0
- data/app/components/primer/open_project/color_field.css.json +18 -0
- data/app/components/primer/open_project/color_field.css.map +1 -0
- data/app/components/primer/open_project/color_field.pcss +70 -0
- data/app/components/primer/open_project/color_field.rb +40 -0
- data/app/components/primer/open_project/sub_header.rb +37 -29
- data/app/components/primer/primer.d.ts +1 -0
- data/app/components/primer/primer.js +1 -0
- data/app/components/primer/primer.pcss +1 -0
- data/app/components/primer/primer.ts +1 -0
- data/app/lib/primer/forms/color_field.html.erb +10 -0
- data/app/lib/primer/forms/color_field.rb +67 -0
- data/app/lib/primer/forms/dsl/color_field_input.rb +97 -0
- data/app/lib/primer/forms/dsl/input_methods.rb +9 -0
- data/app/lib/primer/forms/primer_color_input.d.ts +17 -0
- data/app/lib/primer/forms/primer_color_input.js +138 -0
- data/app/lib/primer/forms/primer_color_input.ts +121 -0
- data/config/locales/en.yml +4 -0
- data/lib/primer/view_components/version.rb +2 -2
- data/lib/primer/yard/component_manifest.rb +2 -1
- data/lib/primer/yard/lookbook_pages_backend.rb +2 -1
- data/previews/primer/open_project/color_field_preview/in_form.html.erb +6 -0
- data/previews/primer/open_project/color_field_preview/in_multi.html.erb +8 -0
- data/previews/primer/open_project/color_field_preview/multiple.html.erb +4 -0
- data/previews/primer/open_project/color_field_preview.rb +108 -0
- data/previews/primer/open_project/sub_header_preview/playground.html.erb +1 -1
- data/previews/primer/open_project/sub_header_preview.rb +19 -20
- data/static/arguments.json +154 -6
- data/static/audited_at.json +1 -0
- data/static/classes.json +3 -0
- data/static/classnames.cjs +18 -0
- data/static/classnames.js +18 -0
- data/static/constants.json +3 -0
- data/static/info_arch.json +305 -16
- data/static/previews.json +148 -10
- data/static/statuses.json +1 -0
- metadata +16 -1
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import {attr, controller, target} from '@github/catalyst'
|
|
2
|
+
|
|
3
|
+
const HEX_PATTERN = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i
|
|
4
|
+
|
|
5
|
+
// Returns the canonical uppercase `#RRGGBB` form of the given text, or null
|
|
6
|
+
// if it is not a three- or six-digit hex color.
|
|
7
|
+
export function parseHex(text: string): string | null {
|
|
8
|
+
const match = HEX_PATTERN.exec(text.trim())
|
|
9
|
+
if (!match) return null
|
|
10
|
+
|
|
11
|
+
let digits = match[1]
|
|
12
|
+
if (digits.length === 3) digits = digits.replace(/./g, '$&$&')
|
|
13
|
+
|
|
14
|
+
return `#${digits.toUpperCase()}`
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@controller('primer-color-input')
|
|
18
|
+
export class PrimerColorInputElement extends HTMLElement {
|
|
19
|
+
@target inputElement: HTMLInputElement
|
|
20
|
+
@target pickerElement: HTMLInputElement
|
|
21
|
+
|
|
22
|
+
// The text input is empty.
|
|
23
|
+
@attr blank = false
|
|
24
|
+
// There is no color to show in the swatch.
|
|
25
|
+
@attr empty = false
|
|
26
|
+
|
|
27
|
+
#abortController: AbortController | null = null
|
|
28
|
+
#observer: MutationObserver | null = null
|
|
29
|
+
|
|
30
|
+
connectedCallback(): void {
|
|
31
|
+
this.#abortController?.abort()
|
|
32
|
+
const {signal} = (this.#abortController = new AbortController())
|
|
33
|
+
|
|
34
|
+
this.syncDisabled()
|
|
35
|
+
this.sync()
|
|
36
|
+
|
|
37
|
+
// The server always renders the picker disabled. Whatever rewrites
|
|
38
|
+
// attributes without reconnecting this element, a Turbo morph for one,
|
|
39
|
+
// puts that back, so the rule is re-applied on every such change.
|
|
40
|
+
this.#observer?.disconnect()
|
|
41
|
+
this.#observer = new MutationObserver(() => this.syncDisabled())
|
|
42
|
+
this.#observer.observe(this, {attributes: true, attributeFilter: ['disabled', 'readonly'], subtree: true})
|
|
43
|
+
|
|
44
|
+
// The form is outside this element's subtree, so data-action cannot
|
|
45
|
+
// reach it. Reset restores the text value after the event, hence the tick.
|
|
46
|
+
this.inputElement.form?.addEventListener('reset', () => setTimeout(() => this.sync()), {signal})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
disconnectedCallback(): void {
|
|
50
|
+
this.#abortController?.abort()
|
|
51
|
+
this.#observer?.disconnect()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// The picker is operable only while its value can reach the submitted text
|
|
55
|
+
// input and that input accepts edits.
|
|
56
|
+
private syncDisabled(): void {
|
|
57
|
+
const disabled = this.inputElement.disabled || this.inputElement.readOnly
|
|
58
|
+
|
|
59
|
+
// Assigning the same value again would still rewrite the attribute and
|
|
60
|
+
// wake the observer, which would then never settle.
|
|
61
|
+
if (this.pickerElement.disabled !== disabled) this.pickerElement.disabled = disabled
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Text → picker. Bound to `input` on the text input, so the swatch follows
|
|
65
|
+
// every keystroke: text that is not a whole color yet shows none. The
|
|
66
|
+
// picker itself has no empty value and keeps the last color to open on.
|
|
67
|
+
syncPicker(): void {
|
|
68
|
+
const text = this.inputElement.value.trim()
|
|
69
|
+
const color = parseHex(text)
|
|
70
|
+
|
|
71
|
+
this.blank = text === ''
|
|
72
|
+
this.empty = color === null
|
|
73
|
+
|
|
74
|
+
if (color) this.pickerElement.value = color.toLowerCase()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Bound to `change` on the text input.
|
|
78
|
+
normalize(): void {
|
|
79
|
+
const color = parseHex(this.inputElement.value)
|
|
80
|
+
if (color) this.inputElement.value = color
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Bound to `paste` on the text input. The browser cuts a paste to the
|
|
84
|
+
// input's `maxlength` first, so padding around a copied color would push
|
|
85
|
+
// its last digits out. The padding is dropped and the rest inserted as an
|
|
86
|
+
// edit of the user's own, which keeps undo, `maxlength` and read-only
|
|
87
|
+
// intact and still ends in a `change` event.
|
|
88
|
+
trimPaste(event: ClipboardEvent): void {
|
|
89
|
+
const text = event.clipboardData?.getData('text/plain') ?? ''
|
|
90
|
+
const trimmed = text.trim()
|
|
91
|
+
if (trimmed === text) return
|
|
92
|
+
|
|
93
|
+
event.preventDefault()
|
|
94
|
+
document.execCommand('insertText', false, trimmed)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Picker → text. Bound to `input` on the picker. The picker's own event
|
|
98
|
+
// stops here: the one forwarded from the text input stands in for it, and
|
|
99
|
+
// listeners further up would otherwise hear of each pick twice.
|
|
100
|
+
syncInput(event: Event): void {
|
|
101
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
|
102
|
+
event.stopPropagation()
|
|
103
|
+
|
|
104
|
+
this.inputElement.value = this.pickerElement.value.toUpperCase()
|
|
105
|
+
this.inputElement.dispatchEvent(new Event('input', {bubbles: true}))
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Bound to `change` on the picker, whose own event stops here as well.
|
|
109
|
+
commit(event: Event): void {
|
|
110
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
|
111
|
+
event.stopPropagation()
|
|
112
|
+
|
|
113
|
+
this.inputElement.dispatchEvent(new Event('change', {bubbles: true}))
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Resynchronises from the text input's current value. Call this after
|
|
117
|
+
// setting the value from script, which fires no event.
|
|
118
|
+
sync(): void {
|
|
119
|
+
this.syncPicker()
|
|
120
|
+
}
|
|
121
|
+
}
|
data/config/locales/en.yml
CHANGED
|
@@ -96,7 +96,8 @@ module Primer
|
|
|
96
96
|
Primer::Alpha::CheckBox => { form_component: true },
|
|
97
97
|
Primer::Alpha::CheckBoxGroup => { form_component: true },
|
|
98
98
|
Primer::Alpha::SubmitButton => { form_component: true },
|
|
99
|
-
Primer::Alpha::FormButton => { form_component: true }
|
|
99
|
+
Primer::Alpha::FormButton => { form_component: true },
|
|
100
|
+
Primer::OpenProject::ColorField => { form_component: true, js: true }
|
|
100
101
|
}.freeze
|
|
101
102
|
|
|
102
103
|
include Enumerable
|
|
@@ -17,7 +17,8 @@ module Primer
|
|
|
17
17
|
Primer::Alpha::CheckBox => [:check_box_with_nested_form],
|
|
18
18
|
Primer::Alpha::CheckBoxGroup => [:check_box_group_form],
|
|
19
19
|
Primer::Alpha::SubmitButton => [:submit_button_form],
|
|
20
|
-
Primer::Alpha::FormButton => [:submit_button_form]
|
|
20
|
+
Primer::Alpha::FormButton => [:submit_button_form],
|
|
21
|
+
Primer::OpenProject::ColorField => []
|
|
21
22
|
}.freeze
|
|
22
23
|
|
|
23
24
|
attr_reader :component_ref, :backend, :docs
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<%= primer_form_with(url: "/foo", method: :get) do |f| %>
|
|
2
|
+
<%= render_inline_form(f) do |form|
|
|
3
|
+
form.color_field(name: :hexcode, label: "Primary color", value: value, input_width: :small)
|
|
4
|
+
end %>
|
|
5
|
+
<%= render(Primer::Beta::Button.new(type: :reset, mt: 2)) { "Reset" } %>
|
|
6
|
+
<% end %>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<%= primer_form_with(url: "/foo", method: :get) do |f| %>
|
|
2
|
+
<%= render_inline_form(f) do |form|
|
|
3
|
+
form.multi(name: :color, label: "Brand color") do |multi|
|
|
4
|
+
multi.color_field(name: :hex, value: "#1A67A3", input_width: :small)
|
|
5
|
+
multi.text_field(name: :token, hidden: true)
|
|
6
|
+
end
|
|
7
|
+
end %>
|
|
8
|
+
<% end %>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<%= render(Primer::Alpha::Stack.new) do %>
|
|
2
|
+
<%= render(Primer::OpenProject::ColorField.new(name: "primary", id: "primary", label: "Primary color", value: "#1A67A3", input_width: :small)) %>
|
|
3
|
+
<%= render(Primer::OpenProject::ColorField.new(name: "accent", id: "accent", label: "Accent color", value: "#35C53F", input_width: :small)) %>
|
|
4
|
+
<% end %>
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module OpenProject
|
|
5
|
+
# @label ColorField
|
|
6
|
+
class ColorFieldPreview < ViewComponent::Preview
|
|
7
|
+
# @label Playground
|
|
8
|
+
#
|
|
9
|
+
# @param label text
|
|
10
|
+
# @param value text
|
|
11
|
+
# @param placeholder text
|
|
12
|
+
# @param caption text
|
|
13
|
+
# @param size [Symbol] select [small, medium, large]
|
|
14
|
+
# @param input_width [Symbol] select [auto, xsmall, small, medium, large, xlarge, xxlarge]
|
|
15
|
+
# @param full_width toggle
|
|
16
|
+
# @param visually_hide_label toggle
|
|
17
|
+
# @param required toggle
|
|
18
|
+
# @param disabled toggle
|
|
19
|
+
# @param readonly toggle
|
|
20
|
+
# @param validation_message text
|
|
21
|
+
def playground(
|
|
22
|
+
label: "Primary color",
|
|
23
|
+
value: "#1A67A3",
|
|
24
|
+
placeholder: "#1A67A3",
|
|
25
|
+
caption: nil,
|
|
26
|
+
size: :medium,
|
|
27
|
+
input_width: :small,
|
|
28
|
+
full_width: true,
|
|
29
|
+
visually_hide_label: false,
|
|
30
|
+
required: false,
|
|
31
|
+
disabled: false,
|
|
32
|
+
readonly: false,
|
|
33
|
+
validation_message: nil
|
|
34
|
+
)
|
|
35
|
+
render(
|
|
36
|
+
Primer::OpenProject::ColorField.new(
|
|
37
|
+
name: "color",
|
|
38
|
+
id: "color",
|
|
39
|
+
label: label,
|
|
40
|
+
value: value,
|
|
41
|
+
placeholder: placeholder,
|
|
42
|
+
caption: caption.presence,
|
|
43
|
+
size: size.to_sym,
|
|
44
|
+
input_width: input_width.to_sym,
|
|
45
|
+
full_width: full_width,
|
|
46
|
+
visually_hide_label: visually_hide_label,
|
|
47
|
+
required: required,
|
|
48
|
+
disabled: disabled,
|
|
49
|
+
readonly: readonly,
|
|
50
|
+
validation_message: validation_message.presence
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @label Default
|
|
56
|
+
# @snapshot
|
|
57
|
+
def default
|
|
58
|
+
render(Primer::OpenProject::ColorField.new(name: "color", id: "color", label: "Primary color", input_width: :small, value: "#1A67A3"))
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @!group States
|
|
62
|
+
#
|
|
63
|
+
# @label Blank with placeholder
|
|
64
|
+
# @snapshot
|
|
65
|
+
def blank_with_placeholder
|
|
66
|
+
render(Primer::OpenProject::ColorField.new(name: "color", id: "color", label: "Primary color", input_width: :small, placeholder: "#1A67A3"))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @label Blank without placeholder
|
|
70
|
+
# @snapshot
|
|
71
|
+
def blank_without_placeholder
|
|
72
|
+
render(Primer::OpenProject::ColorField.new(name: "color", id: "color", label: "Primary color", input_width: :small))
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @label Disabled
|
|
76
|
+
# @snapshot
|
|
77
|
+
def disabled
|
|
78
|
+
render(Primer::OpenProject::ColorField.new(name: "color", id: "color", label: "Primary color", input_width: :small, value: "#1A67A3", disabled: true))
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @label Read-only
|
|
82
|
+
# @snapshot
|
|
83
|
+
def readonly
|
|
84
|
+
render(Primer::OpenProject::ColorField.new(name: "color", id: "color", label: "Primary color", input_width: :small, value: "#1A67A3", readonly: true))
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# @label Invalid
|
|
88
|
+
# @snapshot
|
|
89
|
+
def invalid
|
|
90
|
+
render(Primer::OpenProject::ColorField.new(name: "color", id: "color", label: "Primary color", input_width: :small, value: "zzz", validation_message: "Hex code is invalid"))
|
|
91
|
+
end
|
|
92
|
+
#
|
|
93
|
+
# @!endgroup
|
|
94
|
+
|
|
95
|
+
# @label In a form
|
|
96
|
+
# @param value text
|
|
97
|
+
def in_form(value: "#1A67A3")
|
|
98
|
+
render_with_template(locals: { value: value })
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# @label Multiple fields
|
|
102
|
+
def multiple; end
|
|
103
|
+
|
|
104
|
+
# @label In a multi input
|
|
105
|
+
def in_multi; end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -13,7 +13,6 @@ module Primer
|
|
|
13
13
|
# @param show_quick_filter toggle
|
|
14
14
|
# @param show_action_button toggle
|
|
15
15
|
# @param show_clear_button toggle
|
|
16
|
-
# @param collapsed_search toggle
|
|
17
16
|
# @param text text
|
|
18
17
|
# @param value text
|
|
19
18
|
def playground(
|
|
@@ -22,22 +21,21 @@ module Primer
|
|
|
22
21
|
show_filter_button: true,
|
|
23
22
|
show_quick_filter: true,
|
|
24
23
|
show_action_button: true,
|
|
25
|
-
collapsed_search: true,
|
|
26
24
|
text: nil,
|
|
27
25
|
value: nil
|
|
28
26
|
)
|
|
29
27
|
bool = ActiveModel::Type::Boolean.new
|
|
30
|
-
render_with_template(locals: {show_filter_input: bool.cast(show_filter_input),
|
|
28
|
+
render_with_template(locals: { show_filter_input: bool.cast(show_filter_input),
|
|
31
29
|
show_clear_button: bool.cast(show_clear_button),
|
|
32
30
|
show_filter_button: bool.cast(show_filter_button),
|
|
33
31
|
show_quick_filter: bool.cast(show_quick_filter),
|
|
34
32
|
show_action_button: bool.cast(show_action_button),
|
|
35
|
-
collapsed_search: bool.cast(collapsed_search),
|
|
36
33
|
text: text,
|
|
37
|
-
value: value})
|
|
34
|
+
value: value })
|
|
38
35
|
end
|
|
39
36
|
|
|
40
37
|
# @label Default
|
|
38
|
+
# @snapshot
|
|
41
39
|
def default
|
|
42
40
|
render(Primer::OpenProject::SubHeader.new) do |component|
|
|
43
41
|
component.with_filter_input(name: "filter", label: "Filter")
|
|
@@ -93,21 +91,6 @@ module Primer
|
|
|
93
91
|
end
|
|
94
92
|
end
|
|
95
93
|
|
|
96
|
-
# @label With expanded search
|
|
97
|
-
def expanded_search
|
|
98
|
-
render(Primer::OpenProject::SubHeader.new(collapsed_search: false)) do |component|
|
|
99
|
-
component.with_filter_input(name: "filter", label: "Filter")
|
|
100
|
-
component.with_filter_button(scheme: :default) do |button|
|
|
101
|
-
button.with_trailing_visual_counter(count: "15")
|
|
102
|
-
"Filter"
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
component.with_action_button(leading_icon: :plus, label: "Create", scheme: :primary) do
|
|
106
|
-
"Create"
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
94
|
# @label With QuickFilters
|
|
112
95
|
def quick_filters
|
|
113
96
|
render_with_template(locals: {})
|
|
@@ -130,6 +113,22 @@ module Primer
|
|
|
130
113
|
end
|
|
131
114
|
end
|
|
132
115
|
end
|
|
116
|
+
|
|
117
|
+
# @label With filter value (expanded)
|
|
118
|
+
# @snapshot
|
|
119
|
+
def expanded_search
|
|
120
|
+
render(Primer::OpenProject::SubHeader.new) do |component|
|
|
121
|
+
component.with_filter_input(name: "filter", label: "Filter", value: "Some search term")
|
|
122
|
+
component.with_filter_button(scheme: :default) do |button|
|
|
123
|
+
button.with_trailing_visual_counter(count: "15")
|
|
124
|
+
"Filter"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
component.with_action_button(leading_icon: :plus, label: "Create", scheme: :primary) do
|
|
128
|
+
"Create"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
133
132
|
end
|
|
134
133
|
end
|
|
135
134
|
end
|
data/static/arguments.json
CHANGED
|
@@ -5973,6 +5973,160 @@
|
|
|
5973
5973
|
}
|
|
5974
5974
|
]
|
|
5975
5975
|
},
|
|
5976
|
+
{
|
|
5977
|
+
"component": "OpenProject::ColorField",
|
|
5978
|
+
"status": "open_project",
|
|
5979
|
+
"a11y_reviewed": false,
|
|
5980
|
+
"short_name": "OpenProjectColorField",
|
|
5981
|
+
"source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/color_field.rb",
|
|
5982
|
+
"lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/color_field/default/",
|
|
5983
|
+
"parameters": [
|
|
5984
|
+
{
|
|
5985
|
+
"name": "size",
|
|
5986
|
+
"type": "Symbol",
|
|
5987
|
+
"default": "N/A",
|
|
5988
|
+
"description": "The size of the field. One of `:large`, `:medium`, or `:small`."
|
|
5989
|
+
},
|
|
5990
|
+
{
|
|
5991
|
+
"name": "full_width",
|
|
5992
|
+
"type": "Boolean",
|
|
5993
|
+
"default": "N/A",
|
|
5994
|
+
"description": "When set to `true`, the field will take up all the horizontal space allowed by its container. Defaults to `true`."
|
|
5995
|
+
},
|
|
5996
|
+
{
|
|
5997
|
+
"name": "name",
|
|
5998
|
+
"type": "String",
|
|
5999
|
+
"default": "N/A",
|
|
6000
|
+
"description": "Value for the HTML name attribute."
|
|
6001
|
+
},
|
|
6002
|
+
{
|
|
6003
|
+
"name": "id",
|
|
6004
|
+
"type": "String",
|
|
6005
|
+
"default": "N/A",
|
|
6006
|
+
"description": "Value for the HTML id attribute."
|
|
6007
|
+
},
|
|
6008
|
+
{
|
|
6009
|
+
"name": "class",
|
|
6010
|
+
"type": "String",
|
|
6011
|
+
"default": "N/A",
|
|
6012
|
+
"description": "CSS classes to include in the input's HTML `class` attribute. Exists for compatibility with Rails form builders."
|
|
6013
|
+
},
|
|
6014
|
+
{
|
|
6015
|
+
"name": "classes",
|
|
6016
|
+
"type": "Array",
|
|
6017
|
+
"default": "N/A",
|
|
6018
|
+
"description": "CSS classes to include in the input's HTML `class` attribute. Combined with the `:class` argument. The list may contain strings, hashes, or `nil` values, and is automatically cleaned up by Primer's [`class_name` helper](https://github.com/primer/view_components/blob/c9cb95c98fee3e2e27f4a10683f555e22285e7f1/app/lib/primer/class_name_helper.rb) (`nils`, falsy entries, and blank strings are ignored)."
|
|
6019
|
+
},
|
|
6020
|
+
{
|
|
6021
|
+
"name": "caption",
|
|
6022
|
+
"type": "String",
|
|
6023
|
+
"default": "N/A",
|
|
6024
|
+
"description": "A string describing the field and what sorts of input it expects. Displayed below the input."
|
|
6025
|
+
},
|
|
6026
|
+
{
|
|
6027
|
+
"name": "label",
|
|
6028
|
+
"type": "String",
|
|
6029
|
+
"default": "N/A",
|
|
6030
|
+
"description": "Label text displayed above the input."
|
|
6031
|
+
},
|
|
6032
|
+
{
|
|
6033
|
+
"name": "visually_hide_label",
|
|
6034
|
+
"type": "Boolean",
|
|
6035
|
+
"default": "N/A",
|
|
6036
|
+
"description": "When set to `true`, hides the label. Although the label will be hidden visually, it will still be visible to screen readers."
|
|
6037
|
+
},
|
|
6038
|
+
{
|
|
6039
|
+
"name": "disabled",
|
|
6040
|
+
"type": "Boolean",
|
|
6041
|
+
"default": "N/A",
|
|
6042
|
+
"description": "When set to `true`, the input will not accept keyboard or mouse input."
|
|
6043
|
+
},
|
|
6044
|
+
{
|
|
6045
|
+
"name": "hidden",
|
|
6046
|
+
"type": "Boolean",
|
|
6047
|
+
"default": "N/A",
|
|
6048
|
+
"description": "When set to `true`, visually hides the field."
|
|
6049
|
+
},
|
|
6050
|
+
{
|
|
6051
|
+
"name": "invalid",
|
|
6052
|
+
"type": "Boolean",
|
|
6053
|
+
"default": "N/A",
|
|
6054
|
+
"description": "If set to `true`, the input will be rendered with a red border. Implied if `validation_message` is truthy. This option is set to `true` automatically if the model object associated with the form reports that the input is invalid via Rails validations. It is provided for cases where the form does not have an associated model. If the input is invalid as determined by Rails validations, setting `invalid` to `false` will have no effect."
|
|
6055
|
+
},
|
|
6056
|
+
{
|
|
6057
|
+
"name": "validation_message",
|
|
6058
|
+
"type": "String",
|
|
6059
|
+
"default": "N/A",
|
|
6060
|
+
"description": "A string displayed between the caption and the input indicating the input's contents are invalid. This option is, by default, set to the first Rails validation message for the input (assuming the form is associated with a model object). Use `validation_message` to override the default or to provide a validation message in case there is no associated model object."
|
|
6061
|
+
},
|
|
6062
|
+
{
|
|
6063
|
+
"name": "label_arguments",
|
|
6064
|
+
"type": "Hash",
|
|
6065
|
+
"default": "N/A",
|
|
6066
|
+
"description": "Attributes that will be passed to Rails' `builder.label` method. These can be HTML attributes or any of the other label options Rails supports. They will appear as HTML attributes on the `<label>` tag."
|
|
6067
|
+
},
|
|
6068
|
+
{
|
|
6069
|
+
"name": "scope_name_to_model",
|
|
6070
|
+
"type": "Boolean",
|
|
6071
|
+
"default": "N/A",
|
|
6072
|
+
"description": "Default `true`. When set to `false`, prevents the model name from prefixing the field name. For example, if the field name is `my_field`, Rails will normally emit an HTML name attribute of `model[my_field]`. Setting `scope_name_to_model` to `false` will cause Rails to emit `my_field` instead."
|
|
6073
|
+
},
|
|
6074
|
+
{
|
|
6075
|
+
"name": "scope_id_to_model",
|
|
6076
|
+
"type": "Boolean",
|
|
6077
|
+
"default": "N/A",
|
|
6078
|
+
"description": "Default `true`. When set to `false`, prevents the model name from prefixing the field ID. For example, if the field name is `my_field`, Rails will normally emit an HTML ID attribute of `model_my_field`. Setting `scope_id_to_model` to `false` will cause Rails to emit `my_field` instead."
|
|
6079
|
+
},
|
|
6080
|
+
{
|
|
6081
|
+
"name": "required",
|
|
6082
|
+
"type": "Boolean",
|
|
6083
|
+
"default": "N/A",
|
|
6084
|
+
"description": "Default `false`. When set to `true`, causes an asterisk (*) to appear next to the field's label indicating it is a required field. Note that this option explicitly does _not_ add a `required` HTML attribute. Doing so would enable native browser validations, which are inaccessible and inconsistent with the Primer design system."
|
|
6085
|
+
},
|
|
6086
|
+
{
|
|
6087
|
+
"name": "aria",
|
|
6088
|
+
"type": "Hash",
|
|
6089
|
+
"default": "N/A",
|
|
6090
|
+
"description": "Key/value pairs that represent Aria attributes and their values. Eg. `aria: { current: true }` becomes `aria-current=\"true\"`."
|
|
6091
|
+
},
|
|
6092
|
+
{
|
|
6093
|
+
"name": "data",
|
|
6094
|
+
"type": "Hash",
|
|
6095
|
+
"default": "N/A",
|
|
6096
|
+
"description": "Key/value pairs that represent data attributes and their values. Eg. `data: { foo: \"bar\" }` becomes `data-foo=\"bar\"`."
|
|
6097
|
+
},
|
|
6098
|
+
{
|
|
6099
|
+
"name": "system_arguments",
|
|
6100
|
+
"type": "Hash",
|
|
6101
|
+
"default": "N/A",
|
|
6102
|
+
"description": "A hash of attributes passed to the underlying Rails builder methods. These options may mean something special depending on the type of input, otherwise they are emitted as HTML attributes. See the [Rails documentation](https://guides.rubyonrails.org/form_helpers.html) for more information. In addition, the usual Primer utility arguments are accepted in system arguments. For example, passing `mt: 2` will add the `mt-2` class to the input. See the Primer system arguments docs for details."
|
|
6103
|
+
},
|
|
6104
|
+
{
|
|
6105
|
+
"name": "input_width",
|
|
6106
|
+
"type": "Symbol",
|
|
6107
|
+
"default": "N/A",
|
|
6108
|
+
"description": "The width of the field. One of `:auto`, `:large`, `:medium`, `:small`, `:xlarge`, `:xsmall`, or `:xxlarge`."
|
|
6109
|
+
},
|
|
6110
|
+
{
|
|
6111
|
+
"name": "maxlength",
|
|
6112
|
+
"type": "Integer",
|
|
6113
|
+
"default": "N/A",
|
|
6114
|
+
"description": "Maximum number of characters the text input accepts. Defaults to 7, the length of `#RRGGBB`."
|
|
6115
|
+
},
|
|
6116
|
+
{
|
|
6117
|
+
"name": "placeholder",
|
|
6118
|
+
"type": "String",
|
|
6119
|
+
"default": "N/A",
|
|
6120
|
+
"description": "Placeholder text. It is not previewed in the swatch, which stays empty while the field is blank."
|
|
6121
|
+
},
|
|
6122
|
+
{
|
|
6123
|
+
"name": "picker_label",
|
|
6124
|
+
"type": "String",
|
|
6125
|
+
"default": "N/A",
|
|
6126
|
+
"description": "Accessible name of the native color picker. Defaults to `I18n.t(\"color_field.picker_label\", label: label)`, or to `I18n.t(\"color_field.picker_label_generic\")` when there is no label."
|
|
6127
|
+
}
|
|
6128
|
+
]
|
|
6129
|
+
},
|
|
5976
6130
|
{
|
|
5977
6131
|
"component": "OpenProject::DangerDialog",
|
|
5978
6132
|
"status": "open_project",
|
|
@@ -6513,12 +6667,6 @@
|
|
|
6513
6667
|
"source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/sub_header.rb",
|
|
6514
6668
|
"lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/sub_header/default/",
|
|
6515
6669
|
"parameters": [
|
|
6516
|
-
{
|
|
6517
|
-
"name": "collapsed_search",
|
|
6518
|
-
"type": "Boolean",
|
|
6519
|
-
"default": "`true`",
|
|
6520
|
-
"description": "When true, the search bar starts collapsed as an icon button on all screen sizes. Clicking expands it."
|
|
6521
|
-
},
|
|
6522
6670
|
{
|
|
6523
6671
|
"name": "system_arguments",
|
|
6524
6672
|
"type": "Hash",
|
data/static/audited_at.json
CHANGED
|
@@ -146,6 +146,7 @@
|
|
|
146
146
|
"Primer::OpenProject::BorderGrid": "",
|
|
147
147
|
"Primer::OpenProject::BorderGrid::Cell": "",
|
|
148
148
|
"Primer::OpenProject::CollapsibleSection": "",
|
|
149
|
+
"Primer::OpenProject::ColorField": "",
|
|
149
150
|
"Primer::OpenProject::DangerDialog": "",
|
|
150
151
|
"Primer::OpenProject::DangerDialog::ConfirmationCheckBox": "",
|
|
151
152
|
"Primer::OpenProject::DangerDialog::FormWrapper": "",
|
data/static/classes.json
CHANGED
data/static/classnames.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module.exports = new Set([
|
|
2
|
+
':popover-open',
|
|
2
3
|
'ActionBar',
|
|
3
4
|
'ActionBar--large',
|
|
4
5
|
'ActionBar--small',
|
|
@@ -15,9 +16,13 @@ module.exports = new Set([
|
|
|
15
16
|
'ActionListContent--hasActiveSubItem',
|
|
16
17
|
'ActionListContent--sizeLarge',
|
|
17
18
|
'ActionListContent--sizeXLarge',
|
|
19
|
+
'ActionListContent--visual16',
|
|
20
|
+
'ActionListContent--visual20',
|
|
21
|
+
'ActionListContent--visual24',
|
|
18
22
|
'ActionListHeader',
|
|
19
23
|
'ActionListItem',
|
|
20
24
|
'ActionListItem--danger',
|
|
25
|
+
'ActionListItem--disabled',
|
|
21
26
|
'ActionListItem--hasSubItem',
|
|
22
27
|
'ActionListItem--navActive',
|
|
23
28
|
'ActionListItem--subItem',
|
|
@@ -72,6 +77,7 @@ module.exports = new Set([
|
|
|
72
77
|
'Box-footer',
|
|
73
78
|
'Box-header',
|
|
74
79
|
'Box-header--blue',
|
|
80
|
+
'Box-list',
|
|
75
81
|
'Box-list--roundedBottom',
|
|
76
82
|
'Box-list--roundedTop',
|
|
77
83
|
'Box-row',
|
|
@@ -97,6 +103,7 @@ module.exports = new Set([
|
|
|
97
103
|
'Button--labelWrap',
|
|
98
104
|
'Button--large',
|
|
99
105
|
'Button--link',
|
|
106
|
+
'Button--medium',
|
|
100
107
|
'Button--primary',
|
|
101
108
|
'Button--secondary',
|
|
102
109
|
'Button--small',
|
|
@@ -109,11 +116,16 @@ module.exports = new Set([
|
|
|
109
116
|
'Button-visual',
|
|
110
117
|
'ButtonGroup',
|
|
111
118
|
'CollapsibleHeader',
|
|
119
|
+
'CollapsibleHeader--collapsed',
|
|
112
120
|
'CollapsibleHeader--multi-line',
|
|
113
121
|
'CollapsibleHeader-description',
|
|
114
122
|
'CollapsibleHeader-title-line',
|
|
115
123
|
'CollapsibleHeader-triggerArea',
|
|
116
124
|
'CollapsibleSection--triggerArea',
|
|
125
|
+
'ColorField',
|
|
126
|
+
'ColorField-picker',
|
|
127
|
+
'ColorField-swatch',
|
|
128
|
+
'ColorField-wrap',
|
|
117
129
|
'Counter',
|
|
118
130
|
'Counter--primary',
|
|
119
131
|
'Counter--secondary',
|
|
@@ -139,6 +151,7 @@ module.exports = new Set([
|
|
|
139
151
|
'FormControl-input-trailingAction',
|
|
140
152
|
'FormControl-input-trailingAction--divider',
|
|
141
153
|
'FormControl-input-trailingVisualLabel',
|
|
154
|
+
'FormControl-input-trailingVisualText',
|
|
142
155
|
'FormControl-input-trailingVisualWrap',
|
|
143
156
|
'FormControl-input-width--auto',
|
|
144
157
|
'FormControl-input-width--large',
|
|
@@ -277,6 +290,7 @@ module.exports = new Set([
|
|
|
277
290
|
'Overlay-form',
|
|
278
291
|
'Overlay-header',
|
|
279
292
|
'Overlay-header--divided',
|
|
293
|
+
'Overlay-header--large',
|
|
280
294
|
'Overlay-headerContentWrap',
|
|
281
295
|
'Overlay-headerFilter',
|
|
282
296
|
'Overlay-title',
|
|
@@ -454,6 +468,9 @@ module.exports = new Set([
|
|
|
454
468
|
'btn-small-mktg',
|
|
455
469
|
'btn-subtle-mktg',
|
|
456
470
|
'close-button',
|
|
471
|
+
'container-lg',
|
|
472
|
+
'container-md',
|
|
473
|
+
'container-xl',
|
|
457
474
|
'css-truncate',
|
|
458
475
|
'css-truncate-overflow',
|
|
459
476
|
'css-truncate-target',
|
|
@@ -482,6 +499,7 @@ module.exports = new Set([
|
|
|
482
499
|
'flash-messages',
|
|
483
500
|
'flash-success',
|
|
484
501
|
'flash-warn',
|
|
502
|
+
'focus',
|
|
485
503
|
'form-control',
|
|
486
504
|
'has-modal',
|
|
487
505
|
'has-modal-disable-scroll',
|