openproject-primer_view_components 0.92.0 → 0.94.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -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/open_project/collapsible_section.html.erb +7 -7
  8. data/app/components/primer/open_project/collapsible_section.rb +17 -2
  9. data/app/components/primer/open_project/color_field.css +1 -0
  10. data/app/components/primer/open_project/color_field.css.json +18 -0
  11. data/app/components/primer/open_project/color_field.css.map +1 -0
  12. data/app/components/primer/open_project/color_field.pcss +70 -0
  13. data/app/components/primer/open_project/color_field.rb +40 -0
  14. data/app/components/primer/primer.d.ts +1 -0
  15. data/app/components/primer/primer.js +1 -0
  16. data/app/components/primer/primer.pcss +1 -0
  17. data/app/components/primer/primer.ts +1 -0
  18. data/app/lib/primer/forms/color_field.html.erb +10 -0
  19. data/app/lib/primer/forms/color_field.rb +67 -0
  20. data/app/lib/primer/forms/dsl/color_field_input.rb +97 -0
  21. data/app/lib/primer/forms/dsl/input_methods.rb +9 -0
  22. data/app/lib/primer/forms/primer_color_input.d.ts +17 -0
  23. data/app/lib/primer/forms/primer_color_input.js +138 -0
  24. data/app/lib/primer/forms/primer_color_input.ts +121 -0
  25. data/config/locales/en.yml +4 -0
  26. data/lib/primer/view_components/version.rb +1 -1
  27. data/lib/primer/yard/component_manifest.rb +2 -1
  28. data/lib/primer/yard/lookbook_pages_backend.rb +2 -1
  29. data/previews/primer/open_project/collapsible_section_preview/non_collapsible.html.erb +10 -0
  30. data/previews/primer/open_project/collapsible_section_preview/playground.html.erb +1 -1
  31. data/previews/primer/open_project/collapsible_section_preview.rb +13 -2
  32. data/previews/primer/open_project/color_field_preview/in_form.html.erb +6 -0
  33. data/previews/primer/open_project/color_field_preview/in_multi.html.erb +8 -0
  34. data/previews/primer/open_project/color_field_preview/multiple.html.erb +4 -0
  35. data/previews/primer/open_project/color_field_preview.rb +108 -0
  36. data/static/arguments.json +156 -2
  37. data/static/audited_at.json +1 -0
  38. data/static/classes.json +3 -0
  39. data/static/classnames.cjs +4 -0
  40. data/static/classnames.js +4 -0
  41. data/static/constants.json +8 -0
  42. data/static/info_arch.json +310 -2
  43. data/static/previews.json +151 -0
  44. data/static/statuses.json +1 -0
  45. metadata +17 -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
+ }
@@ -9,6 +9,10 @@ en:
9
9
  button_filter: "Filter"
10
10
  button_save: "Save"
11
11
 
12
+ color_field:
13
+ picker_label: "Pick color for %{label}"
14
+ picker_label_generic: "Pick color"
15
+
12
16
  drag_handle:
13
17
  button_drag: "Drag to reorder"
14
18
 
@@ -5,7 +5,7 @@ module Primer
5
5
  module ViewComponents
6
6
  module VERSION
7
7
  MAJOR = 0
8
- MINOR = 92
8
+ MINOR = 94
9
9
  PATCH = 0
10
10
 
11
11
  STRING = [MAJOR, MINOR, PATCH].join(".")
@@ -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,10 @@
1
+ <%= render(Primer::OpenProject::CollapsibleSection.new(collapsed: :locked)) do |section| %>
2
+ <% section.with_title { "Feedback" } %>
3
+ <% section.with_collapsible_content do %>
4
+ <%= render(Primer::Alpha::Banner.new(mb: 3)) { "Please take one minute time to answer this question" } %>
5
+ <%= primer_form_with(url: "/foo") do |f| %>
6
+ <%= render(RadioButtonGroupForm.new(f)) %>
7
+ <% end %>
8
+
9
+ <% end %>
10
+ <% end %>
@@ -1,4 +1,4 @@
1
- <%= render(Primer::OpenProject::CollapsibleSection.new) do |section| %>
1
+ <%= render(Primer::OpenProject::CollapsibleSection.new(collapsed: collapsed)) do |section| %>
2
2
  <% section.with_title { "Advanced settings" } %>
3
3
 
4
4
  <% if caption.present? %>
@@ -10,10 +10,12 @@ module Primer
10
10
  # @label Playground
11
11
  # @param caption [String] text
12
12
  # @param show_additional_information [Boolean] toggle
13
- def playground(caption: "(optional)", show_additional_information: false)
13
+ # @param collapsed [String] select ["false", "true", "locked"]
14
+ def playground(caption: "(optional)", show_additional_information: false, collapsed: "false")
15
+ collapsed = { "false" => false, "true" => true, "locked" => :locked }.fetch(collapsed)
14
16
  render_with_template(
15
17
  template: "primer/open_project/collapsible_section_preview/playground",
16
- locals: { caption: caption, show_additional_information: show_additional_information}
18
+ locals: { caption: caption, show_additional_information: show_additional_information, collapsed: collapsed }
17
19
  )
18
20
  end
19
21
 
@@ -53,6 +55,15 @@ module Primer
53
55
  )
54
56
  end
55
57
 
58
+ # @label Non-collapsible
59
+ # @snapshot
60
+ def non_collapsible
61
+ render_with_template(
62
+ template: "primer/open_project/collapsible_section_preview/non_collapsible",
63
+ locals: { }
64
+ )
65
+ end
66
+
56
67
  # @label With link in title
57
68
  # @hidden
58
69
  def with_link_in_title
@@ -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
@@ -5961,9 +5961,9 @@
5961
5961
  },
5962
5962
  {
5963
5963
  "name": "collapsed",
5964
- "type": "Boolean",
5964
+ "type": "Boolean, Symbol",
5965
5965
  "default": "`false`",
5966
- "description": "Whether the section is collapsed on initial render."
5966
+ "description": "The initial state of the section. `false` renders it open and toggleable, `true` renders it collapsed and toggleable, and `:locked` keeps it permanently open with the toggle disabled."
5967
5967
  },
5968
5968
  {
5969
5969
  "name": "system_arguments",
@@ -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",
@@ -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
@@ -265,6 +265,9 @@
265
265
  "CollapsibleSection--triggerArea": [
266
266
  "Primer::OpenProject::CollapsibleSection"
267
267
  ],
268
+ "ColorField": [
269
+ "Primer::OpenProject::ColorField"
270
+ ],
268
271
  "Counter": [
269
272
  "Primer::Beta::Counter"
270
273
  ],
@@ -122,6 +122,10 @@ module.exports = new Set([
122
122
  'CollapsibleHeader-title-line',
123
123
  'CollapsibleHeader-triggerArea',
124
124
  'CollapsibleSection--triggerArea',
125
+ 'ColorField',
126
+ 'ColorField-picker',
127
+ 'ColorField-swatch',
128
+ 'ColorField-wrap',
125
129
  'Counter',
126
130
  'Counter--primary',
127
131
  'Counter--secondary',
data/static/classnames.js CHANGED
@@ -122,6 +122,10 @@ const classNames = new Set([
122
122
  'CollapsibleHeader-title-line',
123
123
  'CollapsibleHeader-triggerArea',
124
124
  'CollapsibleSection--triggerArea',
125
+ 'ColorField',
126
+ 'ColorField-picker',
127
+ 'ColorField-swatch',
128
+ 'ColorField-wrap',
125
129
  'Counter',
126
130
  'Counter--primary',
127
131
  'Counter--secondary',
@@ -1747,6 +1747,11 @@
1747
1747
  "GeneratedSlotMethods": "Primer::OpenProject::BorderGrid::Cell::GeneratedSlotMethods"
1748
1748
  },
1749
1749
  "Primer::OpenProject::CollapsibleSection": {
1750
+ "COLLAPSED_OPTIONS": [
1751
+ false,
1752
+ true,
1753
+ "locked"
1754
+ ],
1750
1755
  "GeneratedSlotMethods": "Primer::OpenProject::CollapsibleSection::GeneratedSlotMethods",
1751
1756
  "TITLE_TAG_FALLBACK": "h2",
1752
1757
  "TITLE_TAG_OPTIONS": [
@@ -1759,6 +1764,9 @@
1759
1764
  "span"
1760
1765
  ]
1761
1766
  },
1767
+ "Primer::OpenProject::ColorField": {
1768
+ "GeneratedSlotMethods": "Primer::OpenProject::ColorField::GeneratedSlotMethods"
1769
+ },
1762
1770
  "Primer::OpenProject::DangerDialog": {
1763
1771
  "ConfirmationCheckBox": "Primer::OpenProject::DangerDialog::ConfirmationCheckBox",
1764
1772
  "FormWrapper": "Primer::OpenProject::DangerDialog::FormWrapper",