ariadne_view_components 0.0.47-x86_64-darwin → 0.0.49-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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -25
- data/app/assets/javascripts/ariadne_view_components.js +2 -2
- data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
- data/app/assets/javascripts/components/ariadne/accumulator_controller/accumulator_controller.d.ts +22 -0
- data/app/assets/javascripts/components/ariadne/dropdown/menu_component.d.ts +1 -0
- data/app/assets/javascripts/components/ariadne/events_controller/events_controller.d.ts +4 -0
- data/app/assets/javascripts/components/ariadne/options_controller/options_controller.d.ts +40 -0
- data/app/assets/javascripts/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +42 -0
- data/app/assets/javascripts/components/ariadne/string_match_controller/string_match_controller.d.ts +27 -0
- data/app/assets/javascripts/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +44 -0
- data/app/assets/javascripts/components/ariadne/toggleable_controller/toggleable_controller.d.ts +34 -0
- data/app/assets/stylesheets/ariadne_view_components.css +3 -3
- data/app/components/ariadne/accumulator_controller/accumulator_controller.d.ts +22 -0
- data/app/components/ariadne/accumulator_controller/accumulator_controller.js +39 -0
- data/app/components/ariadne/accumulator_controller/accumulator_controller.ts +48 -0
- data/app/components/ariadne/action_card_component.html.erb +11 -0
- data/app/components/ariadne/action_card_component.rb +45 -0
- data/app/components/ariadne/ariadne.js +10 -0
- data/app/components/ariadne/ariadne.ts +10 -0
- data/app/components/ariadne/bottom_tab_component.html.erb +4 -0
- data/app/components/ariadne/bottom_tab_component.rb +44 -0
- data/app/components/ariadne/bottom_tab_nav_component.html.erb +5 -0
- data/app/components/ariadne/bottom_tab_nav_component.rb +33 -0
- data/app/components/ariadne/breadcrumbs_component.html.erb +13 -0
- data/app/components/ariadne/breadcrumbs_component.rb +31 -0
- data/app/components/ariadne/checkbox_component.html.erb +5 -0
- data/app/components/ariadne/checkbox_component.rb +43 -0
- data/app/components/ariadne/close_button_component.html.erb +4 -0
- data/app/components/ariadne/close_button_component.rb +33 -0
- data/app/components/ariadne/combobox_component.html.erb +14 -0
- data/app/components/ariadne/combobox_component.rb +76 -0
- data/app/components/ariadne/dropdown/menu_component.d.ts +1 -0
- data/app/components/ariadne/dropdown/menu_component.js +1 -0
- data/app/components/ariadne/events_controller/events_controller.d.ts +4 -0
- data/app/components/ariadne/events_controller/events_controller.js +6 -0
- data/app/components/ariadne/events_controller/events_controller.ts +7 -0
- data/app/components/ariadne/layout_component.html.erb +21 -0
- data/app/components/ariadne/layout_component.rb +69 -0
- data/app/components/ariadne/modal_component.html.erb +11 -0
- data/app/components/ariadne/modal_component.rb +88 -0
- data/app/components/ariadne/options_controller/options_controller.d.ts +40 -0
- data/app/components/ariadne/options_controller/options_controller.js +98 -0
- data/app/components/ariadne/options_controller/options_controller.ts +132 -0
- data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +42 -0
- data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.js +237 -0
- data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.ts +278 -0
- data/app/components/ariadne/popover_component.html.erb +10 -0
- data/app/components/ariadne/popover_component.rb +81 -0
- data/app/components/ariadne/progress_bar_component.html.erb +5 -0
- data/app/components/ariadne/progress_bar_component.rb +63 -0
- data/app/components/ariadne/relative_time_component.html.erb +3 -0
- data/app/components/ariadne/relative_time_component.rb +61 -0
- data/app/components/ariadne/show_more_button_component.html.erb +11 -0
- data/app/components/ariadne/show_more_button_component.rb +47 -0
- data/app/components/ariadne/spinner_component.html.erb +16 -0
- data/app/components/ariadne/spinner_component.rb +45 -0
- data/app/components/ariadne/string_match_controller/string_match_controller.d.ts +27 -0
- data/app/components/ariadne/string_match_controller/string_match_controller.js +51 -0
- data/app/components/ariadne/string_match_controller/string_match_controller.ts +64 -0
- data/app/components/ariadne/subheader_component.html.erb +11 -0
- data/app/components/ariadne/subheader_component.rb +65 -0
- data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +44 -0
- data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.js +153 -0
- data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.ts +192 -0
- data/app/components/ariadne/toggle_component/toggle_component.html.erb +15 -0
- data/app/components/ariadne/toggle_component.rb +95 -0
- data/app/components/ariadne/toggleable_controller/toggleable_controller.d.ts +34 -0
- data/app/components/ariadne/toggleable_controller/toggleable_controller.js +54 -0
- data/app/components/ariadne/toggleable_controller/toggleable_controller.ts +77 -0
- data/lib/ariadne/view_components/version.rb +1 -1
- data/static/arguments.yml +50 -0
- data/static/audited_at.json +17 -0
- data/static/classes.yml +209 -173
- data/static/constants.json +356 -0
- data/static/statuses.json +17 -0
- data/tailwind.config.js +7 -7
- metadata +75 -12
- /data/app/assets/javascripts/{ariadne-form.d.ts → components/ariadne/ariadne-form.d.ts} +0 -0
- /data/app/assets/javascripts/{ariadne.d.ts → components/ariadne/ariadne.d.ts} +0 -0
- /data/app/assets/javascripts/{clipboard_copy_component → components/ariadne/clipboard_copy_component}/clipboard-copy-component.d.ts +0 -0
- /data/app/assets/javascripts/{rich_text_area_component → components/ariadne/rich_text_area_component}/rich-text-area-component.d.ts +0 -0
- /data/app/assets/javascripts/{slideover_component → components/ariadne/slideover_component}/slideover-component.d.ts +0 -0
- /data/app/assets/javascripts/{tab_container_component → components/ariadne/tab_container_component}/tab-container-component.d.ts +0 -0
- /data/app/assets/javascripts/{tab_nav_component → components/ariadne/tab_nav_component}/tab-nav-component.d.ts +0 -0
- /data/app/assets/javascripts/{time_ago_component → components/ariadne/time_ago_component}/time-ago-component.d.ts +0 -0
- /data/app/assets/javascripts/{tooltip_component → components/ariadne/tooltip_component}/tooltip-component.d.ts +0 -0
@@ -0,0 +1,237 @@
|
|
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 _OutletManagerController_instances, _OutletManagerController_outlets_get;
|
7
|
+
import { Controller } from '@hotwired/stimulus';
|
8
|
+
class OutletManagerController extends Controller {
|
9
|
+
constructor() {
|
10
|
+
super(...arguments);
|
11
|
+
_OutletManagerController_instances.add(this);
|
12
|
+
this.outletEventsLookup = null;
|
13
|
+
this.eventRecords = new Map();
|
14
|
+
}
|
15
|
+
getOutlets() {
|
16
|
+
return null;
|
17
|
+
}
|
18
|
+
outletUpdate(event, data) { }
|
19
|
+
getState() {
|
20
|
+
return null;
|
21
|
+
}
|
22
|
+
connect() {
|
23
|
+
this.syncOutlets();
|
24
|
+
}
|
25
|
+
syncOutlets() {
|
26
|
+
const event = new Event('init');
|
27
|
+
this.sendToOutlets(event, {
|
28
|
+
data: this.getState(),
|
29
|
+
eventKey: this.getEventKey(event),
|
30
|
+
});
|
31
|
+
}
|
32
|
+
sendToOutlets(event, updateTo = {}) {
|
33
|
+
var _a;
|
34
|
+
const eventKey = (_a = updateTo.eventKey) !== null && _a !== void 0 ? _a : this.getEventKey(event);
|
35
|
+
const outlets = __classPrivateFieldGet(this, _OutletManagerController_instances, "a", _OutletManagerController_outlets_get);
|
36
|
+
if (outlets === null || outlets === void 0 ? void 0 : outlets.length) {
|
37
|
+
for (const index in outlets) {
|
38
|
+
const outlet = outlets[index];
|
39
|
+
if (outlet.isListeningForOutletEvent(eventKey) && !this.hasHeardEvent(event)) {
|
40
|
+
const isSameControllerType = this.identifier === outlet.identifier;
|
41
|
+
outlet.outletUpdate(event, { eventKey, data: isSameControllerType ? updateTo.data : undefined });
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
isListeningForOutletEvent(eventTypes) {
|
47
|
+
const eventTypeNames = eventTypes.split('-');
|
48
|
+
if (!eventTypeNames.length) {
|
49
|
+
return false;
|
50
|
+
}
|
51
|
+
let lookup = this.outletEvents;
|
52
|
+
for (let i = 0; i < eventTypeNames.length; i++) {
|
53
|
+
const name = eventTypeNames[i];
|
54
|
+
if (typeof lookup === 'boolean') {
|
55
|
+
return lookup;
|
56
|
+
}
|
57
|
+
const hasWildCard = lookup['*'] !== undefined;
|
58
|
+
let nextKey = name;
|
59
|
+
if (hasWildCard) {
|
60
|
+
nextKey = '*';
|
61
|
+
}
|
62
|
+
else {
|
63
|
+
const isListeningForDOMEvent = lookup.domEvent !== undefined;
|
64
|
+
if (isListeningForDOMEvent && !this.isDOMEventName(name)) {
|
65
|
+
return false;
|
66
|
+
}
|
67
|
+
else if (isListeningForDOMEvent) {
|
68
|
+
nextKey = 'domEvent';
|
69
|
+
}
|
70
|
+
}
|
71
|
+
if (!lookup[nextKey]) {
|
72
|
+
return false;
|
73
|
+
}
|
74
|
+
lookup = lookup[nextKey];
|
75
|
+
}
|
76
|
+
return true;
|
77
|
+
}
|
78
|
+
isDOMEventName(eventName) {
|
79
|
+
return OutletManagerController.domEvents[eventName];
|
80
|
+
}
|
81
|
+
getEventKey(event) {
|
82
|
+
const pre = this.event_key_prefix;
|
83
|
+
const post = this.event_key_postfix;
|
84
|
+
const maybePreHyphen = pre ? '-' : '';
|
85
|
+
const maybePrefix = pre !== null && pre !== void 0 ? pre : '';
|
86
|
+
const maybePostHyphen = post ? '-' : '';
|
87
|
+
const maybePostfix = post !== null && post !== void 0 ? post : '';
|
88
|
+
return `${this.identifier}-${maybePrefix}${maybePreHyphen}${event.type}${maybePostHyphen}${maybePostfix}`;
|
89
|
+
}
|
90
|
+
hasHeardEvent(event) {
|
91
|
+
if (this.eventRecords.has(event)) {
|
92
|
+
return true;
|
93
|
+
}
|
94
|
+
this.eventRecords.set(event, true);
|
95
|
+
setTimeout(() => this.eventRecords.delete(event));
|
96
|
+
return false;
|
97
|
+
}
|
98
|
+
get event_key_prefix() {
|
99
|
+
return '';
|
100
|
+
}
|
101
|
+
get event_key_postfix() {
|
102
|
+
return '';
|
103
|
+
}
|
104
|
+
get outletEvents() {
|
105
|
+
if (!this.outletEventsLookup && this.hasOutletEventsValue) {
|
106
|
+
this.outletEventsLookup = this.outletEventsValue.reduce((acc, eventType) => {
|
107
|
+
let step = acc;
|
108
|
+
eventType.split('-').forEach((eventTypeName, i, splitArr) => {
|
109
|
+
if (typeof step === 'boolean') {
|
110
|
+
return;
|
111
|
+
}
|
112
|
+
if (i === splitArr.length - 1) {
|
113
|
+
step[eventTypeName] = true;
|
114
|
+
}
|
115
|
+
else if (step[eventTypeName] === undefined) {
|
116
|
+
step[eventTypeName] = {};
|
117
|
+
}
|
118
|
+
step = step[eventTypeName];
|
119
|
+
});
|
120
|
+
return acc;
|
121
|
+
}, {});
|
122
|
+
}
|
123
|
+
else if (!this.outletEventsLookup) {
|
124
|
+
this.outletEventsLookup = { '*': true };
|
125
|
+
}
|
126
|
+
return this.outletEventsLookup;
|
127
|
+
}
|
128
|
+
}
|
129
|
+
_OutletManagerController_instances = new WeakSet(), _OutletManagerController_outlets_get = function _OutletManagerController_outlets_get() {
|
130
|
+
const outlets = this.getOutlets();
|
131
|
+
if (outlets) {
|
132
|
+
return outlets;
|
133
|
+
}
|
134
|
+
const defaultOutlets = [];
|
135
|
+
if (this.hasToggleableOutlet) {
|
136
|
+
defaultOutlets.push(...this.toggleableOutlets);
|
137
|
+
}
|
138
|
+
if (this.hasOptionsOutlet) {
|
139
|
+
defaultOutlets.push(...this.optionsOutlets);
|
140
|
+
}
|
141
|
+
if (this.hasStringMatchOutlet) {
|
142
|
+
defaultOutlets.push(...this.stringMatchOutlets);
|
143
|
+
}
|
144
|
+
return defaultOutlets;
|
145
|
+
};
|
146
|
+
OutletManagerController.values = {
|
147
|
+
outletEvents: Array,
|
148
|
+
};
|
149
|
+
OutletManagerController.outlets = ['toggleable', 'options', 'string-match'];
|
150
|
+
OutletManagerController.domEvents = {
|
151
|
+
abort: true,
|
152
|
+
afterprint: true,
|
153
|
+
animationend: true,
|
154
|
+
animationiteration: true,
|
155
|
+
animationstart: true,
|
156
|
+
beforeprint: true,
|
157
|
+
beforeunload: true,
|
158
|
+
blur: true,
|
159
|
+
canplay: true,
|
160
|
+
canplaythrough: true,
|
161
|
+
change: true,
|
162
|
+
click: true,
|
163
|
+
contextmenu: true,
|
164
|
+
copy: true,
|
165
|
+
cut: true,
|
166
|
+
dblclick: true,
|
167
|
+
drag: true,
|
168
|
+
dragend: true,
|
169
|
+
dragenter: true,
|
170
|
+
dragleave: true,
|
171
|
+
dragover: true,
|
172
|
+
dragstart: true,
|
173
|
+
drop: true,
|
174
|
+
durationchange: true,
|
175
|
+
ended: true,
|
176
|
+
error: true,
|
177
|
+
focus: true,
|
178
|
+
focusin: true,
|
179
|
+
focusout: true,
|
180
|
+
fullscreenchange: true,
|
181
|
+
fullscreenerror: true,
|
182
|
+
hashchange: true,
|
183
|
+
input: true,
|
184
|
+
invalid: true,
|
185
|
+
keydown: true,
|
186
|
+
keypress: true,
|
187
|
+
keyup: true,
|
188
|
+
load: true,
|
189
|
+
loadeddata: true,
|
190
|
+
loadedmetadata: true,
|
191
|
+
loadstart: true,
|
192
|
+
message: true,
|
193
|
+
mousedown: true,
|
194
|
+
mouseenter: true,
|
195
|
+
mouseleave: true,
|
196
|
+
mousemove: true,
|
197
|
+
mouseover: true,
|
198
|
+
mouseout: true,
|
199
|
+
mouseup: true,
|
200
|
+
mousewheel: true,
|
201
|
+
offline: true,
|
202
|
+
online: true,
|
203
|
+
open: true,
|
204
|
+
pagehide: true,
|
205
|
+
pageshow: true,
|
206
|
+
paste: true,
|
207
|
+
pause: true,
|
208
|
+
play: true,
|
209
|
+
playing: true,
|
210
|
+
popstate: true,
|
211
|
+
progress: true,
|
212
|
+
ratechange: true,
|
213
|
+
resize: true,
|
214
|
+
reset: true,
|
215
|
+
scroll: true,
|
216
|
+
search: true,
|
217
|
+
seeked: true,
|
218
|
+
seeking: true,
|
219
|
+
select: true,
|
220
|
+
show: true,
|
221
|
+
stalled: true,
|
222
|
+
storage: true,
|
223
|
+
submit: true,
|
224
|
+
suspend: true,
|
225
|
+
timeupdate: true,
|
226
|
+
toggle: true,
|
227
|
+
touchcancel: true,
|
228
|
+
touchend: true,
|
229
|
+
touchmove: true,
|
230
|
+
touchstart: true,
|
231
|
+
transitionend: true,
|
232
|
+
unload: true,
|
233
|
+
volumechange: true,
|
234
|
+
waiting: true,
|
235
|
+
wheel: true,
|
236
|
+
};
|
237
|
+
export default OutletManagerController;
|
@@ -0,0 +1,278 @@
|
|
1
|
+
import {Controller} from '@hotwired/stimulus'
|
2
|
+
|
3
|
+
type TOutletEventLookup = boolean | {[k: string]: TOutletEventLookup}
|
4
|
+
|
5
|
+
export type TOutletChangeData<T> =
|
6
|
+
| {
|
7
|
+
eventKey?: string
|
8
|
+
data?: T
|
9
|
+
}
|
10
|
+
| undefined
|
11
|
+
|
12
|
+
export default class OutletManagerController<T> extends Controller {
|
13
|
+
static values = {
|
14
|
+
outletEvents: Array,
|
15
|
+
}
|
16
|
+
|
17
|
+
declare readonly outletEventsValue: Array<string>
|
18
|
+
declare readonly hasOutletEventsValue: boolean
|
19
|
+
|
20
|
+
static outlets = ['toggleable', 'options', 'string-match']
|
21
|
+
declare readonly toggleableOutlets: Array<OutletManagerController<T>>
|
22
|
+
declare readonly hasToggleableOutlet: boolean
|
23
|
+
declare readonly optionsOutlets: Array<OutletManagerController<T>>
|
24
|
+
declare readonly hasOptionsOutlet: boolean
|
25
|
+
declare readonly stringMatchOutlets: Array<OutletManagerController<T>>
|
26
|
+
declare readonly hasStringMatchOutlet: boolean
|
27
|
+
|
28
|
+
outletEventsLookup: TOutletEventLookup | null = null
|
29
|
+
|
30
|
+
static domEvents: {[k: string]: boolean} = {
|
31
|
+
abort: true,
|
32
|
+
afterprint: true,
|
33
|
+
animationend: true,
|
34
|
+
animationiteration: true,
|
35
|
+
animationstart: true,
|
36
|
+
beforeprint: true,
|
37
|
+
beforeunload: true,
|
38
|
+
blur: true,
|
39
|
+
canplay: true,
|
40
|
+
canplaythrough: true,
|
41
|
+
change: true,
|
42
|
+
click: true,
|
43
|
+
contextmenu: true,
|
44
|
+
copy: true,
|
45
|
+
cut: true,
|
46
|
+
dblclick: true,
|
47
|
+
drag: true,
|
48
|
+
dragend: true,
|
49
|
+
dragenter: true,
|
50
|
+
dragleave: true,
|
51
|
+
dragover: true,
|
52
|
+
dragstart: true,
|
53
|
+
drop: true,
|
54
|
+
durationchange: true,
|
55
|
+
ended: true,
|
56
|
+
error: true,
|
57
|
+
focus: true,
|
58
|
+
focusin: true,
|
59
|
+
focusout: true,
|
60
|
+
fullscreenchange: true,
|
61
|
+
fullscreenerror: true,
|
62
|
+
hashchange: true,
|
63
|
+
input: true,
|
64
|
+
invalid: true,
|
65
|
+
keydown: true,
|
66
|
+
keypress: true,
|
67
|
+
keyup: true,
|
68
|
+
load: true,
|
69
|
+
loadeddata: true,
|
70
|
+
loadedmetadata: true,
|
71
|
+
loadstart: true,
|
72
|
+
message: true,
|
73
|
+
mousedown: true,
|
74
|
+
mouseenter: true,
|
75
|
+
mouseleave: true,
|
76
|
+
mousemove: true,
|
77
|
+
mouseover: true,
|
78
|
+
mouseout: true,
|
79
|
+
mouseup: true,
|
80
|
+
mousewheel: true,
|
81
|
+
offline: true,
|
82
|
+
online: true,
|
83
|
+
open: true,
|
84
|
+
pagehide: true,
|
85
|
+
pageshow: true,
|
86
|
+
paste: true,
|
87
|
+
pause: true,
|
88
|
+
play: true,
|
89
|
+
playing: true,
|
90
|
+
popstate: true,
|
91
|
+
progress: true,
|
92
|
+
ratechange: true,
|
93
|
+
resize: true,
|
94
|
+
reset: true,
|
95
|
+
scroll: true,
|
96
|
+
search: true,
|
97
|
+
seeked: true,
|
98
|
+
seeking: true,
|
99
|
+
select: true,
|
100
|
+
show: true,
|
101
|
+
stalled: true,
|
102
|
+
storage: true,
|
103
|
+
submit: true,
|
104
|
+
suspend: true,
|
105
|
+
timeupdate: true,
|
106
|
+
toggle: true,
|
107
|
+
touchcancel: true,
|
108
|
+
touchend: true,
|
109
|
+
touchmove: true,
|
110
|
+
touchstart: true,
|
111
|
+
transitionend: true,
|
112
|
+
unload: true,
|
113
|
+
volumechange: true,
|
114
|
+
waiting: true,
|
115
|
+
wheel: true,
|
116
|
+
}
|
117
|
+
|
118
|
+
eventRecords: Map<Event, boolean> = new Map()
|
119
|
+
|
120
|
+
getOutlets(): Array<OutletManagerController<T>> | null | void {
|
121
|
+
return null
|
122
|
+
}
|
123
|
+
|
124
|
+
outletUpdate(event: Event, data: TOutletChangeData<T>): void {}
|
125
|
+
|
126
|
+
getState(): T {
|
127
|
+
return null as T
|
128
|
+
}
|
129
|
+
|
130
|
+
connect() {
|
131
|
+
this.syncOutlets()
|
132
|
+
}
|
133
|
+
|
134
|
+
syncOutlets() {
|
135
|
+
const event = new Event('init')
|
136
|
+
this.sendToOutlets(event, {
|
137
|
+
data: this.getState(),
|
138
|
+
eventKey: this.getEventKey(event),
|
139
|
+
})
|
140
|
+
}
|
141
|
+
|
142
|
+
sendToOutlets(event: Event, updateTo: TOutletChangeData<T> = {}): void {
|
143
|
+
const eventKey = updateTo.eventKey ?? this.getEventKey(event)
|
144
|
+
const outlets = this.#outlets
|
145
|
+
if (outlets?.length) {
|
146
|
+
for (const index in outlets) {
|
147
|
+
const outlet = outlets[index]
|
148
|
+
if (outlet.isListeningForOutletEvent(eventKey) && !this.hasHeardEvent(event)) {
|
149
|
+
const isSameControllerType = this.identifier === outlet.identifier
|
150
|
+
outlet.outletUpdate(event, {eventKey, data: isSameControllerType ? updateTo.data : undefined})
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
isListeningForOutletEvent(eventTypes: string) {
|
157
|
+
const eventTypeNames = eventTypes.split('-')
|
158
|
+
|
159
|
+
if (!eventTypeNames.length) {
|
160
|
+
return false
|
161
|
+
}
|
162
|
+
|
163
|
+
let lookup = this.outletEvents
|
164
|
+
for (let i = 0; i < eventTypeNames.length; i++) {
|
165
|
+
const name = eventTypeNames[i]
|
166
|
+
if (typeof lookup === 'boolean') {
|
167
|
+
return lookup
|
168
|
+
}
|
169
|
+
|
170
|
+
const hasWildCard = lookup['*'] !== undefined
|
171
|
+
let nextKey = name
|
172
|
+
if (hasWildCard) {
|
173
|
+
nextKey = '*'
|
174
|
+
} else {
|
175
|
+
const isListeningForDOMEvent = lookup.domEvent !== undefined
|
176
|
+
if (isListeningForDOMEvent && !this.isDOMEventName(name)) {
|
177
|
+
return false
|
178
|
+
} else if (isListeningForDOMEvent) {
|
179
|
+
nextKey = 'domEvent'
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
if (!lookup[nextKey]) {
|
184
|
+
return false
|
185
|
+
}
|
186
|
+
|
187
|
+
lookup = lookup[nextKey]
|
188
|
+
}
|
189
|
+
|
190
|
+
return true
|
191
|
+
}
|
192
|
+
|
193
|
+
isDOMEventName(eventName: string) {
|
194
|
+
return OutletManagerController.domEvents[eventName]
|
195
|
+
}
|
196
|
+
|
197
|
+
getEventKey(event: Event) {
|
198
|
+
const pre = this.event_key_prefix
|
199
|
+
const post = this.event_key_postfix
|
200
|
+
|
201
|
+
const maybePreHyphen = pre ? '-' : ''
|
202
|
+
const maybePrefix = pre ?? ''
|
203
|
+
const maybePostHyphen = post ? '-' : ''
|
204
|
+
const maybePostfix = post ?? ''
|
205
|
+
|
206
|
+
return `${this.identifier}-${maybePrefix}${maybePreHyphen}${event.type}${maybePostHyphen}${maybePostfix}`
|
207
|
+
}
|
208
|
+
|
209
|
+
hasHeardEvent(event: Event) {
|
210
|
+
if (this.eventRecords.has(event)) {
|
211
|
+
return true
|
212
|
+
}
|
213
|
+
|
214
|
+
this.eventRecords.set(event, true)
|
215
|
+
setTimeout(() => this.eventRecords.delete(event))
|
216
|
+
|
217
|
+
return false
|
218
|
+
}
|
219
|
+
|
220
|
+
get event_key_prefix() {
|
221
|
+
return ''
|
222
|
+
}
|
223
|
+
|
224
|
+
get event_key_postfix() {
|
225
|
+
return ''
|
226
|
+
}
|
227
|
+
|
228
|
+
get outletEvents() {
|
229
|
+
if (!this.outletEventsLookup && this.hasOutletEventsValue) {
|
230
|
+
this.outletEventsLookup = this.outletEventsValue.reduce((acc, eventType) => {
|
231
|
+
let step = acc
|
232
|
+
eventType.split('-').forEach((eventTypeName, i, splitArr) => {
|
233
|
+
if (typeof step === 'boolean') {
|
234
|
+
return
|
235
|
+
}
|
236
|
+
|
237
|
+
if (i === splitArr.length - 1) {
|
238
|
+
step[eventTypeName] = true
|
239
|
+
} else if (step[eventTypeName] === undefined) {
|
240
|
+
step[eventTypeName] = {}
|
241
|
+
}
|
242
|
+
|
243
|
+
step = step[eventTypeName]
|
244
|
+
})
|
245
|
+
|
246
|
+
return acc
|
247
|
+
}, {} as TOutletEventLookup)
|
248
|
+
} else if (!this.outletEventsLookup) {
|
249
|
+
this.outletEventsLookup = {'*': true}
|
250
|
+
}
|
251
|
+
|
252
|
+
return this.outletEventsLookup
|
253
|
+
}
|
254
|
+
|
255
|
+
get #outlets(): Array<OutletManagerController<T>> | null | void {
|
256
|
+
const outlets = this.getOutlets()
|
257
|
+
|
258
|
+
if (outlets) {
|
259
|
+
return outlets
|
260
|
+
}
|
261
|
+
|
262
|
+
const defaultOutlets: Array<OutletManagerController<T>> = []
|
263
|
+
|
264
|
+
if (this.hasToggleableOutlet) {
|
265
|
+
defaultOutlets.push(...this.toggleableOutlets)
|
266
|
+
}
|
267
|
+
|
268
|
+
if (this.hasOptionsOutlet) {
|
269
|
+
defaultOutlets.push(...this.optionsOutlets)
|
270
|
+
}
|
271
|
+
|
272
|
+
if (this.hasStringMatchOutlet) {
|
273
|
+
defaultOutlets.push(...this.stringMatchOutlets)
|
274
|
+
}
|
275
|
+
|
276
|
+
return defaultOutlets
|
277
|
+
}
|
278
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |component| %>
|
2
|
+
<div class="<%= @base_classes %>">
|
3
|
+
<%= base %>
|
4
|
+
</div>
|
5
|
+
<div class="<%= @items_wrapper_classes %>" data-action="click->toggleable#toggle">
|
6
|
+
<% items.each do |item| %>
|
7
|
+
<%= item %>
|
8
|
+
<% end %>
|
9
|
+
</div>
|
10
|
+
<% end %>
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ariadne
|
4
|
+
# Displays content in a box that hovers over other content
|
5
|
+
class PopoverComponent < Ariadne::Component
|
6
|
+
DEFAULT_TAG = :div
|
7
|
+
TAG_OPTIONS = [DEFAULT_TAG].freeze
|
8
|
+
|
9
|
+
DIRECTIONS = [:top, :right, :bottom, :left]
|
10
|
+
|
11
|
+
# Menu: List of selectable items (ie: navigation)
|
12
|
+
# Dialog: Essentiall a modal
|
13
|
+
# Listbox: Something like a dropdown for a <select> element
|
14
|
+
# Tooltip: plain text
|
15
|
+
ROLES = [:menu, :dialog, :listbox, :tooltip]
|
16
|
+
HORIZONTAL_ALIGNMENTS = [:left, :right, :center]
|
17
|
+
|
18
|
+
DEFAULT_CLASSES = {
|
19
|
+
wrapper: "ariadne-group ariadne-relative ariadne-w-fit",
|
20
|
+
items: "ariadne-w-fit ariadne-absolute ariadne-shadow-lg ariadne-z-10 ariadne-p-2 ariadne-bg-white ariadne-rounded-md",
|
21
|
+
base: "ariadne-inline-block",
|
22
|
+
}
|
23
|
+
|
24
|
+
ITEMS_DIRECITON_CLASSES = "group-data-[popover-direction=top]:ariadne-bottom-full group-data-[popover-direction=top]:-ariadne-translate-y-2 group-data-[popover-direction=bottom]:ariadne-top-full group-data-[popover-direction=bottom]:ariadne-translate-y-2"
|
25
|
+
ITEMS_HORIZONTAL_ALIGNMENT_CLASSES = "group-data-[popover-horizontal-alignment=left]:ariadne-left-0 group-data-[popover-horizontal-alignment=right]:ariadne-right-0 group-data-[popover-horizontal-alignment=center]:ariadne-left-1/2 group-data-[popover-horizontal-alignment=center]:-ariadne-translate-x-1/2"
|
26
|
+
ITEMS_VISIBILITY_CLASSES = "group-data-[popover-visible=false]:ariadne-hidden"
|
27
|
+
|
28
|
+
DEFAULT_ATTRIBUTES = {
|
29
|
+
"data-controller": "toggleable",
|
30
|
+
"data-action": "click->toggleable#toggle",
|
31
|
+
"data-toggleable-synced-attrs-value": '["data-popover-visible"]',
|
32
|
+
}
|
33
|
+
|
34
|
+
renders_one :base
|
35
|
+
|
36
|
+
renders_many :items
|
37
|
+
|
38
|
+
# @example Default
|
39
|
+
#
|
40
|
+
# <%= render(Ariadne::PopoverComponent.new) { "Example" } %>
|
41
|
+
#
|
42
|
+
# @param tag [Symbol, String] The rendered tag name.
|
43
|
+
# @param classes [String] <%= link_to_classes_docs %>
|
44
|
+
# @param attributes [Hash] <%= link_to_attributes_docs %>
|
45
|
+
def initialize(
|
46
|
+
tag: DEFAULT_TAG,
|
47
|
+
direction: :bottom,
|
48
|
+
classes: "",
|
49
|
+
role:,
|
50
|
+
attributes: {},
|
51
|
+
horizontal_alignment: :center,
|
52
|
+
initial_visible: false,
|
53
|
+
base_wrapper_classes: "",
|
54
|
+
items_wrapper_classes: ""
|
55
|
+
)
|
56
|
+
@tag = check_incoming_tag(DEFAULT_TAG, tag)
|
57
|
+
@direction = fetch_or_raise(DIRECTIONS, direction)
|
58
|
+
@horizontal_alignment = fetch_or_raise(HORIZONTAL_ALIGNMENTS, horizontal_alignment)
|
59
|
+
@role = fetch_or_raise(ROLES, role)
|
60
|
+
@classes = merge_class_names(DEFAULT_CLASSES[:wrapper], classes)
|
61
|
+
|
62
|
+
@attributes = DEFAULT_ATTRIBUTES
|
63
|
+
.merge({
|
64
|
+
"data-popover-direction": @direction,
|
65
|
+
"data-popover-horizontal-alignment": @horizontal_alignment,
|
66
|
+
"data-popover-visible": initial_visible,
|
67
|
+
"data-toggleable-close-on-outside-click-value": true,
|
68
|
+
})
|
69
|
+
.merge(attributes)
|
70
|
+
|
71
|
+
@base_classes = merge_class_names(DEFAULT_CLASSES[:base], base_wrapper_classes)
|
72
|
+
@items_wrapper_classes = merge_class_names(
|
73
|
+
DEFAULT_CLASSES[:items],
|
74
|
+
ITEMS_DIRECITON_CLASSES,
|
75
|
+
ITEMS_HORIZONTAL_ALIGNMENT_CLASSES,
|
76
|
+
ITEMS_VISIBILITY_CLASSES,
|
77
|
+
items_wrapper_classes,
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ariadne
|
4
|
+
# Bar used to show a progress in an activity, supports single bars or multiple bars within one component
|
5
|
+
# use aria-labelledby and aria-describedby to describe the progress bar's purpose
|
6
|
+
class ProgressBarComponent < Ariadne::Component
|
7
|
+
DEFAULT_TAGS = {
|
8
|
+
wrapper: :div,
|
9
|
+
item: :div,
|
10
|
+
}
|
11
|
+
|
12
|
+
DEFAULT_CLASSES = {
|
13
|
+
wrapper: "ariadne-flex ariadne-gap-1 ariadne-bg-slate-200 ariadne-rounded-md ariadne-overflow-hidden",
|
14
|
+
item: "",
|
15
|
+
}
|
16
|
+
|
17
|
+
DEFAULT_ATTRIBUTES = {
|
18
|
+
wrapper: {
|
19
|
+
role: "progressbar",
|
20
|
+
"data-controller": "accumulator",
|
21
|
+
"aria-valuenow": 0,
|
22
|
+
},
|
23
|
+
item: { "data-accumulator-target": "sum" },
|
24
|
+
}
|
25
|
+
|
26
|
+
BAR_SIZES = {
|
27
|
+
sm: "ariadne-h-2",
|
28
|
+
md: "ariadne-h-3",
|
29
|
+
lg: "ariadne-h-4",
|
30
|
+
}
|
31
|
+
|
32
|
+
renders_many :items, lambda { |tag: DEFAULT_TAGS[:item], classes: "", value: 0, attributes: {}|
|
33
|
+
Ariadne::BaseComponent.new(
|
34
|
+
tag: check_incoming_tag(DEFAULT_TAGS[:item], tag),
|
35
|
+
classes: merge_class_names(DEFAULT_CLASSES[:item], BAR_SIZES[@size], classes),
|
36
|
+
attributes: DEFAULT_ATTRIBUTES[:item].merge({
|
37
|
+
style: "width: #{(value - @min).to_f / (@max - @min) * 100}%",
|
38
|
+
"data-value": value,
|
39
|
+
}).merge(attributes),
|
40
|
+
)
|
41
|
+
}
|
42
|
+
|
43
|
+
# @example Default
|
44
|
+
#
|
45
|
+
# <%= render(Ariadne::ProgressBarComponent.new) { "Example" } %>
|
46
|
+
#
|
47
|
+
# @param tag [Symbol, String] The rendered tag name.
|
48
|
+
# @param classes [String] <%= link_to_classes_docs %>
|
49
|
+
# @param attributes [Hash] <%= link_to_attributes_docs %>
|
50
|
+
def initialize(tag: DEFAULT_TAGS[:wrapper], min: 0, max: 100, classes: "", size: :md, attributes: {})
|
51
|
+
@tag = check_incoming_tag(DEFAULT_TAGS[:wrapper], tag)
|
52
|
+
@classes = merge_class_names(DEFAULT_CLASSES[:wrapper], classes)
|
53
|
+
|
54
|
+
@min = min
|
55
|
+
@max = max
|
56
|
+
@size = size
|
57
|
+
@attributes = DEFAULT_ATTRIBUTES[:wrapper].merge({
|
58
|
+
"aria-valuemin": @min,
|
59
|
+
"aria-valuemax": @max,
|
60
|
+
}).merge(attributes)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|