ariadne_view_components 0.0.47-x86_64-darwin → 0.0.48-x86_64-darwin

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -25
  3. data/app/assets/javascripts/ariadne_view_components.js +2 -2
  4. data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
  5. data/app/assets/javascripts/components/ariadne/accumulator_controller/accumulator_controller.d.ts +22 -0
  6. data/app/assets/javascripts/components/ariadne/dropdown/menu_component.d.ts +1 -0
  7. data/app/assets/javascripts/components/ariadne/options_controller/options_controller.d.ts +21 -0
  8. data/app/assets/javascripts/components/ariadne/toggleable_controller/toggleable_controller.d.ts +34 -0
  9. data/app/assets/stylesheets/ariadne_view_components.css +3 -3
  10. data/app/components/ariadne/accumulator_controller/accumulator_controller.d.ts +22 -0
  11. data/app/components/ariadne/accumulator_controller/accumulator_controller.js +39 -0
  12. data/app/components/ariadne/accumulator_controller/accumulator_controller.ts +48 -0
  13. data/app/components/ariadne/action_card_component.html.erb +11 -0
  14. data/app/components/ariadne/action_card_component.rb +45 -0
  15. data/app/components/ariadne/ariadne.js +6 -0
  16. data/app/components/ariadne/ariadne.ts +6 -0
  17. data/app/components/ariadne/bottom_tab_component.html.erb +4 -0
  18. data/app/components/ariadne/bottom_tab_component.rb +44 -0
  19. data/app/components/ariadne/bottom_tab_nav_component.html.erb +5 -0
  20. data/app/components/ariadne/bottom_tab_nav_component.rb +33 -0
  21. data/app/components/ariadne/breadcrumbs_component.html.erb +13 -0
  22. data/app/components/ariadne/breadcrumbs_component.rb +31 -0
  23. data/app/components/ariadne/checkbox_component.html.erb +5 -0
  24. data/app/components/ariadne/checkbox_component.rb +43 -0
  25. data/app/components/ariadne/close_button_component.html.erb +4 -0
  26. data/app/components/ariadne/close_button_component.rb +32 -0
  27. data/app/components/ariadne/dropdown/menu_component.d.ts +1 -0
  28. data/app/components/ariadne/dropdown/menu_component.js +1 -0
  29. data/app/components/ariadne/options_controller/options_controller.d.ts +21 -0
  30. data/app/components/ariadne/options_controller/options_controller.js +50 -0
  31. data/app/components/ariadne/options_controller/options_controller.ts +57 -0
  32. data/app/components/ariadne/popover_component.html.erb +11 -0
  33. data/app/components/ariadne/popover_component.rb +81 -0
  34. data/app/components/ariadne/progress_bar_component.html.erb +5 -0
  35. data/app/components/ariadne/progress_bar_component.rb +63 -0
  36. data/app/components/ariadne/relative_time_component.html.erb +3 -0
  37. data/app/components/ariadne/relative_time_component.rb +61 -0
  38. data/app/components/ariadne/show_more_button_component.html.erb +11 -0
  39. data/app/components/ariadne/show_more_button_component.rb +47 -0
  40. data/app/components/ariadne/spinner_component.html.erb +16 -0
  41. data/app/components/ariadne/spinner_component.rb +45 -0
  42. data/app/components/ariadne/subheader_component.html.erb +11 -0
  43. data/app/components/ariadne/subheader_component.rb +65 -0
  44. data/app/components/ariadne/toggle_component/toggle_component.html.erb +15 -0
  45. data/app/components/ariadne/toggle_component.rb +95 -0
  46. data/app/components/ariadne/toggleable_controller/toggleable_controller.d.ts +34 -0
  47. data/app/components/ariadne/toggleable_controller/toggleable_controller.js +74 -0
  48. data/app/components/ariadne/toggleable_controller/toggleable_controller.ts +87 -0
  49. data/lib/ariadne/view_components/version.rb +1 -1
  50. data/static/arguments.yml +50 -0
  51. data/static/audited_at.json +14 -0
  52. data/static/classes.yml +209 -173
  53. data/static/constants.json +282 -0
  54. data/static/statuses.json +14 -0
  55. data/tailwind.config.js +7 -7
  56. metadata +53 -12
  57. /data/app/assets/javascripts/{ariadne-form.d.ts → components/ariadne/ariadne-form.d.ts} +0 -0
  58. /data/app/assets/javascripts/{ariadne.d.ts → components/ariadne/ariadne.d.ts} +0 -0
  59. /data/app/assets/javascripts/{clipboard_copy_component → components/ariadne/clipboard_copy_component}/clipboard-copy-component.d.ts +0 -0
  60. /data/app/assets/javascripts/{rich_text_area_component → components/ariadne/rich_text_area_component}/rich-text-area-component.d.ts +0 -0
  61. /data/app/assets/javascripts/{slideover_component → components/ariadne/slideover_component}/slideover-component.d.ts +0 -0
  62. /data/app/assets/javascripts/{tab_container_component → components/ariadne/tab_container_component}/tab-container-component.d.ts +0 -0
  63. /data/app/assets/javascripts/{tab_nav_component → components/ariadne/tab_nav_component}/tab-nav-component.d.ts +0 -0
  64. /data/app/assets/javascripts/{time_ago_component → components/ariadne/time_ago_component}/time-ago-component.d.ts +0 -0
  65. /data/app/assets/javascripts/{tooltip_component → components/ariadne/tooltip_component}/tooltip-component.d.ts +0 -0
@@ -0,0 +1,22 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ export default class AccumulatorController extends Controller {
3
+ static targets: string[];
4
+ static values: {
5
+ syncAttrs: {
6
+ type: ArrayConstructor;
7
+ default: string[];
8
+ };
9
+ sumAttr: {
10
+ type: string;
11
+ default: string;
12
+ };
13
+ };
14
+ sumTargets: Array<HTMLElement>;
15
+ accumulatorTarget?: HTMLElement;
16
+ syncAttrsValue: Array<string>;
17
+ sumAttrValue: string;
18
+ connect(): void;
19
+ accumulate(): void;
20
+ setAttributesTo(sum: number): void;
21
+ get accumulator(): Element;
22
+ }
@@ -0,0 +1 @@
1
+ import '@github/details-menu-element';
@@ -0,0 +1,21 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ export default class OptionsController extends Controller {
3
+ #private;
4
+ static targets: string[];
5
+ static values: {
6
+ activeIndex: {
7
+ type: NumberConstructor;
8
+ default: number;
9
+ };
10
+ syncedAttrs: ArrayConstructor;
11
+ antiAttrs: ArrayConstructor;
12
+ };
13
+ readonly optionTargets: Array<Element>;
14
+ activeIndexValue: number;
15
+ readonly syncedAttrsValue: string[];
16
+ readonly hasSyncedAttrsValue: boolean;
17
+ readonly antiAttrsValue: string[];
18
+ readonly hasAntiAttrsValue: boolean;
19
+ connect(): void;
20
+ select(e: Event, newIndex?: number): void;
21
+ }
@@ -0,0 +1,34 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ export interface ToggleableOutlet {
3
+ toggle: (event: Event, value?: boolean) => void;
4
+ }
5
+ export default class ToggleableController extends Controller implements ToggleableOutlet {
6
+ #private;
7
+ static outlets: string[];
8
+ static values: {
9
+ state: {
10
+ type: BooleanConstructor;
11
+ default: boolean;
12
+ };
13
+ syncedAttrs: ArrayConstructor;
14
+ antiAttrs: ArrayConstructor;
15
+ closeOnOutsideClick: {
16
+ type: BooleanConstructor;
17
+ default: boolean;
18
+ };
19
+ };
20
+ static removeOnFalseAttrs: {
21
+ [k: string]: boolean;
22
+ };
23
+ stateValue: boolean;
24
+ readonly toggleableOutlets: Array<ToggleableOutlet>;
25
+ readonly hasToggleableOutlet: boolean;
26
+ readonly syncedAttrsValue: string[];
27
+ readonly hasSyncedAttrsValue: boolean;
28
+ readonly antiAttrsValue: string[];
29
+ readonly hasAntiAttrsValue: boolean;
30
+ readonly closeOnOutsideClickValue: boolean;
31
+ connect(): void;
32
+ toggle(event: Event, value?: boolean): void;
33
+ clickOutside(event: Event): void;
34
+ }
@@ -1,6 +1,6 @@
1
- @import 'tailwindcss/base';
2
- @import 'tailwindcss/components';
3
- @import 'tailwindcss/utilities';
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
4
 
5
5
  @import 'tooltip-component.css';
6
6
  @import 'prosemirror.css';
@@ -0,0 +1,22 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ export default class AccumulatorController extends Controller {
3
+ static targets: string[];
4
+ static values: {
5
+ syncAttrs: {
6
+ type: ArrayConstructor;
7
+ default: string[];
8
+ };
9
+ sumAttr: {
10
+ type: string;
11
+ default: string;
12
+ };
13
+ };
14
+ sumTargets: Array<HTMLElement>;
15
+ accumulatorTarget?: HTMLElement;
16
+ syncAttrsValue: Array<string>;
17
+ sumAttrValue: string;
18
+ connect(): void;
19
+ accumulate(): void;
20
+ setAttributesTo(sum: number): void;
21
+ get accumulator(): Element;
22
+ }
@@ -0,0 +1,39 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ class AccumulatorController extends Controller {
3
+ connect() {
4
+ this.accumulate();
5
+ }
6
+ accumulate() {
7
+ let sum = 0;
8
+ for (let i in this.sumTargets) {
9
+ const target = this.sumTargets[i];
10
+ const value = Number(target.getAttribute(this.sumAttrValue));
11
+ if (!isNaN(value)) {
12
+ sum += value;
13
+ }
14
+ }
15
+ this.setAttributesTo(sum);
16
+ }
17
+ setAttributesTo(sum) {
18
+ for (let i in this.syncAttrsValue) {
19
+ const attr = this.syncAttrsValue[i];
20
+ this.accumulator.setAttribute(attr, sum.toString());
21
+ }
22
+ }
23
+ get accumulator() {
24
+ var _a;
25
+ return (_a = this.accumulatorTarget) !== null && _a !== void 0 ? _a : this.element;
26
+ }
27
+ }
28
+ AccumulatorController.targets = ['sum', 'accumulator'];
29
+ AccumulatorController.values = {
30
+ syncAttrs: {
31
+ type: Array,
32
+ default: ['aria-valuenow'],
33
+ },
34
+ sumAttr: {
35
+ type: 'string',
36
+ default: 'data-value',
37
+ },
38
+ };
39
+ export default AccumulatorController;
@@ -0,0 +1,48 @@
1
+ import {Controller} from '@hotwired/stimulus'
2
+
3
+ export default class AccumulatorController extends Controller {
4
+ static targets = ['sum', 'accumulator']
5
+ static values = {
6
+ syncAttrs: {
7
+ type: Array,
8
+ default: ['aria-valuenow'],
9
+ },
10
+ sumAttr: {
11
+ type: 'string',
12
+ default: 'data-value',
13
+ },
14
+ }
15
+
16
+ declare sumTargets: Array<HTMLElement>
17
+ declare accumulatorTarget?: HTMLElement
18
+ declare syncAttrsValue: Array<string>
19
+ declare sumAttrValue: string
20
+
21
+ connect(): void {
22
+ this.accumulate()
23
+ }
24
+
25
+ accumulate() {
26
+ let sum = 0
27
+ for (let i in this.sumTargets) {
28
+ const target = this.sumTargets[i]
29
+ const value = Number(target.getAttribute(this.sumAttrValue))
30
+ if (!isNaN(value)) {
31
+ sum += value
32
+ }
33
+ }
34
+
35
+ this.setAttributesTo(sum)
36
+ }
37
+
38
+ setAttributesTo(sum: number) {
39
+ for (let i in this.syncAttrsValue) {
40
+ const attr = this.syncAttrsValue[i]
41
+ this.accumulator.setAttribute(attr, sum.toString())
42
+ }
43
+ }
44
+
45
+ get accumulator() {
46
+ return this.accumulatorTarget ?? this.element
47
+ }
48
+ }
@@ -0,0 +1,11 @@
1
+ <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |component| %>
2
+ <%= icon %>
3
+ <%= title %>
4
+ <% if actions? %>
5
+ <div class="<%= @actions_wrapper_classes %>">
6
+ <% actions.each do |action| %>
7
+ <%= action %>
8
+ <% end %>
9
+ </div>
10
+ <% end %>
11
+ <% end %>
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # Add a general description of component here
5
+ # Add additional usage considerations or best practices that may aid the user to use the component correctly.
6
+ # @accessibility Add any accessibility considerations
7
+ class ActionCardComponent < Ariadne::Component
8
+ DEFAULT_TAG = :div
9
+ TAG_OPTIONS = [DEFAULT_TAG].freeze
10
+
11
+ DEFAULT_CLASSES = {
12
+ wrapper: "ariadne-w-fit ariadne-flex ariadne-flex-col ariadne-items-center",
13
+ actions_wrapper: "ariadne-flex",
14
+ }
15
+
16
+ DEFAULT_ATTRIBUTES = {
17
+ wrapper: {},
18
+ }
19
+
20
+ renders_one :icon, Ariadne::HeroiconComponent
21
+
22
+ renders_one :title, Ariadne::HeadingComponent
23
+
24
+ renders_many :actions, Ariadne::ButtonComponent
25
+
26
+ # @example Default
27
+ #
28
+ # <%= render(Ariadne::ActionCardComponent.new) { "Example" } %>
29
+ #
30
+ # @param tag [Symbol, String] The rendered tag name.
31
+ # @param classes [String] <%= link_to_classes_docs %>
32
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
33
+ def initialize(
34
+ tag: DEFAULT_TAG,
35
+ classes: "",
36
+ attributes: {},
37
+ actions_wrapper_classes: ""
38
+ )
39
+ @tag = check_incoming_tag(DEFAULT_TAG, tag)
40
+ @classes = merge_class_names(DEFAULT_CLASSES[:wrapper], classes)
41
+ @attributes = DEFAULT_ATTRIBUTES[:wrapper].merge(attributes)
42
+ @actions_wrapper_classes = merge_class_names(DEFAULT_CLASSES[:actions_wrapper], actions_wrapper_classes)
43
+ end
44
+ end
45
+ end
@@ -1,5 +1,8 @@
1
1
  import { Application } from '@hotwired/stimulus';
2
2
  import AriadneForm from './ariadne-form';
3
+ import OptionsController from './options_controller/options_controller';
4
+ import AccumulatorController from './accumulator_controller/accumulator_controller';
5
+ import ToggleableController from './toggleable_controller/toggleable_controller';
3
6
  import ClipboardCopyComponent from './clipboard_copy_component/clipboard-copy-component';
4
7
  import RichTextAreaComponent from './rich_text_area_component/rich-text-area-component';
5
8
  import SlideoverComponent from './slideover_component/slideover-component';
@@ -14,3 +17,6 @@ application.register('rich-text-area-component', RichTextAreaComponent);
14
17
  application.register('slideover-component', SlideoverComponent);
15
18
  application.register('tab-nav-component', TabNavComponent);
16
19
  application.register('tooltip-component', TooltipComponent);
20
+ application.register('toggleable', ToggleableController);
21
+ application.register('accumulator', AccumulatorController);
22
+ application.register('options', OptionsController);
@@ -2,6 +2,9 @@ import {Application} from '@hotwired/stimulus'
2
2
 
3
3
  import AriadneForm from './ariadne-form'
4
4
 
5
+ import OptionsController from './options_controller/options_controller'
6
+ import AccumulatorController from './accumulator_controller/accumulator_controller'
7
+ import ToggleableController from './toggleable_controller/toggleable_controller'
5
8
  import ClipboardCopyComponent from './clipboard_copy_component/clipboard-copy-component'
6
9
  import RichTextAreaComponent from './rich_text_area_component/rich-text-area-component'
7
10
  import SlideoverComponent from './slideover_component/slideover-component'
@@ -19,3 +22,6 @@ application.register('rich-text-area-component', RichTextAreaComponent)
19
22
  application.register('slideover-component', SlideoverComponent)
20
23
  application.register('tab-nav-component', TabNavComponent)
21
24
  application.register('tooltip-component', TooltipComponent)
25
+ application.register('toggleable', ToggleableController)
26
+ application.register('accumulator', AccumulatorController)
27
+ application.register('options', OptionsController)
@@ -0,0 +1,4 @@
1
+ <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |component| %>
2
+ <%= icon %>
3
+ <%= content %>
4
+ <% end %>
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # Tab component to be used with bottom_tab_nav
5
+
6
+ # Accessibility considerations:
7
+ # aria-controls="tabpanelID": Use this if content is being conditionally controlled. Reference the ID of the content being controlled
8
+ class BottomTabComponent < Ariadne::Component
9
+ DEFAULT_TAG = :a
10
+ TAG_OPTIONS = [DEFAULT_TAG].freeze
11
+
12
+ DEFAULT_CLASSES = "ariadne-w-full ariadne-py-4 ariadne-flex ariadne-flex-col ariadne-justify-center ariadne-items-center ariadne-cursor-pointer [&>span]:ariadne-p-0 ariadne-border-y-2 ariadne-border-r-2 first:ariadne-border-l-2 ariadne-border-solid ariadne-border-black"
13
+ TAB_BACKGROUND_COLOR_CLASSES = "aria-selected:ariadne-bg-gray-200"
14
+
15
+ DEFAULT_ATTRIBUTES = {
16
+ "data-action": "click->options#select",
17
+ "data-options-target": "option",
18
+ role: "tab",
19
+ tabindex: "0",
20
+ }
21
+
22
+ renders_one :icon, Ariadne::HeroiconComponent
23
+
24
+ # @example Default
25
+ #
26
+ # <%= render(Ariadne::BottomTabComponent.new) { "Example" } %>
27
+ #
28
+ # @param tag [Symbol, String] The rendered tag name.
29
+ # @param classes [String] <%= link_to_classes_docs %>
30
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
31
+ def initialize(tag: DEFAULT_TAG, classes: "", active: false, attributes: {})
32
+ @tag = check_incoming_tag(DEFAULT_TAG, tag)
33
+ @classes = merge_class_names(
34
+ DEFAULT_CLASSES,
35
+ TAB_BACKGROUND_COLOR_CLASSES,
36
+ classes,
37
+ )
38
+
39
+ @attributes = DEFAULT_ATTRIBUTES
40
+ .merge({ "aria-selected": active })
41
+ .merge(attributes)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,5 @@
1
+ <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do %>
2
+ <% tabs.each do |tab| %>
3
+ <%= tab %>
4
+ <% end %>
5
+ <% end %>
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # Navigation component for BottomTabs
5
+ class BottomTabNavComponent < Ariadne::Component
6
+ DEFAULT_TAG = :nav
7
+ DEFAULT_TAB_TAG = :a
8
+ TAG_OPTIONS = [DEFAULT_TAG].freeze
9
+
10
+ DEFAULT_CLASSES = "ariadne-flex"
11
+
12
+ DEFAULT_ATTRIBUTES = {
13
+ "data-controller": "options",
14
+ "data-options-synced-attrs-value": '["aria-selected"]',
15
+ role: "tablist",
16
+ }
17
+
18
+ renders_many :tabs, Ariadne::BottomTabComponent
19
+
20
+ # @example Default
21
+ #
22
+ # <%= render(Ariadne::BottomTabNavComponent.new) { "Example" } %>
23
+ #
24
+ # @param tag [Symbol, String] The rendered tag name.
25
+ # @param classes [String] <%= link_to_classes_docs %>
26
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
27
+ def initialize(tag: DEFAULT_TAG, classes: "", attributes: {})
28
+ @tag = check_incoming_tag(DEFAULT_TAG, tag)
29
+ @classes = merge_class_names(DEFAULT_CLASSES, classes)
30
+ @attributes = DEFAULT_ATTRIBUTES.merge(attributes)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |component| %>
2
+ <ol class="ariadne-flex ariadne-gap-2 ariadne-items-center">
3
+ <% @items.each_with_index do |item, index| %>
4
+ <% if index == @items.size - 1 %>
5
+ <li class="<%= @active_item_classes %>" aria-current="page"><%= item[:title] %></li>
6
+ <% else %>
7
+ <li class="<%= @item_classes %>"><a href="<%= item[:url] %>"><%= item[:title] %></a></li>
8
+ <%= render Ariadne::HeroiconComponent.new(tag: :svg, icon: "chevron-right", variant: HeroiconsHelper::Icon::VARIANT_OUTLINE, size: :xs) do |icon| %>
9
+ <% end %>
10
+ <% end %>
11
+ <% end %>
12
+ </ol>
13
+ <% end %>
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # Breadcrumb component showing current navigation. The last item is considered the active one
5
+ class BreadcrumbsComponent < Ariadne::Component
6
+ DEFAULT_TAG = :nav
7
+ TAG_OPTIONS = [DEFAULT_TAG].freeze
8
+
9
+ DEFAULT_CLASSES = { wrapper: "", item: "", active_item: "ariadne-underline" }
10
+
11
+ # @example Default
12
+ #
13
+ # <%= render(Ariadne::BreadcrumbsComponent.new) { "Example" } %>
14
+ #
15
+ # @param tag [Symbol, String] The rendered tag name.
16
+ # @param classes [String] <%= link_to_classes_docs %>
17
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
18
+ def initialize(tag: DEFAULT_TAG, classes: "", items: [], item_classes: "", active_item_classes: "", attributes: {})
19
+ @tag = check_incoming_tag(DEFAULT_TAG, tag)
20
+ @classes = merge_class_names(
21
+ DEFAULT_CLASSES[:wrapper],
22
+ classes,
23
+ )
24
+
25
+ @items = items
26
+ @item_classes = merge_class_names(DEFAULT_CLASSES[:item], item_classes)
27
+ @active_item_classes = merge_class_names(DEFAULT_CLASSES[:item], DEFAULT_CLASSES[:active_item], item_classes, active_item_classes)
28
+ @attributes = attributes
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,5 @@
1
+ <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @label_classes, attributes: @label_attributes) do |component| %>
2
+ <%= render Ariadne::BaseComponent.new(tag: :input, classes: @input_classes, attributes: @input_attributes) do |input| %>
3
+ <% end %>
4
+ <%= content %>
5
+ <% end %>
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # Just a checkbox with a label, state managed by toggleable controller
5
+ class CheckboxComponent < Ariadne::Component
6
+ DEFAULT_TAG = :label
7
+ TAG_OPTIONS = [DEFAULT_TAG].freeze
8
+
9
+ DEFAULT_CLASSES = {
10
+ input: "ariadne-mr-2",
11
+ label: "ariadne-flex ariadne-items-center ariadne-cursor-pointer ariadne-w-fit",
12
+ }
13
+
14
+ DEFAULT_ATTRIBUTES = {
15
+ input: {
16
+ type: "checkbox",
17
+ "data-controller": "toggleable",
18
+ "data-toggleable-synced-attrs-value": '["checked", "aria-checked"]',
19
+ "data-action": "click->toggleable#toggle",
20
+ },
21
+ label: {},
22
+ }
23
+
24
+ # @example Default
25
+ #
26
+ # <%= render(Ariadne::CheckboxComponent.new) { "Example" } %>
27
+ #
28
+ # @param tag [Symbol, String] The rendered tag name.
29
+ # @param classes [String] <%= link_to_classes_docs %>
30
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
31
+ def initialize(tag: DEFAULT_TAG, classes: "", input_classes: "", initial_value: false, input_attributes: {}, attributes: {})
32
+ @tag = @tag = check_incoming_tag(DEFAULT_TAG, tag)
33
+
34
+ @label_attributes = DEFAULT_ATTRIBUTES[:label].merge(attributes)
35
+ @label_classes = merge_class_names(DEFAULT_CLASSES[:label], classes)
36
+
37
+ @input_classes = merge_class_names(DEFAULT_CLASSES[:input], input_classes)
38
+ @input_attributes = DEFAULT_ATTRIBUTES[:input]
39
+ .merge({ "data-toggleable-state-value": initial_value.to_s })
40
+ .merge(input_attributes)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,4 @@
1
+ <%= render Ariadne::ButtonComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |component| %>
2
+ <%= render Ariadne::HeroiconComponent.new(icon: "x-mark", variant: HeroiconsHelper::Icon::VARIANT_OUTLINE, classes: @icon_classes, size: @size) do |icon| %>
3
+ <% end %>
4
+ <% end %>
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # Simple button with X icon to close models and such
5
+ class CloseButtonComponent < Ariadne::Component
6
+ DEFAULT_TAG = :button
7
+ TAG_OPTIONS = [DEFAULT_TAG].freeze
8
+
9
+ DEFAULT_CLASSES = "ariadne-border-none ariadne-bg-transparent ariadne-shadow-none hover:ariadne-bg-transparent"
10
+
11
+ # @example Default
12
+ #
13
+ # <%= render(Ariadne::CloseButtonComponent.new) { "Example" } %>
14
+ #
15
+ # @param tag [Symbol, String] The rendered tag name.
16
+ # @param classes [String] <%= link_to_classes_docs %>
17
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
18
+ def initialize(tag: DEFAULT_TAG, classes: "", icon_classes: "", size: :xs, aria_label: nil, attributes: {})
19
+ raise ArgumentError, "An 'aria_label' argument is required to use a Close Button. Include as much detail as you can about what the button will be closing." if aria_label.blank?
20
+
21
+ @tag = check_incoming_tag(DEFAULT_TAG, tag)
22
+ @attributes = { "aria-label": aria_label }.merge(attributes)
23
+ @classes = merge_class_names(
24
+ DEFAULT_CLASSES,
25
+ classes,
26
+ )
27
+
28
+ @size = size
29
+ @icon_classses = icon_classes
30
+ end
31
+ end
32
+ end
@@ -0,0 +1 @@
1
+ import '@github/details-menu-element';
@@ -0,0 +1 @@
1
+ import '@github/details-menu-element';
@@ -0,0 +1,21 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ export default class OptionsController extends Controller {
3
+ #private;
4
+ static targets: string[];
5
+ static values: {
6
+ activeIndex: {
7
+ type: NumberConstructor;
8
+ default: number;
9
+ };
10
+ syncedAttrs: ArrayConstructor;
11
+ antiAttrs: ArrayConstructor;
12
+ };
13
+ readonly optionTargets: Array<Element>;
14
+ activeIndexValue: number;
15
+ readonly syncedAttrsValue: string[];
16
+ readonly hasSyncedAttrsValue: boolean;
17
+ readonly antiAttrsValue: string[];
18
+ readonly hasAntiAttrsValue: boolean;
19
+ connect(): void;
20
+ select(e: Event, newIndex?: number): void;
21
+ }
@@ -0,0 +1,50 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var _OptionsController_instances, _OptionsController_updateAllAttrsForElement, _OptionsController_syncAttrsForTarget;
7
+ import { Controller } from '@hotwired/stimulus';
8
+ class OptionsController extends Controller {
9
+ constructor() {
10
+ super(...arguments);
11
+ _OptionsController_instances.add(this);
12
+ }
13
+ connect() {
14
+ this.select(new Event('Init'), this.activeIndexValue);
15
+ }
16
+ select(e, newIndex) {
17
+ for (let index in this.optionTargets) {
18
+ const target = this.optionTargets[index];
19
+ const isActive = newIndex === undefined ? target === e.currentTarget : Number(index) === Number(newIndex);
20
+ if (isActive) {
21
+ this.activeIndexValue = Number(index);
22
+ }
23
+ __classPrivateFieldGet(this, _OptionsController_instances, "m", _OptionsController_updateAllAttrsForElement).call(this, target, isActive);
24
+ }
25
+ }
26
+ }
27
+ _OptionsController_instances = new WeakSet(), _OptionsController_updateAllAttrsForElement = function _OptionsController_updateAllAttrsForElement(element, value) {
28
+ if (this.hasSyncedAttrsValue) {
29
+ __classPrivateFieldGet(this, _OptionsController_instances, "m", _OptionsController_syncAttrsForTarget).call(this, element, this.syncedAttrsValue, value);
30
+ }
31
+ if (this.hasAntiAttrsValue) {
32
+ __classPrivateFieldGet(this, _OptionsController_instances, "m", _OptionsController_syncAttrsForTarget).call(this, element, this.antiAttrsValue, !value);
33
+ }
34
+ }, _OptionsController_syncAttrsForTarget = function _OptionsController_syncAttrsForTarget(element, attrs, value) {
35
+ const attrState = String(value);
36
+ for (let index in attrs) {
37
+ const attr = attrs[index];
38
+ element.setAttribute(attr, attrState);
39
+ }
40
+ };
41
+ OptionsController.targets = ['option'];
42
+ OptionsController.values = {
43
+ activeIndex: {
44
+ type: Number,
45
+ default: 0,
46
+ },
47
+ syncedAttrs: Array,
48
+ antiAttrs: Array,
49
+ };
50
+ export default OptionsController;
@@ -0,0 +1,57 @@
1
+ import {Controller} from '@hotwired/stimulus'
2
+
3
+ export default class OptionsController extends Controller {
4
+ static targets = ['option']
5
+
6
+ static values = {
7
+ activeIndex: {
8
+ type: Number,
9
+ default: 0,
10
+ },
11
+ syncedAttrs: Array,
12
+ antiAttrs: Array,
13
+ }
14
+
15
+ declare readonly optionTargets: Array<Element>
16
+ declare activeIndexValue: number
17
+
18
+ declare readonly syncedAttrsValue: string[]
19
+ declare readonly hasSyncedAttrsValue: boolean
20
+ declare readonly antiAttrsValue: string[]
21
+ declare readonly hasAntiAttrsValue: boolean
22
+
23
+ connect(): void {
24
+ this.select(new Event('Init'), this.activeIndexValue)
25
+ }
26
+
27
+ select(e: Event, newIndex?: number) {
28
+ for (let index in this.optionTargets) {
29
+ const target = this.optionTargets[index]
30
+ const isActive = newIndex === undefined ? target === e.currentTarget : Number(index) === Number(newIndex)
31
+
32
+ if (isActive) {
33
+ this.activeIndexValue = Number(index)
34
+ }
35
+
36
+ this.#updateAllAttrsForElement(target, isActive)
37
+ }
38
+ }
39
+
40
+ #updateAllAttrsForElement(element: Element, value: boolean) {
41
+ if (this.hasSyncedAttrsValue) {
42
+ this.#syncAttrsForTarget(element, this.syncedAttrsValue, value)
43
+ }
44
+
45
+ if (this.hasAntiAttrsValue) {
46
+ this.#syncAttrsForTarget(element, this.antiAttrsValue, !value)
47
+ }
48
+ }
49
+
50
+ #syncAttrsForTarget(element: Element, attrs: string[], value: boolean) {
51
+ const attrState = String(value)
52
+ for (let index in attrs) {
53
+ const attr = attrs[index]
54
+ element.setAttribute(attr, attrState)
55
+ }
56
+ }
57
+ }