anchor_view_components 0.44.0 → 0.45.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/app/assets/images/icons/percentage.svg +6 -0
  4. data/app/components/anchor/anchor_view_components.ts +2 -0
  5. data/app/components/anchor/assistive_tech_notifications_component.html.erb +23 -0
  6. data/app/components/anchor/assistive_tech_notifications_component.rb +4 -0
  7. data/app/components/anchor/assistive_tech_notifications_component.ts +15 -0
  8. data/app/components/anchor/autocomplete_component.html.erb +5 -5
  9. data/app/components/anchor/copy_to_clipboard_component.en.yml +1 -0
  10. data/app/components/anchor/copy_to_clipboard_component.html.erb +2 -2
  11. data/app/components/anchor/copy_to_clipboard_controller.ts +10 -8
  12. data/app/components/anchor/error_message_component.rb +5 -7
  13. data/app/components/anchor/input_component.rb +1 -5
  14. data/app/components/anchor/label_component.rb +3 -7
  15. data/app/components/anchor/radio_button_collection_component.rb +1 -34
  16. data/app/components/anchor/radio_button_component.html.erb +1 -1
  17. data/app/components/anchor/radio_button_component.rb +3 -7
  18. data/app/components/anchor/select_component.rb +1 -5
  19. data/app/components/anchor/toast_component.html.erb +5 -1
  20. data/app/components/anchor/toast_component.rb +4 -0
  21. data/app/components/anchor/toast_controller.ts +5 -0
  22. data/app/helpers/anchor/form_builder.rb +11 -25
  23. data/app/helpers/anchor/model_validators.rb +10 -5
  24. data/app/helpers/anchor/view_helper.rb +1 -0
  25. data/lib/anchor/view_components/version.rb +1 -1
  26. data/previews/anchor/assistive_tech_notifications_component_preview/default.html.erb +10 -0
  27. data/previews/anchor/assistive_tech_notifications_component_preview.rb +5 -0
  28. data/previews/forms/with_icons.html.erb +10 -19
  29. metadata +8 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b272707b7b7780690e4bd12712dfae937b8fd30e97cc4eaf9ab86b15a83a9122
4
- data.tar.gz: ef9c2b7c05ccbbc0e24ef552da216c0e502e6d57d83c1b5101c53b5e665912cc
3
+ metadata.gz: 02e14b9cbe3088a320100d337b3f23f92c97e03f659bd16d42ac21655838cc07
4
+ data.tar.gz: 4323338bfdedf4ed58101ee366bd21726bc1f3d910d7c824a3bc8eae5ff93d59
5
5
  SHA512:
6
- metadata.gz: 2f0273735e483b4b93949b639ac1c76191fda722709efd043908bee522f853a9ae500d57a127b32bdab5f65232a3769755a98fce1cce4e082038d998f149c324
7
- data.tar.gz: e27c29a51d263e4d55ec537515d18215ed280fc6f19df997cb9d4733c6ebc60c6495b80fd4679882b77e3cbea629249ed1f0284665453e8e01288179773308d7
6
+ metadata.gz: 2c89ce43a18e3072e0a24d30ac43a4f489cfeea27c318dff78d4f02769c8c2418f1d179b2a71158eb44bc680cf1bd4b2f7d7cde0fe93948b2e2a55c523b7b645
7
+ data.tar.gz: 35f880936914bd255eec0d3cc77f95352aef81b0dbe60feaada58877100e3c2b45468cd61fe6c0b471bf9836f0055aaff74fa16803cfccf7bfd917fab36542b3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.45.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 2cf21ed: Add more-horiz icon
8
+ - 2d2c3e6: Added a AssistiveTechNotifications component for notifying assistive tech users of changes that might otherwise only be presented visually. The output is two [ARIA live regions][aria-live-regions]—one `polite`, the other `assertive`—and is meant to be placed in an application’s layout so that it’s rendered on every page. Also provided, is the component’s public JavaScript function, `notifyAssistiveTech`, so that applications can easily send messages to these two live regions.
9
+
10
+ [aria-live-regions]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions
11
+
3
12
  ## 0.44.0
4
13
 
5
14
  ### Minor Changes
@@ -0,0 +1,6 @@
1
+ <!-- Source: Iconoir, added via `bin/add_icon` -->
2
+ <svg width="24" height="24" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <path d="M17 19C15.8954 19 15 18.1046 15 17C15 15.8954 15.8954 15 17 15C18.1046 15 19 15.8954 19 17C19 18.1046 18.1046 19 17 19Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
4
+ <path d="M7 9C5.89543 9 5 8.10457 5 7C5 5.89543 5.89543 5 7 5C8.10457 5 9 5.89543 9 7C9 8.10457 8.10457 9 7 9Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
5
+ <path d="M19 5L5 19" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
6
+ </svg>
@@ -10,6 +10,7 @@ import ToastController from "./toast_controller";
10
10
  import ToggleController from "./toggle_controller";
11
11
  import TypeaheadSelectController from "./typeahead_select_controller";
12
12
  import { Application } from "@hotwired/stimulus";
13
+ import { notifyAssistiveTech } from "./assistive_tech_notifications_component";
13
14
 
14
15
  export function registerAnchorControllers(application: Application) {
15
16
  application.register("autocomplete", AutocompleteController);
@@ -31,4 +32,5 @@ export {
31
32
  ToastController,
32
33
  ToggleController,
33
34
  TypeaheadSelectController,
35
+ notifyAssistiveTech,
34
36
  };
@@ -0,0 +1,23 @@
1
+ <%= tag.div(
2
+ **merge_options(
3
+ wrapper_options,
4
+ aria: {
5
+ atomic: true,
6
+ live: "polite",
7
+ },
8
+ class: "sr-only",
9
+ id: "js-assistive-tech-notifications",
10
+ ),
11
+ ) %>
12
+
13
+ <%= tag.div(
14
+ **merge_options(
15
+ wrapper_options,
16
+ aria: {
17
+ atomic: true,
18
+ live: "assertive",
19
+ },
20
+ class: "sr-only",
21
+ id: "js-assistive-tech-notifications-assertive",
22
+ ),
23
+ ) %>
@@ -0,0 +1,4 @@
1
+ module Anchor
2
+ class AssistiveTechNotificationsComponent < Component
3
+ end
4
+ end
@@ -0,0 +1,15 @@
1
+ export function notifyAssistiveTech(message: string, assertive = false) {
2
+ const liveRegionId = assertive
3
+ ? "js-assistive-tech-notifications-assertive"
4
+ : "js-assistive-tech-notifications";
5
+ const liveRegion = document.getElementById(liveRegionId);
6
+
7
+ if (liveRegion) {
8
+ liveRegion.textContent = message;
9
+ } else {
10
+ console.warn(
11
+ `Could not find #${liveRegionId}.`,
12
+ "Make sure to include `anchor_assistive_tech_notifications` in your Rails layout.",
13
+ );
14
+ }
15
+ }
@@ -1,25 +1,25 @@
1
- <%= tag.div(
1
+ <%= tag.div(**merge_options(wrapper_options,
2
2
  data: { controller: "autocomplete", autocomplete_url_value: src },
3
3
  role: "combobox",
4
4
  class: "group relative"
5
- ) do %>
5
+ )) do %>
6
6
  <% if form_builder.class.module_parent_name == "Anchor" %>
7
7
  <%= form_builder.text_field(
8
8
  name,
9
9
  **merge_options(input_options, default_input_options)
10
10
  ) %>
11
11
  <%= form_builder.text_field(
12
- "#{name}_id".to_sym,
12
+ :"#{name}_id",
13
13
  { class: "hidden", data: { autocomplete_target: "hidden" }}
14
14
  ) %>
15
15
  <% else %>
16
16
  <%= form_builder.input(
17
- "#{name}_search".to_sym,
17
+ :"#{name}_search",
18
18
  input_html: merge_options(input_options, default_input_options)
19
19
  ) %>
20
20
  <div class="hidden">
21
21
  <%= form_builder.input(
22
- "#{name}_id".to_sym,
22
+ :"#{name}_id",
23
23
  input_html: { data: { autocomplete_target: "hidden" } }
24
24
  ) %>
25
25
  </div>
@@ -1,2 +1,3 @@
1
1
  en:
2
+ assistive_tech_notification: Copied
2
3
  copy_to_clipboard: Copy to Clipboard
@@ -4,7 +4,7 @@
4
4
  action: "click->copy-to-clipboard#copy",
5
5
  controller: "copy-to-clipboard",
6
6
  copy_to_clipboard_text_to_copy_value: value,
7
- copy_to_clipboard_hidden_class: "hidden",
7
+ copy_to_clipboard_assistive_tech_notification_value: t(".assistive_tech_notification"),
8
8
  },
9
9
  class: "bg-transparent",
10
10
  type: "button",
@@ -15,7 +15,7 @@
15
15
  ) %>
16
16
  <%= anchor_icon(
17
17
  icon: "check",
18
- classes: "hidden",
18
+ hidden: true,
19
19
  data: { copy_to_clipboard_target: "successIcon"},
20
20
  ) %>
21
21
  <% end %>
@@ -1,26 +1,28 @@
1
1
  import { Controller } from "@hotwired/stimulus";
2
+ import { notifyAssistiveTech } from "./assistive_tech_notifications_component";
2
3
 
3
4
  export default class extends Controller<HTMLDivElement> {
4
5
  static targets = [ "initialIcon", "successIcon"];
5
- static classes = [ "hidden" ]
6
+ static values = {
7
+ assistiveTechNotification: String,
8
+ notificationDelay: { type: Number, default: 1500 },
9
+ textToCopy: String,
10
+ };
6
11
 
7
12
  declare readonly initialIconTarget: SVGElement;
8
13
  declare readonly successIconTarget: SVGElement;
9
14
  declare readonly notificationDelayValue: number;
10
15
  declare readonly hiddenClass: string;
11
16
  declare readonly textToCopyValue: string;
17
+ declare readonly assistiveTechNotificationValue: string;
12
18
  declare readonly hasTextToCopyValue: boolean;
13
19
 
14
- static values = {
15
- notificationDelay: { type: Number, default: 1500 },
16
- textToCopy: String,
17
- };
18
-
19
20
  copy(): void {
20
21
  if (this.hasTextToCopyValue) {
21
22
  navigator.clipboard.writeText(this.textToCopyValue);
22
23
  }
23
24
  this.toggleIcons();
25
+ notifyAssistiveTech(this.assistiveTechNotificationValue);
24
26
 
25
27
  setTimeout(() => {
26
28
  this.toggleIcons();
@@ -28,7 +30,7 @@ export default class extends Controller<HTMLDivElement> {
28
30
  }
29
31
 
30
32
  toggleIcons(): void {
31
- this.initialIconTarget.classList.toggle(this.hiddenClass);
32
- this.successIconTarget.classList.toggle(this.hiddenClass);
33
+ this.initialIconTarget.toggleAttribute("hidden");
34
+ this.successIconTarget.toggleAttribute("hidden");
33
35
  }
34
36
  }
@@ -13,8 +13,8 @@ module Anchor
13
13
  text-sm
14
14
  ).freeze
15
15
 
16
- def initialize(form_builder:, attribute:, **kwargs)
17
- @form_builder = form_builder
16
+ def initialize(object:, attribute:, **kwargs)
17
+ @object = object
18
18
  @attribute = attribute
19
19
 
20
20
  super(**kwargs)
@@ -22,16 +22,14 @@ module Anchor
22
22
 
23
23
  private
24
24
 
25
- attr_reader :attribute, :form_builder
26
-
27
- delegate :object, to: :form_builder
25
+ attr_reader :attribute
28
26
 
29
27
  def error_message
30
- object.errors.full_messages_for(attribute).to_sentence
28
+ @object.errors.full_messages_for(attribute).to_sentence
31
29
  end
32
30
 
33
31
  def render?
34
- object.errors.has_key?(attribute)
32
+ @object.errors.has_key?(attribute)
35
33
  end
36
34
  end
37
35
  end
@@ -20,23 +20,19 @@ module Anchor
20
20
  ).freeze
21
21
 
22
22
  def initialize(
23
- form_builder:,
24
23
  attribute:,
25
- type:,
26
24
  starting_icon: nil,
27
25
  ending_icon: nil,
28
26
  **kwargs
29
27
  )
30
- @form_builder = form_builder
31
28
  @attribute = attribute
32
- @type = type
33
29
  @starting_icon = starting_icon
34
30
  @ending_icon = ending_icon
35
31
 
36
32
  super(**kwargs)
37
33
  end
38
34
 
39
- attr_reader :attribute, :type, :starting_icon, :ending_icon
35
+ attr_reader :attribute, :starting_icon, :ending_icon
40
36
 
41
37
  def options
42
38
  {
@@ -8,14 +8,10 @@ module Anchor
8
8
 
9
9
  attr_accessor :options
10
10
 
11
- def initialize(form_builder:, attribute:, **options)
12
- @form_builder = form_builder
13
- @attribute = attribute
14
- @options = options.merge(
15
- class: Array(options.delete(:class)) + LABEL_CLASSES
16
- )
11
+ def initialize(object:, attribute:, required: nil)
12
+ @options = { class: LABEL_CLASSES }
17
13
  @required = ModelValidators
18
- .new(@form_builder.object, options)
14
+ .new(object, required:)
19
15
  .attribute_required?(attribute)
20
16
 
21
17
  super()
@@ -1,40 +1,7 @@
1
1
  module Anchor
2
2
  class RadioButtonCollectionComponent < Component
3
- attr_reader :attribute, :descriptions, :form_builder
4
-
5
- def initialize(
6
- form_builder:,
7
- attribute:,
8
- collection:,
9
- value_method:,
10
- text_method:,
11
- descriptions: nil,
12
- **options
13
- )
14
- @form_builder = form_builder
15
- @attribute = attribute
16
- @collection = collection
17
- @value_method = value_method
18
- @text_method = text_method
19
- @descriptions = descriptions
20
- @options = options
21
-
22
- super()
23
- end
24
-
25
3
  def options
26
- @options.merge(
27
- class: Array(@options.delete(:class)) +
28
- RadioButtonComponent::INPUT_CLASSES
29
- )
30
- end
31
-
32
- def radio(radio:)
33
- RadioButtonComponent.new(
34
- radio:,
35
- attribute:,
36
- form_builder:
37
- )
4
+ { class: RadioButtonComponent::INPUT_CLASSES }
38
5
  end
39
6
  end
40
7
  end
@@ -5,7 +5,7 @@
5
5
  <% if description.present? %>
6
6
  <div class="flex flex-col gap-1">
7
7
  <%= radio.label %>
8
- <%= description_span %>
8
+ <%= tag.span description, id: description_id, class: DESCRIPTION_CLASSES %>
9
9
  </div>
10
10
  <% else %>
11
11
  <%= tag.div radio.label, class: "self-center" %>
@@ -36,24 +36,20 @@ module Anchor
36
36
  text-sm
37
37
  ).freeze
38
38
 
39
- def initialize(radio:, attribute:, form_builder:, **kwargs)
39
+ def initialize(form_builder:, radio:, attribute:, **kwargs)
40
+ @form_builder = form_builder
40
41
  @radio = radio
41
42
  @attribute = attribute
42
- @form_builder = form_builder
43
43
 
44
44
  super(**kwargs)
45
45
  end
46
46
 
47
47
  private
48
48
 
49
- attr_reader :radio, :attribute, :form_builder
49
+ attr_reader :form_builder, :radio, :attribute
50
50
 
51
51
  delegate :value, :object, to: :radio
52
52
 
53
- def description_span
54
- tag.span description, id: description_id, class: DESCRIPTION_CLASSES
55
- end
56
-
57
53
  def radio_options
58
54
  {
59
55
  aria: description.present? && aria_description,
@@ -1,15 +1,11 @@
1
1
  module Anchor
2
2
  class SelectComponent < Component
3
- attr_reader :attribute
4
-
5
3
  def initialize(
6
- form_builder:,
7
4
  attribute:,
8
5
  choices:,
9
6
  show_marker: true,
10
7
  **kwargs
11
8
  )
12
- @form_builder = form_builder
13
9
  @attribute = attribute
14
10
  @choices = choices
15
11
  @show_marker = show_marker
@@ -24,7 +20,7 @@ module Anchor
24
20
  def html_options
25
21
  {
26
22
  class: InputComponent::INPUT_CLASSES,
27
- data: { testid: "select-#{attribute.to_s.dasherize}" },
23
+ data: { testid: "select-#{@attribute.to_s.dasherize}" },
28
24
  }
29
25
  end
30
26
 
@@ -1,7 +1,11 @@
1
1
  <%= tag.div(
2
2
  **merge_options(wrapper_options, {
3
3
  class: "toast",
4
- data: { controller: "toast", testid: test_id },
4
+ data: {
5
+ controller: "toast",
6
+ toast_assistive_tech_notification_value: assistive_tech_notification,
7
+ testid: test_id,
8
+ },
5
9
  popover: "manual",
6
10
  })
7
11
  ) do %>
@@ -25,6 +25,10 @@ module Anchor
25
25
  content?
26
26
  end
27
27
 
28
+ def assistive_tech_notification
29
+ strip_tags(content)
30
+ end
31
+
28
32
  def test_id
29
33
  wrapper_options.dig(:data, :testid) || "toast"
30
34
  end
@@ -1,11 +1,14 @@
1
1
  import { Controller } from "@hotwired/stimulus";
2
+ import { notifyAssistiveTech } from "./assistive_tech_notifications_component";
2
3
 
3
4
  export default class extends Controller<HTMLDivElement> {
4
5
  static values = {
6
+ assistiveTechNotification: String,
5
7
  hideDelay: { type: Number, default: 3000 },
6
8
  showDelay: { type: Number, default: 200 },
7
9
  };
8
10
 
11
+ declare assistiveTechNotificationValue: string;
9
12
  declare hideDelayValue: number
10
13
  declare showDelayValue: number
11
14
 
@@ -17,6 +20,8 @@ export default class extends Controller<HTMLDivElement> {
17
20
  setTimeout(() => {
18
21
  this.element.remove();
19
22
  }, this.hideDelayValue);
23
+
24
+ notifyAssistiveTech(this.assistiveTechNotificationValue);
20
25
  }
21
26
 
22
27
  disconnect(): void {
@@ -32,15 +32,7 @@ module Anchor
32
32
  options = {},
33
33
  html_options = {}
34
34
  )
35
- render RadioButtonCollectionComponent.new(
36
- form_builder: self,
37
- attribute:,
38
- collection:,
39
- value_method:,
40
- text_method:,
41
- **options,
42
- **html_options
43
- ) do |component|
35
+ render RadioButtonCollectionComponent.new do |component|
44
36
  super(
45
37
  attribute,
46
38
  collection,
@@ -49,7 +41,11 @@ module Anchor
49
41
  options,
50
42
  component.options.merge(html_options),
51
43
  ) do |radio|
52
- render component.radio(radio:)
44
+ render RadioButtonComponent.new(
45
+ radio:,
46
+ attribute:,
47
+ form_builder: self
48
+ )
53
49
  end
54
50
  end
55
51
  end
@@ -86,9 +82,7 @@ module Anchor
86
82
 
87
83
  def email_field(attribute, options = {})
88
84
  render InputComponent.new(
89
- form_builder: self,
90
85
  attribute:,
91
- type: :email,
92
86
  starting_icon: options.delete(:starting_icon),
93
87
  ending_icon: options.delete(:ending_icon)
94
88
  ) do |component|
@@ -98,7 +92,7 @@ module Anchor
98
92
 
99
93
  def error_message_for(attribute, options = {})
100
94
  render ErrorMessageComponent.new(
101
- form_builder: self,
95
+ object:,
102
96
  attribute:,
103
97
  **options
104
98
  )
@@ -106,10 +100,9 @@ module Anchor
106
100
 
107
101
  def label(attribute, text = nil, options = {}, &block)
108
102
  render LabelComponent.new(
109
- form_builder: self,
103
+ object:,
110
104
  attribute:,
111
- text:,
112
- **options
105
+ required: options.delete(:required) { :if_has_validators }
113
106
  ) do |component|
114
107
  if block.present?
115
108
  super
@@ -126,31 +119,26 @@ module Anchor
126
119
 
127
120
  def number_field(attribute, options = {})
128
121
  render InputComponent.new(
129
- form_builder: self,
130
122
  attribute:,
131
- type: :number,
132
123
  starting_icon: options.delete(:starting_icon),
133
124
  ending_icon: options.delete(:ending_icon)
134
125
  ) do |component|
135
- super attribute, component.options.merge(options)
126
+ super(attribute, component.options.merge(options))
136
127
  end
137
128
  end
138
129
 
139
130
  def search_field(attribute, options = {})
140
131
  render InputComponent.new(
141
- form_builder: self,
142
132
  attribute:,
143
- type: :search,
144
133
  starting_icon: options.delete(:starting_icon),
145
134
  ending_icon: options.delete(:ending_icon)
146
135
  ) do |component|
147
- super attribute, component.options.merge(options)
136
+ super(attribute, component.options.merge(options))
148
137
  end
149
138
  end
150
139
 
151
140
  def select(attribute, choices = nil, options = {}, html_options = {}, &)
152
141
  render SelectComponent.new(
153
- form_builder: self,
154
142
  attribute:,
155
143
  choices:,
156
144
  show_marker: options.fetch(:show_marker, true),
@@ -168,9 +156,7 @@ module Anchor
168
156
 
169
157
  def text_field(attribute, options = {})
170
158
  render InputComponent.new(
171
- form_builder: self,
172
159
  attribute:,
173
- type: :text,
174
160
  starting_icon: options.delete(:starting_icon),
175
161
  ending_icon: options.delete(:ending_icon)
176
162
  ) do |component|
@@ -1,13 +1,18 @@
1
1
  module Anchor
2
2
  class ModelValidators
3
- def initialize(model, options)
3
+ # Pass the value :if_has_validators to the required keyword argument to
4
+ # indicate an unspecified value. Passing any other value will result in
5
+ # `required`'s truthiness being used to determine whether the attribute is
6
+ # required, while passing :if_has_validators will check the model's
7
+ # validators.
8
+ def initialize(model, required: :if_has_validators)
4
9
  @model = model
5
- @options = options
10
+ @required = required
6
11
  end
7
12
 
8
13
  def attribute_required?(attribute)
9
- if options.has_key?(:required)
10
- options[:required]
14
+ if required != :if_has_validators
15
+ required
11
16
  elsif has_validators?
12
17
  attribute_required_by_validators?(attribute)
13
18
  else
@@ -17,7 +22,7 @@ module Anchor
17
22
 
18
23
  private
19
24
 
20
- attr_reader :model, :options
25
+ attr_reader :model, :required
21
26
 
22
27
  def has_validators?
23
28
  model.class.respond_to?(:validators_on)
@@ -2,6 +2,7 @@ module Anchor
2
2
  module ViewHelper
3
3
  ANCHOR_HELPERS = %i[
4
4
  action_menu
5
+ assistive_tech_notifications
5
6
  autocomplete/results
6
7
  badge
7
8
  banner
@@ -1,5 +1,5 @@
1
1
  module Anchor
2
2
  module ViewComponents
3
- VERSION = "0.44.0".freeze
3
+ VERSION = "0.45.0".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,10 @@
1
+ <%= anchor_text do %>
2
+ This component is visually hidden, by design. Inspect the page source and look
3
+ for the two
4
+ <%= anchor_link(
5
+ "ARIA live regions",
6
+ href: "https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions",
7
+ ) %>:
8
+ <code>div#js-assistive-tech-notifications</code>
9
+ and <code>div#js-assistive-tech-notifications-assertive</code>.
10
+ <% end %>
@@ -0,0 +1,5 @@
1
+ module Anchor
2
+ class AssistiveTechNotificationsComponentPreview < Preview
3
+ def default; end
4
+ end
5
+ end
@@ -1,20 +1,11 @@
1
- <%= anchor_form_with url: false, method: :get do |form| %>
2
- <%= form.search_field :search, placeholder: "Search…",
3
- starting_icon: :search %>
4
- <%= form.text_field :search, placeholder: "Search…",
5
- ending_icon: :calendar %>
6
- <%= form.text_field :search, placeholder: "Search…", starting_icon: :search,
7
- ending_icon: :calendar %>
8
- <%= form.number_field(
9
- :amount,
10
- placeholder: "0.00",
11
- starting_icon: :dollar,
12
- step: 0.01
13
- ) %>
14
- <%= form.number_field(
15
- :amount,
16
- placeholder: "0",
17
- ending_icon: :dollar,
18
- step: 1
19
- ) %>
1
+ <%= anchor_form_with url: false do |form| %>
2
+ <%= tag.div do %>
3
+ <%= form.label :price %>
4
+ <%= form.text_field :price, inputmode: :numeric, starting_icon: "dollar" %>
5
+ <% end %>
6
+
7
+ <%= tag.div do %>
8
+ <%= form.label :discount %>
9
+ <%= form.text_field :discount, inputmode: :numeric, ending_icon: "percentage" %>
10
+ <% end %>
20
11
  <% end %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anchor_view_components
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.44.0
4
+ version: 0.45.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Buoy Software
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-08 00:00:00.000000000 Z
11
+ date: 2024-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -69,6 +69,7 @@ files:
69
69
  - app/assets/images/icons/nav-arrow-left.svg
70
70
  - app/assets/images/icons/nav-arrow-right.svg
71
71
  - app/assets/images/icons/paste-clipboard.svg
72
+ - app/assets/images/icons/percentage.svg
72
73
  - app/assets/images/icons/plus.svg
73
74
  - app/assets/images/icons/search.svg
74
75
  - app/assets/images/icons/warning-circle.svg
@@ -82,6 +83,9 @@ files:
82
83
  - app/components/anchor/action_menu_component.html.erb
83
84
  - app/components/anchor/action_menu_component.rb
84
85
  - app/components/anchor/anchor_view_components.ts
86
+ - app/components/anchor/assistive_tech_notifications_component.html.erb
87
+ - app/components/anchor/assistive_tech_notifications_component.rb
88
+ - app/components/anchor/assistive_tech_notifications_component.ts
85
89
  - app/components/anchor/autocomplete/results_component.html.erb
86
90
  - app/components/anchor/autocomplete/results_component.rb
87
91
  - app/components/anchor/autocomplete_component.en.yml
@@ -196,6 +200,8 @@ files:
196
200
  - previews/anchor/action_menu_component_preview/autoplacement.html.erb
197
201
  - previews/anchor/action_menu_component_preview/custom_trigger.html.erb
198
202
  - previews/anchor/action_menu_component_preview/opens_a_dialog.html.erb
203
+ - previews/anchor/assistive_tech_notifications_component_preview.rb
204
+ - previews/anchor/assistive_tech_notifications_component_preview/default.html.erb
199
205
  - previews/anchor/badge_component_preview.rb
200
206
  - previews/anchor/banner_component_preview.rb
201
207
  - previews/anchor/banner_component_preview/body_only.html.erb