Skip to content

Commit 4a1d9da

Browse files
committed
Improved controllers with events
1 parent 08ae174 commit 4a1d9da

24 files changed

+500
-126
lines changed

assets/shared/controllers/carousel_controller.ts

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,48 @@
11
import { ActionEvent, Controller } from '@hotwired/stimulus';
2-
import { Carousel, type CarouselOptions } from 'flowbite';
2+
import { Carousel, type CarouselOptions, type CarouselInterface } from 'flowbite';
3+
4+
import { CAROUSEL_EVENTS } from '$assets/types/constants/carousel';
35

46
import type { ValueDefinitionMap } from '@hotwired/stimulus/dist/types/core/value_properties';
57

68
/* stimulusFetch: 'lazy' */
79
export default class CarouselController extends Controller<HTMLElement> {
810
static values: ValueDefinitionMap = {
911
options: { type: Object, default: {} },
12+
eventPrefix: { type: String },
1013
};
1114

12-
static targets = ['carousel', 'item'];
15+
static targets = ['item'];
1316

1417
declare optionsValue: CarouselOptions;
1518

1619
declare readonly hasOptionsValue: boolean;
1720

18-
declare readonly carouselTarget: HTMLElement;
21+
declare eventPrefixValue: string;
1922

20-
declare readonly hasCarouselTarget: boolean;
23+
declare readonly hasEventPrefixValue: boolean;
2124

2225
declare readonly itemTarget: HTMLElement;
2326

2427
declare readonly itemTargets: HTMLElement[];
2528

2629
declare readonly hasItemTarget: boolean;
2730

28-
private carousel: Carousel | null = null;
31+
private eventPrefix: string | undefined = undefined;
32+
33+
private carousel: CarouselInterface | null = null;
2934

3035
connect() {
31-
this.carousel = new Carousel(this.itemTargets.map((item, position) => ({ el: item, position })), this.optionsValue);
36+
this.eventPrefix = this.hasEventPrefixValue ? this.eventPrefixValue : undefined;
37+
this.carousel = new Carousel(
38+
this.itemTargets.map((item, position) => ({ el: item, position })),
39+
{ ...this.defaultValues, ...this.optionsValue },
40+
);
3241

3342
document.addEventListener('turbo:before-cache', this.beforeCache);
3443
}
3544

36-
disconnect(): void {
45+
disconnect() {
3746
document.removeEventListener('turbo:before-cache', this.beforeCache);
3847
}
3948

@@ -79,11 +88,49 @@ export default class CarouselController extends Controller<HTMLElement> {
7988
this.carousel.cycle();
8089
}
8190

91+
isVisible(position: number) {
92+
if (!this.carousel) {
93+
return false;
94+
}
95+
96+
return this.carousel.getItem(position);
97+
}
98+
99+
isInitialized() {
100+
return !!this.carousel;
101+
}
102+
82103
private beforeCache = () => {
83104
if (!this.carousel) {
84105
return;
85106
}
86107

87108
this.carousel.slideTo(0);
88109
};
110+
111+
get defaultValues(): CarouselOptions {
112+
return {
113+
onNext: () => {
114+
this.dispatch(CAROUSEL_EVENTS.NEXT, {
115+
target: this.element,
116+
detail: { carousel: this.carousel },
117+
prefix: this.eventPrefix,
118+
});
119+
},
120+
onPrev: () => {
121+
this.dispatch(CAROUSEL_EVENTS.PREV, {
122+
target: this.element,
123+
detail: { carousel: this.carousel },
124+
prefix: this.eventPrefix,
125+
});
126+
},
127+
onChange: () => {
128+
this.dispatch(CAROUSEL_EVENTS.CHANGE, {
129+
target: this.element,
130+
detail: { carousel: this.carousel },
131+
prefix: this.eventPrefix,
132+
});
133+
},
134+
};
135+
}
89136
}

assets/shared/controllers/class-modal_controller.ts

Lines changed: 0 additions & 78 deletions
This file was deleted.

assets/shared/controllers/alert_controller.ts renamed to assets/shared/controllers/dismiss_controller.ts

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import { Controller } from '@hotwired/stimulus';
2-
import { Dismiss, type DismissOptions } from 'flowbite';
2+
import { Dismiss, type DismissOptions, type DismissInterface } from 'flowbite';
3+
4+
import { DISMISS_EVENTS } from '$assets/types/constants/dismiss';
35

46
import type { ValueDefinitionMap } from '@hotwired/stimulus/dist/types/core/value_properties';
57

68
/* stimulusFetch: 'lazy' */
79
export default class DismissController extends Controller<HTMLElement> {
810
static values: ValueDefinitionMap = {
911
options: { type: Object, default: {} },
12+
eventPrefix: { type: String },
1013
};
1114

1215
static targets = ['dismiss', 'trigger'];
@@ -15,6 +18,10 @@ export default class DismissController extends Controller<HTMLElement> {
1518

1619
declare readonly hasOptionsValue: boolean;
1720

21+
declare eventPrefixValue: string;
22+
23+
declare readonly hasEventPrefixValue: boolean;
24+
1825
declare readonly dismissTarget: HTMLElement;
1926

2027
declare readonly hasDismissTarget: boolean;
@@ -23,19 +30,25 @@ export default class DismissController extends Controller<HTMLElement> {
2330

2431
declare readonly hasTriggerTarget: boolean;
2532

26-
private dismiss: Dismiss | null = null;
33+
private target = this.element;
34+
35+
private eventPrefix: string | undefined = undefined;
36+
37+
private dismiss: DismissInterface | null = null;
2738

2839
connect() {
40+
this.target = this.hasDismissTarget ? this.dismissTarget : this.element;
41+
this.eventPrefix = this.hasEventPrefixValue ? this.eventPrefixValue : undefined;
2942
this.dismiss = new Dismiss(
30-
this.hasDismissTarget ? this.dismissTarget : this.element,
43+
this.target,
3144
this.hasTriggerTarget ? this.triggerTarget : undefined,
32-
this.optionsValue,
45+
{ ...this.defaultValues, ...this.optionsValue },
3346
);
3447

3548
document.addEventListener('turbo:before-cache', this.beforeCache);
3649
}
3750

38-
disconnect(): void {
51+
disconnect() {
3952
document.removeEventListener('turbo:before-cache', this.beforeCache);
4053
}
4154

@@ -47,11 +60,27 @@ export default class DismissController extends Controller<HTMLElement> {
4760
this.dismiss.hide();
4861
}
4962

63+
isInitialized() {
64+
return !!this.dismiss;
65+
}
66+
5067
private beforeCache = () => {
5168
if (!this.dismiss) {
5269
return;
5370
}
5471

5572
this.dismiss.hide();
5673
};
74+
75+
get defaultValues(): DismissOptions {
76+
return {
77+
onHide: () => {
78+
this.dispatch(DISMISS_EVENTS.HIDE, {
79+
target: this.target,
80+
detail: { dismiss: this.dismiss },
81+
prefix: this.eventPrefix,
82+
});
83+
},
84+
};
85+
}
5786
}

assets/shared/controllers/drawer_controller.ts

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import { Controller } from '@hotwired/stimulus';
2-
import { Drawer, type DrawerOptions } from 'flowbite';
2+
import { Drawer, type DrawerOptions, type DrawerInterface } from 'flowbite';
3+
4+
import { DRAWER_EVENTS } from '$assets/types/constants/drawer';
35

46
import type { ValueDefinitionMap } from '@hotwired/stimulus/dist/types/core/value_properties';
57

68
/* stimulusFetch: 'lazy' */
79
export default class DrawerController extends Controller<HTMLElement> {
810
static values: ValueDefinitionMap = {
911
options: { type: Object, default: {} },
12+
eventPrefix: { type: String },
1013
};
1114

1215
static targets = ['drawer'];
@@ -15,19 +18,29 @@ export default class DrawerController extends Controller<HTMLElement> {
1518

1619
declare readonly hasOptionsValue: boolean;
1720

21+
declare eventPrefixValue: string;
22+
23+
declare readonly hasEventPrefixValue: boolean;
24+
1825
declare readonly drawerTarget: HTMLElement;
1926

2027
declare readonly hasDrawerTarget: boolean;
2128

22-
private drawer: Drawer | null = null;
29+
private target = this.element;
30+
31+
private eventPrefix: string | undefined = undefined;
32+
33+
private drawer: DrawerInterface | null = null;
2334

2435
connect() {
25-
this.drawer = new Drawer(this.hasDrawerTarget ? this.drawerTarget : this.element, this.optionsValue);
36+
this.target = this.hasDrawerTarget ? this.drawerTarget : this.element;
37+
this.eventPrefix = this.hasEventPrefixValue ? this.eventPrefixValue : undefined;
38+
this.drawer = new Drawer(this.target, { ...this.defaultValues, ...this.optionsValue });
2639

2740
document.addEventListener('turbo:before-cache', this.beforeCache);
2841
}
2942

30-
disconnect(): void {
43+
disconnect() {
3144
document.removeEventListener('turbo:before-cache', this.beforeCache);
3245
}
3346

@@ -55,11 +68,57 @@ export default class DrawerController extends Controller<HTMLElement> {
5568
this.drawer.toggle();
5669
}
5770

71+
isVisible() {
72+
if (!this.drawer) {
73+
return false;
74+
}
75+
76+
return this.drawer.isVisible();
77+
}
78+
79+
isHidden() {
80+
if (!this.drawer) {
81+
return true;
82+
}
83+
84+
return this.drawer.isHidden();
85+
}
86+
87+
isInitialized() {
88+
return !!this.drawer;
89+
}
90+
5891
private beforeCache = () => {
5992
if (!this.drawer) {
6093
return;
6194
}
6295

6396
this.drawer.hide();
6497
};
98+
99+
get defaultValues(): DrawerOptions {
100+
return {
101+
onHide: () => {
102+
this.dispatch(DRAWER_EVENTS.HIDE, {
103+
target: this.target,
104+
detail: { drawer: this.drawer },
105+
prefix: this.eventPrefix,
106+
});
107+
},
108+
onShow: () => {
109+
this.dispatch(DRAWER_EVENTS.SHOW, {
110+
target: this.target,
111+
detail: { drawer: this.drawer },
112+
prefix: this.eventPrefix,
113+
});
114+
},
115+
onToggle: () => {
116+
this.dispatch(DRAWER_EVENTS.TOGGLE, {
117+
target: this.target,
118+
detail: { drawer: this.drawer },
119+
prefix: this.eventPrefix,
120+
});
121+
},
122+
};
123+
}
65124
}

0 commit comments

Comments
 (0)