ariadne_view_components 0.0.48 → 0.0.49

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2 -0
  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/events_controller/events_controller.d.ts +4 -0
  6. data/app/assets/javascripts/components/ariadne/options_controller/options_controller.d.ts +30 -11
  7. data/app/assets/javascripts/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +42 -0
  8. data/app/assets/javascripts/components/ariadne/string_match_controller/string_match_controller.d.ts +27 -0
  9. data/app/assets/javascripts/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +44 -0
  10. data/app/assets/javascripts/components/ariadne/toggleable_controller/toggleable_controller.d.ts +17 -17
  11. data/app/components/ariadne/ariadne.js +4 -0
  12. data/app/components/ariadne/ariadne.ts +4 -0
  13. data/app/components/ariadne/close_button_component.html.erb +1 -1
  14. data/app/components/ariadne/close_button_component.rb +2 -1
  15. data/app/components/ariadne/combobox_component.html.erb +14 -0
  16. data/app/components/ariadne/combobox_component.rb +76 -0
  17. data/app/components/ariadne/events_controller/events_controller.d.ts +4 -0
  18. data/app/components/ariadne/events_controller/events_controller.js +6 -0
  19. data/app/components/ariadne/events_controller/events_controller.ts +7 -0
  20. data/app/components/ariadne/layout_component.html.erb +21 -0
  21. data/app/components/ariadne/layout_component.rb +69 -0
  22. data/app/components/ariadne/modal_component.html.erb +11 -0
  23. data/app/components/ariadne/modal_component.rb +88 -0
  24. data/app/components/ariadne/options_controller/options_controller.d.ts +30 -11
  25. data/app/components/ariadne/options_controller/options_controller.js +75 -27
  26. data/app/components/ariadne/options_controller/options_controller.ts +104 -29
  27. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +42 -0
  28. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.js +237 -0
  29. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.ts +278 -0
  30. data/app/components/ariadne/popover_component.html.erb +0 -1
  31. data/app/components/ariadne/show_more_button_component.html.erb +1 -1
  32. data/app/components/ariadne/string_match_controller/string_match_controller.d.ts +27 -0
  33. data/app/components/ariadne/string_match_controller/string_match_controller.js +51 -0
  34. data/app/components/ariadne/string_match_controller/string_match_controller.ts +64 -0
  35. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +44 -0
  36. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.js +153 -0
  37. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.ts +192 -0
  38. data/app/components/ariadne/toggleable_controller/toggleable_controller.d.ts +17 -17
  39. data/app/components/ariadne/toggleable_controller/toggleable_controller.js +35 -55
  40. data/app/components/ariadne/toggleable_controller/toggleable_controller.ts +41 -51
  41. data/lib/ariadne/view_components/version.rb +1 -1
  42. data/static/audited_at.json +3 -0
  43. data/static/constants.json +74 -0
  44. data/static/statuses.json +3 -0
  45. metadata +24 -2
@@ -0,0 +1,192 @@
1
+ import OutletManagerController from '../outlet_manager_controller/outlet_manager_controller'
2
+
3
+ export type TStimulusDispatchEvent<TDetails> = {
4
+ target?: Element | undefined
5
+ detail?: TDetails | undefined
6
+ prefix?: string | undefined
7
+ bubbles?: boolean | undefined
8
+ cancelable?: boolean | undefined
9
+ preventDefault: () => void
10
+ }
11
+
12
+ export type TBooleanValueDetail = {
13
+ value: boolean
14
+ }
15
+
16
+ export interface TSyncAttrDetail extends TBooleanValueDetail {
17
+ attr: string
18
+ }
19
+
20
+ /*
21
+ This class isn't used directly by itself because it has no functionality. What it does is establishes
22
+ "synced attrs" and "anti-attrs" so that other controllers can extend this one and not worry about
23
+ implementing the logic themselves (and thus have duplicate logic all over our controllers)
24
+
25
+ To implement this, extend your controller with "SyncedBooleanAttributesController" then spread its
26
+ values into your controllers then implement:
27
+
28
+ export default class MyNewController extends SyncedBooleanAttributesController {
29
+ static values = {
30
+ ...SyncedBooleanAttributesController.values,
31
+ myString: String,
32
+ }
33
+ }
34
+
35
+ Also, consider the functions defined here ABOVE the connection() function. Those functions will
36
+ give you control over how your controller can interact with other SyncedBooleanAttributeControllers.
37
+ Not every controller needs them but you should consider them (description can be found in the functions)
38
+
39
+ And don't forget that when you want to change an attr on an element, you should not do it manually.
40
+ Instead run:
41
+ this.updateAttributesForElement(element, value)
42
+ This will let you take advantage of the ecosystem created by this base controller without any additional work
43
+ */
44
+
45
+ export default class SyncedBooleanAttributesController<T> extends OutletManagerController<T> {
46
+ static values = {
47
+ ...OutletManagerController.values,
48
+ syncedAttrs: Array, // Set option target attrs to true/false in agreement with the option's selected state
49
+ antiAttrs: Array, // Set option target attrs to true/false opposite of the option's selected state
50
+ protectAttrs: Boolean, // If the controller should block other SyncedBooleanAttributesController from changing its defined attrs
51
+ }
52
+
53
+ declare readonly syncedAttrsValue: string[]
54
+ declare readonly hasSyncedAttrsValue: boolean
55
+ declare readonly antiAttrsValue: string[]
56
+ declare readonly hasAntiAttrsValue: boolean
57
+ declare readonly protectAttrsValue: boolean
58
+
59
+ // Some attributes are only false in HTML if they don't exist
60
+ // If included here, the property will be deleted on "false"
61
+ static removeOnFalseAttrs: {[k: string]: boolean} = {
62
+ checked: true,
63
+ }
64
+
65
+ syncedAttrsLookup: {[k: string]: boolean} | null = null
66
+ antiAttrsLookup: {[k: string]: boolean} | null = null
67
+
68
+ getValueForElement(element: Element): boolean | null {
69
+ // This function allows the base controller to access a given element's
70
+ // current status so the attributes can be set or compared. For example,
71
+ // you will want to make sure the attributes are added initially and are
72
+ // in sync with the controller's state. To ensure this, you can use the
73
+ // default connect() function or add "this.syncElementAttributes()" to your
74
+ // custom connect function. It'll look through your targets and get values for
75
+ // each then set the appropriate attrs and anti-attrs
76
+ return null
77
+ }
78
+
79
+ getElementsToSync(): Array<Element> | null | undefined {
80
+ // These are the elements your controller wants to keep in sync with the attrs
81
+ // Sometimes these are this.element, sometimes they're specific targets.
82
+ // Return them here so the base controller can automate some behaviors for you
83
+ return []
84
+ }
85
+
86
+ connect(): void {
87
+ // This function will sync attrs and anti-attrs when the controller connects.
88
+ // The logic is abstracted to a function so you can override this connect
89
+ // function in favor of your own without having to duplicate the sync logic
90
+ this.syncElementAttributes()
91
+ }
92
+
93
+ updateAttributesForElement(element: Element, value: boolean) {
94
+ // This is how you should update any synced or anti-synced attrs on your elements
95
+ // Do not do it manually unless you are very sure of what you're doing
96
+ if (this.hasSyncedAttrsValue) {
97
+ this.#setAttrs(element, this.syncedAttrsValue, value)
98
+ }
99
+
100
+ if (this.hasAntiAttrsValue) {
101
+ this.#setAttrs(element, this.antiAttrsValue, !value)
102
+ }
103
+ }
104
+
105
+ syncElementAttributes() {
106
+ this.syncOutlets()
107
+ // Essentially just a "sync attrs and anti-attrs on mount" function
108
+ const elements = this.getElementsToSync()
109
+
110
+ if (elements?.length) {
111
+ for (let index in elements) {
112
+ const element = elements[index]
113
+ const value = this.getValueForElement(element) ?? false
114
+ this.updateAttributesForElement(element, value)
115
+ }
116
+ }
117
+ }
118
+
119
+ validateAttrChange(dispatchEvent: TStimulusDispatchEvent<TSyncAttrDetail>) {
120
+ // If you protect your attrs, then this function will deny other controllers you specify from making changes to them.
121
+ // For example, if you want an item to disappear when it's selected, then your Options controller likely has an "aria-hidden"
122
+ // synced attr. If you use another attr to filter the list and then remove that filter, normally that would unhide your selected
123
+ // element. But if you have Options protect its attrs, the filter behavior won't be allowed to change it at any time and thus
124
+ // the element will remain hidden
125
+ const {target, detail} = dispatchEvent
126
+ if (target && detail) {
127
+ const currentValue = this.getValueForElement(target)
128
+ if (currentValue !== null && this.protectAttrsValue && this.#isAttr(detail.attr)) {
129
+ dispatchEvent.preventDefault()
130
+ }
131
+ }
132
+ }
133
+
134
+ #isSyncedAttr(attr: string) {
135
+ // Helper function to determine if the attr is synced
136
+ if (this.syncedAttrsLookup === null) {
137
+ this.syncedAttrsLookup = this.#getLookupForStringArray(this.syncedAttrsValue)
138
+ }
139
+
140
+ return this.syncedAttrsLookup[attr] ?? false
141
+ }
142
+
143
+ #isAntiAttr(attr: string) {
144
+ // Helper function to determine if the attr is anti-synced
145
+ if (this.antiAttrsLookup === null) {
146
+ this.antiAttrsLookup = this.#getLookupForStringArray(this.antiAttrsValue)
147
+ }
148
+
149
+ return this.antiAttrsLookup[attr] ?? false
150
+ }
151
+
152
+ #isAttr(attr: string) {
153
+ // Helper function to determine if an attr is known to a controller
154
+ return this.#isAntiAttr(attr) || this.#isSyncedAttr(attr)
155
+ }
156
+
157
+ #setAttrs(element: Element, attrs: string[], value: boolean) {
158
+ // Attempts to change the attr for an element. However, it'll dispatch an event
159
+ // first so other controllers get the opportunity to deny it
160
+ const attrState = JSON.stringify(value)
161
+ for (let index in attrs) {
162
+ const attr = attrs[index]
163
+
164
+ const dispatchEvent = this.dispatch('attrChange', {
165
+ target: element,
166
+ detail: {attr, value},
167
+ } as TStimulusDispatchEvent<TSyncAttrDetail>)
168
+
169
+ if (!dispatchEvent.defaultPrevented) {
170
+ if (attrState === 'false' && SyncedBooleanAttributesController.removeOnFalseAttrs[attr]) {
171
+ element.removeAttribute(attr)
172
+ } else {
173
+ element.setAttribute(attr, attrState)
174
+ }
175
+ }
176
+ }
177
+ }
178
+
179
+ #getLookupForStringArray(arr?: Array<string>) {
180
+ // Helper function to return an array of strings into an object for easy lookup
181
+ // While the arrays contained here are small, looking up attrs will happen often
182
+ // so I think it's worth the small sacrifice to memory
183
+ if (!arr?.length) {
184
+ return {}
185
+ }
186
+
187
+ return arr.reduce((acc, cur) => {
188
+ acc[cur] = true
189
+ return acc
190
+ }, {} as {[k: string]: boolean})
191
+ }
192
+ }
@@ -1,34 +1,34 @@
1
- import { Controller } from '@hotwired/stimulus';
2
- export interface ToggleableOutlet {
3
- toggle: (event: Event, value?: boolean) => void;
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;
4
5
  }
5
- export default class ToggleableController extends Controller implements ToggleableOutlet {
6
- #private;
6
+ export default class ToggleableController extends SyncedBooleanAttributesController<boolean> implements ToggleableOutlet {
7
7
  static outlets: string[];
8
8
  static values: {
9
9
  state: {
10
10
  type: BooleanConstructor;
11
11
  default: boolean;
12
12
  };
13
- syncedAttrs: ArrayConstructor;
14
- antiAttrs: ArrayConstructor;
15
13
  closeOnOutsideClick: {
16
14
  type: BooleanConstructor;
17
15
  default: boolean;
18
16
  };
19
- };
20
- static removeOnFalseAttrs: {
21
- [k: string]: boolean;
17
+ syncedAttrs: ArrayConstructor;
18
+ antiAttrs: ArrayConstructor;
19
+ protectAttrs: BooleanConstructor;
20
+ outletEvents: ArrayConstructor;
22
21
  };
23
22
  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
23
  readonly closeOnOutsideClickValue: boolean;
31
24
  connect(): void;
32
- toggle(event: Event, value?: boolean): void;
25
+ toggle(event: Event, updateTo?: TOutletChangeData<boolean>): void;
26
+ on(event: Event): void;
27
+ off(event: Event): void;
33
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
34
  }
@@ -1,74 +1,54 @@
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 _ToggleableController_instances, _ToggleableController_updateAllAttrs, _ToggleableController_setAttrs, _ToggleableController_updateOutlets;
7
- import { Controller } from '@hotwired/stimulus';
8
1
  import { useClickOutside } from 'stimulus-use';
9
- class ToggleableController extends Controller {
2
+ import SyncedBooleanAttributesController from '../synced_boolean_attributes_controller/synced_boolean_attributes_controller';
3
+ class ToggleableController extends SyncedBooleanAttributesController {
10
4
  constructor() {
11
5
  super(...arguments);
12
- _ToggleableController_instances.add(this);
6
+ this.outletUpdate = this.toggle;
13
7
  }
14
8
  connect() {
15
- __classPrivateFieldGet(this, _ToggleableController_instances, "m", _ToggleableController_updateAllAttrs).call(this);
16
- __classPrivateFieldGet(this, _ToggleableController_instances, "m", _ToggleableController_updateOutlets).call(this, new Event('Init'));
17
- useClickOutside(this, { dispatchEvent: this.closeOnOutsideClickValue });
9
+ this.syncElementAttributes();
10
+ useClickOutside(this, { dispatchEvent: this.closeOnOutsideClickValue && this.stateValue });
18
11
  }
19
- toggle(event, value) {
20
- this.stateValue = value !== null && value !== void 0 ? value : !this.stateValue;
21
- __classPrivateFieldGet(this, _ToggleableController_instances, "m", _ToggleableController_updateAllAttrs).call(this);
22
- __classPrivateFieldGet(this, _ToggleableController_instances, "m", _ToggleableController_updateOutlets).call(this, event);
12
+ toggle(event, updateTo = {}) {
13
+ var _a;
14
+ const v = (_a = updateTo.data) !== null && _a !== void 0 ? _a : !this.stateValue;
15
+ this.updateAttributesForElement(this.element, v);
16
+ this.stateValue = v;
17
+ this.sendToOutlets(event, Object.assign(Object.assign({}, updateTo), { data: v }));
18
+ }
19
+ on(event) {
20
+ this.toggle(event, { data: true });
21
+ }
22
+ off(event) {
23
+ this.toggle(event, { data: false });
23
24
  }
24
25
  clickOutside(event) {
25
- if (this.closeOnOutsideClickValue) {
26
- this.toggle(event, false);
26
+ if (this.closeOnOutsideClickValue && this.stateValue) {
27
+ this.toggle(event, { data: false });
27
28
  }
28
29
  }
29
- }
30
- _ToggleableController_instances = new WeakSet(), _ToggleableController_updateAllAttrs = function _ToggleableController_updateAllAttrs() {
31
- if (this.hasSyncedAttrsValue) {
32
- __classPrivateFieldGet(this, _ToggleableController_instances, "m", _ToggleableController_setAttrs).call(this, this.syncedAttrsValue);
30
+ getValueForElement(element) {
31
+ if (element !== this.element) {
32
+ return null;
33
+ }
34
+ return this.stateValue;
33
35
  }
34
- if (this.hasAntiAttrsValue) {
35
- __classPrivateFieldGet(this, _ToggleableController_instances, "m", _ToggleableController_setAttrs).call(this, this.antiAttrsValue, false);
36
+ getElementsToSync() {
37
+ return [this.element];
36
38
  }
37
- }, _ToggleableController_setAttrs = function _ToggleableController_setAttrs(attrs, matchState = true) {
38
- const attrState = String(matchState ? this.stateValue : !this.stateValue);
39
- for (let index in attrs) {
40
- const attr = attrs[index];
41
- if (attrState === 'false' && ToggleableController.removeOnFalseAttrs[attr]) {
42
- this.element.removeAttribute(attr);
43
- }
44
- else {
45
- this.element.setAttribute(attr, attrState);
46
- }
39
+ getState() {
40
+ return this.stateValue;
47
41
  }
48
- }, _ToggleableController_updateOutlets = function _ToggleableController_updateOutlets(event) {
49
- if (this.hasToggleableOutlet) {
50
- for (let index in this.toggleableOutlets) {
51
- const outlet = this.toggleableOutlets[index];
52
- outlet.toggle(event, this.stateValue);
53
- }
42
+ get event_key_postfix() {
43
+ return this.stateValue ? 'on' : 'off';
54
44
  }
55
- };
56
- ToggleableController.outlets = ['toggleable'];
57
- ToggleableController.values = {
58
- state: {
45
+ }
46
+ ToggleableController.outlets = SyncedBooleanAttributesController.outlets;
47
+ ToggleableController.values = Object.assign(Object.assign({}, SyncedBooleanAttributesController.values), { state: {
59
48
  type: Boolean,
60
49
  default: false,
61
- },
62
- syncedAttrs: Array,
63
- antiAttrs: Array,
64
- closeOnOutsideClick: {
50
+ }, closeOnOutsideClick: {
65
51
  type: Boolean,
66
52
  default: false,
67
- },
68
- };
69
- // Some attributes are only false in HTML if they don't exist
70
- // If included here, the property will be deleted on "false"
71
- ToggleableController.removeOnFalseAttrs = {
72
- checked: true,
73
- };
53
+ } });
74
54
  export default ToggleableController;
@@ -1,87 +1,77 @@
1
- import {Controller} from '@hotwired/stimulus'
1
+ import type {TOutletChangeData} from '../outlet_manager_controller/outlet_manager_controller'
2
2
  import {useClickOutside} from 'stimulus-use'
3
+ import SyncedBooleanAttributesController from '../synced_boolean_attributes_controller/synced_boolean_attributes_controller'
3
4
 
4
- export interface ToggleableOutlet {
5
- toggle: (event: Event, value?: boolean) => void
5
+ export interface ToggleableOutlet extends SyncedBooleanAttributesController<boolean> {
6
+ toggle: (event: Event, updateTo?: TOutletChangeData<boolean>) => void
6
7
  }
7
8
 
8
- export default class ToggleableController extends Controller implements ToggleableOutlet {
9
- static outlets = ['toggleable']
9
+ export default class ToggleableController
10
+ extends SyncedBooleanAttributesController<boolean>
11
+ implements ToggleableOutlet
12
+ {
13
+ static outlets = SyncedBooleanAttributesController.outlets
10
14
  static values = {
15
+ ...SyncedBooleanAttributesController.values,
11
16
  state: {
12
17
  type: Boolean,
13
18
  default: false,
14
19
  },
15
- syncedAttrs: Array,
16
- antiAttrs: Array,
17
20
  closeOnOutsideClick: {
18
21
  type: Boolean,
19
22
  default: false,
20
23
  },
21
24
  }
22
25
 
23
- // Some attributes are only false in HTML if they don't exist
24
- // If included here, the property will be deleted on "false"
25
- static removeOnFalseAttrs: {[k: string]: boolean} = {
26
- checked: true,
27
- }
28
-
29
26
  declare stateValue: boolean
30
- declare readonly toggleableOutlets: Array<ToggleableOutlet>
31
- declare readonly hasToggleableOutlet: boolean
32
- declare readonly syncedAttrsValue: string[]
33
- declare readonly hasSyncedAttrsValue: boolean
34
- declare readonly antiAttrsValue: string[]
35
- declare readonly hasAntiAttrsValue: boolean
36
27
  declare readonly closeOnOutsideClickValue: boolean
37
28
 
38
29
  connect(): void {
39
- this.#updateAllAttrs()
40
- this.#updateOutlets(new Event('Init'))
41
- useClickOutside(this, {dispatchEvent: this.closeOnOutsideClickValue})
30
+ this.syncElementAttributes()
31
+ useClickOutside(this, {dispatchEvent: this.closeOnOutsideClickValue && this.stateValue})
32
+ }
33
+
34
+ toggle(event: Event, updateTo: TOutletChangeData<boolean> = {}) {
35
+ const v = updateTo.data ?? !this.stateValue
36
+
37
+ this.updateAttributesForElement(this.element, v)
38
+ this.stateValue = v
39
+ this.sendToOutlets(event, {...updateTo, data: v})
42
40
  }
43
41
 
44
- toggle(event: Event, value?: boolean) {
45
- this.stateValue = value ?? !this.stateValue
42
+ on(event: Event) {
43
+ this.toggle(event, {data: true})
44
+ }
46
45
 
47
- this.#updateAllAttrs()
48
- this.#updateOutlets(event)
46
+ off(event: Event) {
47
+ this.toggle(event, {data: false})
49
48
  }
50
49
 
51
50
  clickOutside(event: Event) {
52
- if (this.closeOnOutsideClickValue) {
53
- this.toggle(event, false)
51
+ if (this.closeOnOutsideClickValue && this.stateValue) {
52
+ this.toggle(event, {data: false})
54
53
  }
55
54
  }
56
55
 
57
- #updateAllAttrs() {
58
- if (this.hasSyncedAttrsValue) {
59
- this.#setAttrs(this.syncedAttrsValue)
56
+ getValueForElement(element: Element): boolean | null {
57
+ if (element !== this.element) {
58
+ return null
60
59
  }
61
60
 
62
- if (this.hasAntiAttrsValue) {
63
- this.#setAttrs(this.antiAttrsValue, false)
64
- }
61
+ return this.stateValue
65
62
  }
66
63
 
67
- #setAttrs(attrs: string[], matchState = true) {
68
- const attrState = String(matchState ? this.stateValue : !this.stateValue)
69
- for (let index in attrs) {
70
- const attr = attrs[index]
71
- if (attrState === 'false' && ToggleableController.removeOnFalseAttrs[attr]) {
72
- this.element.removeAttribute(attr)
73
- } else {
74
- this.element.setAttribute(attr, attrState)
75
- }
76
- }
64
+ getElementsToSync(): Element[] | null | undefined {
65
+ return [this.element]
77
66
  }
78
67
 
79
- #updateOutlets(event: Event) {
80
- if (this.hasToggleableOutlet) {
81
- for (let index in this.toggleableOutlets) {
82
- const outlet = this.toggleableOutlets[index]
83
- outlet.toggle(event, this.stateValue)
84
- }
85
- }
68
+ getState() {
69
+ return this.stateValue
86
70
  }
71
+
72
+ get event_key_postfix() {
73
+ return this.stateValue ? 'on' : 'off'
74
+ }
75
+
76
+ outletUpdate = this.toggle
87
77
  }
@@ -3,6 +3,6 @@
3
3
  # :nocov:
4
4
  module Ariadne
5
5
  module ViewComponents
6
- VERSION = "0.0.48"
6
+ VERSION = "0.0.49"
7
7
  end
8
8
  end
@@ -13,6 +13,7 @@
13
13
  "Ariadne::CheckboxComponent": "",
14
14
  "Ariadne::ClipboardCopyComponent": "",
15
15
  "Ariadne::CloseButtonComponent": "",
16
+ "Ariadne::ComboboxComponent": "",
16
17
  "Ariadne::CommentComponent": "",
17
18
  "Ariadne::ContainerComponent": "",
18
19
  "Ariadne::Content": "",
@@ -31,9 +32,11 @@
31
32
  "Ariadne::HeroiconComponent": "",
32
33
  "Ariadne::ImageComponent": "",
33
34
  "Ariadne::InlineFlexComponent": "",
35
+ "Ariadne::LayoutComponent": "",
34
36
  "Ariadne::LinkComponent": "",
35
37
  "Ariadne::ListComponent": "",
36
38
  "Ariadne::ListComponent::ListItem": "",
39
+ "Ariadne::ModalComponent": "",
37
40
  "Ariadne::NarrowContainerComponent": "",
38
41
  "Ariadne::PanelBarComponent": "",
39
42
  "Ariadne::PanelBarComponent::PanelItem": "",
@@ -214,6 +214,30 @@
214
214
  "button"
215
215
  ]
216
216
  },
217
+ "Ariadne::ComboboxComponent": {
218
+ "DEFAULT_ATTRIBUTES": {
219
+ "wrapper": {
220
+ "data-controller": "options toggleable string-match"
221
+ },
222
+ "options_wrapper": {
223
+ },
224
+ "input": {
225
+ "type": "text",
226
+ "autocomplete": "off",
227
+ "data-action": "input->string-match#change focusin->toggleable#on"
228
+ }
229
+ },
230
+ "DEFAULT_CLASSES": {
231
+ "wrapper": "ariadne-group ariadne-w-fit ariadne-relative",
232
+ "options_wrapper": "group-data-[toggleable-state-value=false]:ariadne-hidden ariadne-absolute ariadne-w-full ariadne-z-10",
233
+ "input": ""
234
+ },
235
+ "DEFAULT_OPTIONS_WRAPPER_TAG": "div",
236
+ "DEFAULT_TAG": "div",
237
+ "TAG_OPTIONS": [
238
+ "div"
239
+ ]
240
+ },
217
241
  "Ariadne::CommentComponent": {
218
242
  "DEFAULT_CLASSES": "ariadne-border-gray-300 ariadne-border ariadne-shadow ariadne-py-5 ariadne-px-5 ariadne-rounded-md ",
219
243
  "DEFAULT_TAG": "div",
@@ -496,6 +520,28 @@
496
520
  "open"
497
521
  ]
498
522
  },
523
+ "Ariadne::LayoutComponent": {
524
+ "DEFAULT_ASIDE_TAG": "div",
525
+ "DEFAULT_ATTRIBUTES": {
526
+ "wrapper": {
527
+ },
528
+ "sidecar": {
529
+ },
530
+ "main": {
531
+ },
532
+ "aside": {
533
+ }
534
+ },
535
+ "DEFAULT_CLASSES": {
536
+ "wrapper": "ariadne-group ariadne-flex ariadne-gap-2 ariadne-flex-col md:ariadne-flex-row",
537
+ "sidecar": "ariadne-w-full md:ariadne-w-1/6",
538
+ "main": "ariadne-grow",
539
+ "aside": "ariadne-w-full md:ariadne-w-1/6"
540
+ },
541
+ "DEFAULT_MAIN_TAG": "div",
542
+ "DEFAULT_SIDECAR_TAG": "div",
543
+ "DEFAULT_TAG": "div"
544
+ },
499
545
  "Ariadne::LinkComponent": {
500
546
  "DEFAULT_ACTIONABLE_CLASSES": "ariadne-cursor-pointer ariadne-font-semibold ariadne-underline ariadne-decoration-double",
501
547
  "DEFAULT_CLASSES": "ariadne-cursor-pointer hover:ariadne-text-button-text-color focus:ariadne-outline-none focus:ariadne-ring-2 focus:ariadne-ring-offset-2 focus:ariadne-ring-purple-500",
@@ -513,6 +559,34 @@
513
559
  "Ariadne::ListComponent::ListItem": {
514
560
  "DEFAULT_ITEM_CLASSES": "ariadne-relative ariadne-p-1.5 focus:ariadne-ring-2 focus:ariadne-ring-offset-2 focus:ariadne-ring-purple-500 hover:ariadne-bg-button-hover-color"
515
561
  },
562
+ "Ariadne::ModalComponent": {
563
+ "DEFAULT_ATTRIBUTES": {
564
+ "wrapper": {
565
+ "data-controller": "toggleable",
566
+ "data-action": "click->toggleable#toggle",
567
+ "data-toggleable-anti-attrs-value": "[\"aria-hidden\"]"
568
+ },
569
+ "shadow": {
570
+ },
571
+ "content": {
572
+ "role": "dialog"
573
+ },
574
+ "close_button": {
575
+ }
576
+ },
577
+ "DEFAULT_CLASSES": {
578
+ "wrapper": "ariadne-group",
579
+ "shadow": "ariadne-w-screen ariadne-h-screen ariadne-bg-black/20 ariadne-fixed ariadne-top-0 ariadne-left-0 ariadne-flex ariadne-justify-center ariadne-items-center data-[close-on-click=true]:ariadne-cursor-pointer",
580
+ "content": "ariadne-bg-white ariadne-p-2 ariadne-relative ariadne-cursor-default",
581
+ "close_button": "ariadne-absolute ariadne-right-2 ariadne-pt-1 ariadne-pb-1 ariadne-pl-1 ariadne-pr-1"
582
+ },
583
+ "DEFAULT_SHADOW_TAG": "div",
584
+ "DEFAULT_TAG": "div",
585
+ "SHADOW_VISIBILITY_CLASSES": "group-aria-hidden:ariadne-hidden",
586
+ "TAG_OPTIONS": [
587
+ "div"
588
+ ]
589
+ },
516
590
  "Ariadne::NarrowContainerComponent": {
517
591
  "DEFAULT_CLASSES": "ariadne-max-w-7xl ariadne-mx-auto ariadne-py-12 ariadne-px-4 sm:ariadne-px-6 lg:ariadne-py-16 lg:ariadne-px-8",
518
592
  "DEFAULT_TAG": "div",
data/static/statuses.json CHANGED
@@ -13,6 +13,7 @@
13
13
  "Ariadne::CheckboxComponent": "stable",
14
14
  "Ariadne::ClipboardCopyComponent": "stable",
15
15
  "Ariadne::CloseButtonComponent": "stable",
16
+ "Ariadne::ComboboxComponent": "stable",
16
17
  "Ariadne::CommentComponent": "stable",
17
18
  "Ariadne::ContainerComponent": "stable",
18
19
  "Ariadne::Content": "stable",
@@ -31,9 +32,11 @@
31
32
  "Ariadne::HeroiconComponent": "stable",
32
33
  "Ariadne::ImageComponent": "stable",
33
34
  "Ariadne::InlineFlexComponent": "stable",
35
+ "Ariadne::LayoutComponent": "stable",
34
36
  "Ariadne::LinkComponent": "stable",
35
37
  "Ariadne::ListComponent": "stable",
36
38
  "Ariadne::ListComponent::ListItem": "stable",
39
+ "Ariadne::ModalComponent": "stable",
37
40
  "Ariadne::NarrowContainerComponent": "stable",
38
41
  "Ariadne::PanelBarComponent": "stable",
39
42
  "Ariadne::PanelBarComponent::PanelItem": "stable",