ariadne_view_components 0.0.47-x86_64-linux → 0.0.49-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -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/events_controller/events_controller.d.ts +4 -0
  8. data/app/assets/javascripts/components/ariadne/options_controller/options_controller.d.ts +40 -0
  9. data/app/assets/javascripts/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +42 -0
  10. data/app/assets/javascripts/components/ariadne/string_match_controller/string_match_controller.d.ts +27 -0
  11. data/app/assets/javascripts/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +44 -0
  12. data/app/assets/javascripts/components/ariadne/toggleable_controller/toggleable_controller.d.ts +34 -0
  13. data/app/assets/stylesheets/ariadne_view_components.css +3 -3
  14. data/app/components/ariadne/accumulator_controller/accumulator_controller.d.ts +22 -0
  15. data/app/components/ariadne/accumulator_controller/accumulator_controller.js +39 -0
  16. data/app/components/ariadne/accumulator_controller/accumulator_controller.ts +48 -0
  17. data/app/components/ariadne/action_card_component.html.erb +11 -0
  18. data/app/components/ariadne/action_card_component.rb +45 -0
  19. data/app/components/ariadne/ariadne.js +10 -0
  20. data/app/components/ariadne/ariadne.ts +10 -0
  21. data/app/components/ariadne/bottom_tab_component.html.erb +4 -0
  22. data/app/components/ariadne/bottom_tab_component.rb +44 -0
  23. data/app/components/ariadne/bottom_tab_nav_component.html.erb +5 -0
  24. data/app/components/ariadne/bottom_tab_nav_component.rb +33 -0
  25. data/app/components/ariadne/breadcrumbs_component.html.erb +13 -0
  26. data/app/components/ariadne/breadcrumbs_component.rb +31 -0
  27. data/app/components/ariadne/checkbox_component.html.erb +5 -0
  28. data/app/components/ariadne/checkbox_component.rb +43 -0
  29. data/app/components/ariadne/close_button_component.html.erb +4 -0
  30. data/app/components/ariadne/close_button_component.rb +33 -0
  31. data/app/components/ariadne/combobox_component.html.erb +14 -0
  32. data/app/components/ariadne/combobox_component.rb +76 -0
  33. data/app/components/ariadne/dropdown/menu_component.d.ts +1 -0
  34. data/app/components/ariadne/dropdown/menu_component.js +1 -0
  35. data/app/components/ariadne/events_controller/events_controller.d.ts +4 -0
  36. data/app/components/ariadne/events_controller/events_controller.js +6 -0
  37. data/app/components/ariadne/events_controller/events_controller.ts +7 -0
  38. data/app/components/ariadne/layout_component.html.erb +21 -0
  39. data/app/components/ariadne/layout_component.rb +69 -0
  40. data/app/components/ariadne/modal_component.html.erb +11 -0
  41. data/app/components/ariadne/modal_component.rb +88 -0
  42. data/app/components/ariadne/options_controller/options_controller.d.ts +40 -0
  43. data/app/components/ariadne/options_controller/options_controller.js +98 -0
  44. data/app/components/ariadne/options_controller/options_controller.ts +132 -0
  45. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +42 -0
  46. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.js +237 -0
  47. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.ts +278 -0
  48. data/app/components/ariadne/popover_component.html.erb +10 -0
  49. data/app/components/ariadne/popover_component.rb +81 -0
  50. data/app/components/ariadne/progress_bar_component.html.erb +5 -0
  51. data/app/components/ariadne/progress_bar_component.rb +63 -0
  52. data/app/components/ariadne/relative_time_component.html.erb +3 -0
  53. data/app/components/ariadne/relative_time_component.rb +61 -0
  54. data/app/components/ariadne/show_more_button_component.html.erb +11 -0
  55. data/app/components/ariadne/show_more_button_component.rb +47 -0
  56. data/app/components/ariadne/spinner_component.html.erb +16 -0
  57. data/app/components/ariadne/spinner_component.rb +45 -0
  58. data/app/components/ariadne/string_match_controller/string_match_controller.d.ts +27 -0
  59. data/app/components/ariadne/string_match_controller/string_match_controller.js +51 -0
  60. data/app/components/ariadne/string_match_controller/string_match_controller.ts +64 -0
  61. data/app/components/ariadne/subheader_component.html.erb +11 -0
  62. data/app/components/ariadne/subheader_component.rb +65 -0
  63. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +44 -0
  64. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.js +153 -0
  65. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.ts +192 -0
  66. data/app/components/ariadne/toggle_component/toggle_component.html.erb +15 -0
  67. data/app/components/ariadne/toggle_component.rb +95 -0
  68. data/app/components/ariadne/toggleable_controller/toggleable_controller.d.ts +34 -0
  69. data/app/components/ariadne/toggleable_controller/toggleable_controller.js +54 -0
  70. data/app/components/ariadne/toggleable_controller/toggleable_controller.ts +77 -0
  71. data/lib/ariadne/view_components/version.rb +1 -1
  72. data/static/arguments.yml +50 -0
  73. data/static/audited_at.json +17 -0
  74. data/static/classes.yml +209 -173
  75. data/static/constants.json +356 -0
  76. data/static/statuses.json +17 -0
  77. data/tailwind.config.js +7 -7
  78. metadata +75 -12
  79. /data/app/assets/javascripts/{ariadne-form.d.ts → components/ariadne/ariadne-form.d.ts} +0 -0
  80. /data/app/assets/javascripts/{ariadne.d.ts → components/ariadne/ariadne.d.ts} +0 -0
  81. /data/app/assets/javascripts/{clipboard_copy_component → components/ariadne/clipboard_copy_component}/clipboard-copy-component.d.ts +0 -0
  82. /data/app/assets/javascripts/{rich_text_area_component → components/ariadne/rich_text_area_component}/rich-text-area-component.d.ts +0 -0
  83. /data/app/assets/javascripts/{slideover_component → components/ariadne/slideover_component}/slideover-component.d.ts +0 -0
  84. /data/app/assets/javascripts/{tab_container_component → components/ariadne/tab_container_component}/tab-container-component.d.ts +0 -0
  85. /data/app/assets/javascripts/{tab_nav_component → components/ariadne/tab_nav_component}/tab-nav-component.d.ts +0 -0
  86. /data/app/assets/javascripts/{time_ago_component → components/ariadne/time_ago_component}/time-ago-component.d.ts +0 -0
  87. /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,4 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ export default class EventsController extends Controller {
3
+ stopPropagation(e: Event): void;
4
+ }
@@ -0,0 +1,40 @@
1
+ import { TOutletChangeData } from '../outlet_manager_controller/outlet_manager_controller';
2
+ import SyncedBooleanAttributesController from '../synced_boolean_attributes_controller/synced_boolean_attributes_controller';
3
+ type TOptionKey = string | number;
4
+ type TActiveOptions = {
5
+ [k: TOptionKey]: boolean;
6
+ };
7
+ export interface OptionsOutlet extends SyncedBooleanAttributesController<TActiveOptions> {
8
+ select: (e: Event, updateTo?: TOutletChangeData<TActiveOptions>) => void;
9
+ }
10
+ export default class OptionsController extends SyncedBooleanAttributesController<TActiveOptions> implements OptionsOutlet {
11
+ #private;
12
+ static outlets: string[];
13
+ static targets: string[];
14
+ static values: {
15
+ activeOptions: ObjectConstructor;
16
+ isMulti: {
17
+ type: BooleanConstructor;
18
+ default: boolean;
19
+ };
20
+ toggleable: {
21
+ type: BooleanConstructor;
22
+ default: boolean;
23
+ };
24
+ syncedAttrs: ArrayConstructor;
25
+ antiAttrs: ArrayConstructor;
26
+ protectAttrs: BooleanConstructor;
27
+ outletEvents: ArrayConstructor;
28
+ };
29
+ readonly optionTargets: Array<Element>;
30
+ activeOptionsValue: TActiveOptions;
31
+ readonly isMultiValue: boolean;
32
+ readonly toggleableValue: boolean;
33
+ optionTargetLookup: Map<Element, TOptionKey>;
34
+ connect(): void;
35
+ select(event: Event, updateTo?: TOutletChangeData<TActiveOptions>): void;
36
+ getValueForElement(element: Element): boolean | null;
37
+ getState(): TActiveOptions;
38
+ outletUpdate: (event: Event, updateTo?: TOutletChangeData<TActiveOptions>) => void;
39
+ }
40
+ export {};
@@ -0,0 +1,42 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+ type TOutletEventLookup = boolean | {
3
+ [k: string]: TOutletEventLookup;
4
+ };
5
+ export type TOutletChangeData<T> = {
6
+ eventKey?: string;
7
+ data?: T;
8
+ } | undefined;
9
+ export default class OutletManagerController<T> extends Controller {
10
+ #private;
11
+ static values: {
12
+ outletEvents: ArrayConstructor;
13
+ };
14
+ readonly outletEventsValue: Array<string>;
15
+ readonly hasOutletEventsValue: boolean;
16
+ static outlets: string[];
17
+ readonly toggleableOutlets: Array<OutletManagerController<T>>;
18
+ readonly hasToggleableOutlet: boolean;
19
+ readonly optionsOutlets: Array<OutletManagerController<T>>;
20
+ readonly hasOptionsOutlet: boolean;
21
+ readonly stringMatchOutlets: Array<OutletManagerController<T>>;
22
+ readonly hasStringMatchOutlet: boolean;
23
+ outletEventsLookup: TOutletEventLookup | null;
24
+ static domEvents: {
25
+ [k: string]: boolean;
26
+ };
27
+ eventRecords: Map<Event, boolean>;
28
+ getOutlets(): Array<OutletManagerController<T>> | null | void;
29
+ outletUpdate(event: Event, data: TOutletChangeData<T>): void;
30
+ getState(): T;
31
+ connect(): void;
32
+ syncOutlets(): void;
33
+ sendToOutlets(event: Event, updateTo?: TOutletChangeData<T>): void;
34
+ isListeningForOutletEvent(eventTypes: string): boolean;
35
+ isDOMEventName(eventName: string): boolean;
36
+ getEventKey(event: Event): string;
37
+ hasHeardEvent(event: Event): boolean;
38
+ get event_key_prefix(): string;
39
+ get event_key_postfix(): string;
40
+ get outletEvents(): TOutletEventLookup;
41
+ }
42
+ export {};
@@ -0,0 +1,27 @@
1
+ import { TOutletChangeData } from '../outlet_manager_controller/outlet_manager_controller';
2
+ import SyncedBooleanAttributesController from '../synced_boolean_attributes_controller/synced_boolean_attributes_controller';
3
+ export interface StringMatchOutlet extends SyncedBooleanAttributesController<string> {
4
+ change: (event: Event, updateTo?: TOutletChangeData<string>) => void;
5
+ }
6
+ export default class StringMatchController extends SyncedBooleanAttributesController<string> implements StringMatchOutlet {
7
+ #private;
8
+ static outlets: string[];
9
+ static targets: string[];
10
+ static values: {
11
+ keyword: StringConstructor;
12
+ syncedAttrs: ArrayConstructor;
13
+ antiAttrs: ArrayConstructor;
14
+ protectAttrs: BooleanConstructor;
15
+ outletEvents: ArrayConstructor;
16
+ };
17
+ readonly matchTargets: Array<HTMLElement>;
18
+ readonly hasMatchTarget: boolean;
19
+ readonly emptyTarget: Element;
20
+ readonly hasEmptyTarget: boolean;
21
+ keywordValue: string;
22
+ change(event: Event, updateTo?: TOutletChangeData<string>): void;
23
+ getElementsToSync(): Element[] | null | undefined;
24
+ getValueForElement(element: Element): boolean;
25
+ getState(): string;
26
+ outletUpdate: (event: Event, updateTo?: TOutletChangeData<string>) => void;
27
+ }
@@ -0,0 +1,44 @@
1
+ import OutletManagerController from '../outlet_manager_controller/outlet_manager_controller';
2
+ export type TStimulusDispatchEvent<TDetails> = {
3
+ target?: Element | undefined;
4
+ detail?: TDetails | undefined;
5
+ prefix?: string | undefined;
6
+ bubbles?: boolean | undefined;
7
+ cancelable?: boolean | undefined;
8
+ preventDefault: () => void;
9
+ };
10
+ export type TBooleanValueDetail = {
11
+ value: boolean;
12
+ };
13
+ export interface TSyncAttrDetail extends TBooleanValueDetail {
14
+ attr: string;
15
+ }
16
+ export default class SyncedBooleanAttributesController<T> extends OutletManagerController<T> {
17
+ #private;
18
+ static values: {
19
+ syncedAttrs: ArrayConstructor;
20
+ antiAttrs: ArrayConstructor;
21
+ protectAttrs: BooleanConstructor;
22
+ outletEvents: ArrayConstructor;
23
+ };
24
+ readonly syncedAttrsValue: string[];
25
+ readonly hasSyncedAttrsValue: boolean;
26
+ readonly antiAttrsValue: string[];
27
+ readonly hasAntiAttrsValue: boolean;
28
+ readonly protectAttrsValue: boolean;
29
+ static removeOnFalseAttrs: {
30
+ [k: string]: boolean;
31
+ };
32
+ syncedAttrsLookup: {
33
+ [k: string]: boolean;
34
+ } | null;
35
+ antiAttrsLookup: {
36
+ [k: string]: boolean;
37
+ } | null;
38
+ getValueForElement(element: Element): boolean | null;
39
+ getElementsToSync(): Array<Element> | null | undefined;
40
+ connect(): void;
41
+ updateAttributesForElement(element: Element, value: boolean): void;
42
+ syncElementAttributes(): void;
43
+ validateAttrChange(dispatchEvent: TStimulusDispatchEvent<TSyncAttrDetail>): void;
44
+ }
@@ -0,0 +1,34 @@
1
+ import type { TOutletChangeData } from '../outlet_manager_controller/outlet_manager_controller';
2
+ import SyncedBooleanAttributesController from '../synced_boolean_attributes_controller/synced_boolean_attributes_controller';
3
+ export interface ToggleableOutlet extends SyncedBooleanAttributesController<boolean> {
4
+ toggle: (event: Event, updateTo?: TOutletChangeData<boolean>) => void;
5
+ }
6
+ export default class ToggleableController extends SyncedBooleanAttributesController<boolean> implements ToggleableOutlet {
7
+ static outlets: string[];
8
+ static values: {
9
+ state: {
10
+ type: BooleanConstructor;
11
+ default: boolean;
12
+ };
13
+ closeOnOutsideClick: {
14
+ type: BooleanConstructor;
15
+ default: boolean;
16
+ };
17
+ syncedAttrs: ArrayConstructor;
18
+ antiAttrs: ArrayConstructor;
19
+ protectAttrs: BooleanConstructor;
20
+ outletEvents: ArrayConstructor;
21
+ };
22
+ stateValue: boolean;
23
+ readonly closeOnOutsideClickValue: boolean;
24
+ connect(): void;
25
+ toggle(event: Event, updateTo?: TOutletChangeData<boolean>): void;
26
+ on(event: Event): void;
27
+ off(event: Event): void;
28
+ clickOutside(event: Event): void;
29
+ getValueForElement(element: Element): boolean | null;
30
+ getElementsToSync(): Element[] | null | undefined;
31
+ getState(): boolean;
32
+ get event_key_postfix(): "on" | "off";
33
+ outletUpdate: (event: Event, updateTo?: TOutletChangeData<boolean>) => 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,10 @@
1
1
  import { Application } from '@hotwired/stimulus';
2
2
  import AriadneForm from './ariadne-form';
3
+ import StringMatchController from './string_match_controller/string_match_controller';
4
+ import EventsController from './events_controller/events_controller';
5
+ import OptionsController from './options_controller/options_controller';
6
+ import AccumulatorController from './accumulator_controller/accumulator_controller';
7
+ import ToggleableController from './toggleable_controller/toggleable_controller';
3
8
  import ClipboardCopyComponent from './clipboard_copy_component/clipboard-copy-component';
4
9
  import RichTextAreaComponent from './rich_text_area_component/rich-text-area-component';
5
10
  import SlideoverComponent from './slideover_component/slideover-component';
@@ -14,3 +19,8 @@ application.register('rich-text-area-component', RichTextAreaComponent);
14
19
  application.register('slideover-component', SlideoverComponent);
15
20
  application.register('tab-nav-component', TabNavComponent);
16
21
  application.register('tooltip-component', TooltipComponent);
22
+ application.register('toggleable', ToggleableController);
23
+ application.register('accumulator', AccumulatorController);
24
+ application.register('options', OptionsController);
25
+ application.register('string-match', StringMatchController);
26
+ application.register('events', EventsController);
@@ -2,6 +2,11 @@ import {Application} from '@hotwired/stimulus'
2
2
 
3
3
  import AriadneForm from './ariadne-form'
4
4
 
5
+ import StringMatchController from './string_match_controller/string_match_controller'
6
+ import EventsController from './events_controller/events_controller'
7
+ import OptionsController from './options_controller/options_controller'
8
+ import AccumulatorController from './accumulator_controller/accumulator_controller'
9
+ import ToggleableController from './toggleable_controller/toggleable_controller'
5
10
  import ClipboardCopyComponent from './clipboard_copy_component/clipboard-copy-component'
6
11
  import RichTextAreaComponent from './rich_text_area_component/rich-text-area-component'
7
12
  import SlideoverComponent from './slideover_component/slideover-component'
@@ -19,3 +24,8 @@ application.register('rich-text-area-component', RichTextAreaComponent)
19
24
  application.register('slideover-component', SlideoverComponent)
20
25
  application.register('tab-nav-component', TabNavComponent)
21
26
  application.register('tooltip-component', TooltipComponent)
27
+ application.register('toggleable', ToggleableController)
28
+ application.register('accumulator', AccumulatorController)
29
+ application.register('options', OptionsController)
30
+ application.register('string-match', StringMatchController)
31
+ application.register('events', EventsController)
@@ -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, scheme: @scheme, 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 %>