@stackoverflow/stacks 1.0.0-beta.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +47 -47
  2. package/dist/controllers/s-popover.d.ts +11 -2
  3. package/dist/css/stacks.css +214 -3
  4. package/dist/css/stacks.min.css +1 -1
  5. package/dist/js/stacks.js +18 -2
  6. package/dist/js/stacks.min.js +1 -1
  7. package/lib/css/atomic/borders.less +378 -378
  8. package/lib/css/atomic/colors.less +209 -209
  9. package/lib/css/atomic/flex.less +375 -375
  10. package/lib/css/atomic/grid.less +174 -174
  11. package/lib/css/atomic/misc.less +343 -343
  12. package/lib/css/atomic/spacing.less +342 -314
  13. package/lib/css/atomic/typography.less +273 -273
  14. package/lib/css/atomic/width-height.less +194 -194
  15. package/lib/css/base/body.less +44 -44
  16. package/lib/css/base/configuration-static.less +61 -61
  17. package/lib/css/base/icons.less +20 -20
  18. package/lib/css/base/internals.less +220 -220
  19. package/lib/css/base/reset-meyer.less +64 -64
  20. package/lib/css/base/reset-normalize.less +449 -449
  21. package/lib/css/base/reset.less +20 -20
  22. package/lib/css/components/activity-indicator.less +44 -45
  23. package/lib/css/components/avatars.less +189 -189
  24. package/lib/css/components/badges.less +209 -209
  25. package/lib/css/components/banners.less +80 -80
  26. package/lib/css/components/blank-states.less +26 -26
  27. package/lib/css/components/breadcrumbs.less +44 -44
  28. package/lib/css/components/button-groups.less +104 -104
  29. package/lib/css/components/buttons.less +665 -665
  30. package/lib/css/components/cards.less +44 -44
  31. package/lib/css/components/code-blocks.less +130 -130
  32. package/lib/css/components/collapsible.less +104 -104
  33. package/lib/css/components/inputs.less +728 -728
  34. package/lib/css/components/link-previews.less +136 -136
  35. package/lib/css/components/links.less +218 -218
  36. package/lib/css/components/menu.less +47 -47
  37. package/lib/css/components/modals.less +133 -133
  38. package/lib/css/components/navigation.less +146 -146
  39. package/lib/css/components/notices.less +233 -233
  40. package/lib/css/components/page-titles.less +60 -60
  41. package/lib/css/components/pagination.less +55 -55
  42. package/lib/css/components/popovers.less +197 -197
  43. package/lib/css/components/post-summary.less +425 -425
  44. package/lib/css/components/progress-bars.less +330 -330
  45. package/lib/css/components/prose.less +503 -503
  46. package/lib/css/components/spinner.less +107 -107
  47. package/lib/css/components/tables.less +341 -341
  48. package/lib/css/components/tags.less +236 -236
  49. package/lib/css/components/toggle-switches.less +144 -144
  50. package/lib/css/components/topbar.less +427 -427
  51. package/lib/css/components/uploader.less +210 -210
  52. package/lib/css/components/user-cards.less +169 -169
  53. package/lib/css/components/widget-dynamic.less +33 -33
  54. package/lib/css/components/widget-static.less +273 -273
  55. package/lib/css/exports/constants-colors.less +1092 -1092
  56. package/lib/css/exports/constants-helpers.less +108 -108
  57. package/lib/css/exports/constants-type.less +153 -153
  58. package/lib/css/exports/exports.less +15 -15
  59. package/lib/css/exports/mixins.less +237 -237
  60. package/lib/css/stacks-dynamic.less +35 -35
  61. package/lib/css/stacks-static.less +86 -86
  62. package/lib/css/stacks.less +13 -13
  63. package/lib/ts/controllers/index.ts +7 -7
  64. package/lib/ts/controllers/s-expandable-control.ts +188 -188
  65. package/lib/ts/controllers/s-modal.ts +321 -321
  66. package/lib/ts/controllers/s-navigation-tablist.ts +117 -117
  67. package/lib/ts/controllers/s-popover.ts +567 -547
  68. package/lib/ts/controllers/s-table.ts +220 -220
  69. package/lib/ts/controllers/s-tooltip.ts +246 -246
  70. package/lib/ts/controllers/s-uploader.ts +172 -172
  71. package/lib/ts/index.ts +20 -20
  72. package/lib/ts/stacks.ts +88 -88
  73. package/lib/tsconfig.json +13 -13
  74. package/package.json +86 -87
@@ -1,172 +1,172 @@
1
- import * as Stacks from "../stacks";
2
-
3
- interface FilePreview {
4
- data?: string | ArrayBuffer;
5
- name: string;
6
- type: string;
7
- };
8
-
9
- export class UploaderController extends Stacks.StacksController {
10
- static targets = ["input", "previews", "uploader"];
11
- private inputTarget!: HTMLInputElement;
12
- private previewsTarget!: HTMLElement;
13
- private uploaderTarget!: HTMLElement;
14
-
15
- private boundDragEnter!: any;
16
- private boundDragLeave!: any;
17
-
18
- private static readonly FILE_DISPLAY_LIMIT = 10;
19
- private static readonly MAX_FILE_SIZE = 1024 * 1024 * 10; // 10 MB
20
-
21
- connect() {
22
- super.connect();
23
- this.boundDragEnter = this.handleUploaderActive.bind(this, true);
24
- this.boundDragLeave = this.handleUploaderActive.bind(this, false);
25
-
26
- this.inputTarget.addEventListener("dragenter", this.boundDragEnter);
27
- this.inputTarget.addEventListener("dragleave", this.boundDragLeave);
28
- }
29
-
30
- disconnect() {
31
- this.inputTarget.removeEventListener("dragenter", this.boundDragEnter);
32
- this.inputTarget.removeEventListener("dragleave", this.boundDragLeave);
33
- super.disconnect();
34
- }
35
-
36
- /**
37
- * Handles rendering the file preview state on input change
38
- */
39
- handleInput() {
40
- this.previewsTarget.innerHTML = "";
41
-
42
- if (!this.inputTarget.files) {
43
- return;
44
- }
45
-
46
- const count = this.inputTarget.files.length;
47
- this.getDataURLs(this.inputTarget.files, UploaderController.FILE_DISPLAY_LIMIT)
48
- .then((res: FilePreview[]) => {
49
- this.handleVisible(true);
50
- const hasMultipleFiles = res.length > 1;
51
-
52
- if (hasMultipleFiles) {
53
- let headingElement = document.createElement("div");
54
- headingElement.classList.add("s-uploader--previews-heading");
55
- headingElement.innerText = res.length < count ?
56
- `Showing ${res.length} of ${count} files` : `${count} items`;
57
- this.previewsTarget.appendChild(headingElement);
58
- this.previewsTarget.classList.add("has-multiple");
59
- } else {
60
- this.previewsTarget.classList.remove("has-multiple");
61
- }
62
- res.forEach((file) => this.addFilePreview(file));
63
- this.handleUploaderActive(true);
64
- });
65
- }
66
-
67
- /**
68
- * Resets the Uploader to initial state
69
- */
70
- reset() {
71
- this.inputTarget.value = '';
72
- this.previewsTarget.innerHTML = "";
73
- this.handleVisible(false);
74
- }
75
-
76
- /**
77
- * Set hide/show and disabled state on elements depending on preview state
78
- * @param {boolean} shouldPreview - Uploader is entering a preview state
79
- */
80
- private handleVisible(shouldPreview: boolean) {
81
- const { scope } = this.targets;
82
- const hideElements = scope.findAllElements('[data-s-uploader-hide-on-input]');
83
- const showElements = scope.findAllElements('[data-s-uploader-show-on-input]');
84
- const enableElements = scope.findAllElements('[data-s-uploader-enable-on-input]');
85
-
86
- if (shouldPreview) {
87
- hideElements.map(el => el.classList.add("d-none"));
88
- showElements.map(el => el.classList.remove("d-none"));
89
- enableElements.map(el => el.removeAttribute("disabled"));
90
- } else {
91
- hideElements.map(el => el.classList.remove("d-none"));
92
- showElements.map(el => el.classList.add("d-none"));
93
- enableElements.map(el => el.setAttribute("disabled", "true"))
94
- this.handleUploaderActive(false);
95
- }
96
- }
97
-
98
- /**
99
- * Adds a DOM element to preview a selected file
100
- * @param {FilePreview} file
101
- */
102
- private addFilePreview(file: FilePreview) {
103
- if (!file) {
104
- return;
105
- }
106
-
107
- let previewElement = document.createElement("div");
108
- let thumbElement;
109
-
110
- if (file.type.match('image/*') && file.data) {
111
- thumbElement = document.createElement("img");
112
- thumbElement.src = file.data.toString();
113
- thumbElement.alt = file.name;
114
- } else {
115
- thumbElement = document.createElement("div");
116
- thumbElement.innerText = file.name;
117
- }
118
-
119
- thumbElement.classList.add("s-uploader--preview-thumbnail");
120
- previewElement.appendChild(thumbElement);
121
- previewElement.classList.add("s-uploader--preview");
122
- previewElement.setAttribute('data-filename', file.name);
123
- this.previewsTarget.appendChild(previewElement);
124
- }
125
-
126
- /**
127
- * Toggles display and disabled state for select elements on valid input
128
- * @param {boolean} active - Uploader is in active state (typically on 'dragenter')
129
- */
130
- private handleUploaderActive(active: boolean) {
131
- this.uploaderTarget.classList.toggle("is-active", active);
132
- }
133
-
134
- /**
135
- * Converts the file data into a data URL
136
- * @param {File} file
137
- * @returns an object containing a FilePreview object
138
- */
139
- private fileToDataURL(file: File): Promise<FilePreview> {
140
- var reader = new FileReader();
141
- const { name, size, type } = file;
142
-
143
- if (size < UploaderController.MAX_FILE_SIZE && type.indexOf("image") > -1) {
144
- return new Promise((resolve, reject) => {
145
- reader.onload = evt => {
146
- const res = evt?.target?.result;
147
- if (res) {
148
- resolve({ data: res, name, type });
149
- } else {
150
- reject();
151
- }
152
- }
153
- reader.readAsDataURL(file);
154
- });
155
- } else {
156
- return Promise.resolve({ name, type });
157
- }
158
- }
159
-
160
- /**
161
- * Gets an array of FilePreviews from a FileList
162
- * @param {FileList|[]} files
163
- * @returns an array of FilePreview objects from a FileList
164
- */
165
- private getDataURLs(files: FileList, limit: number): Promise<FilePreview[]> {
166
- const promises = Array.from(files)
167
- .slice(0, Math.min(limit, files.length))
168
- .map(f => this.fileToDataURL(f));
169
-
170
- return Promise.all(promises);
171
- }
172
- };
1
+ import * as Stacks from "../stacks";
2
+
3
+ interface FilePreview {
4
+ data?: string | ArrayBuffer;
5
+ name: string;
6
+ type: string;
7
+ };
8
+
9
+ export class UploaderController extends Stacks.StacksController {
10
+ static targets = ["input", "previews", "uploader"];
11
+ private inputTarget!: HTMLInputElement;
12
+ private previewsTarget!: HTMLElement;
13
+ private uploaderTarget!: HTMLElement;
14
+
15
+ private boundDragEnter!: any;
16
+ private boundDragLeave!: any;
17
+
18
+ private static readonly FILE_DISPLAY_LIMIT = 10;
19
+ private static readonly MAX_FILE_SIZE = 1024 * 1024 * 10; // 10 MB
20
+
21
+ connect() {
22
+ super.connect();
23
+ this.boundDragEnter = this.handleUploaderActive.bind(this, true);
24
+ this.boundDragLeave = this.handleUploaderActive.bind(this, false);
25
+
26
+ this.inputTarget.addEventListener("dragenter", this.boundDragEnter);
27
+ this.inputTarget.addEventListener("dragleave", this.boundDragLeave);
28
+ }
29
+
30
+ disconnect() {
31
+ this.inputTarget.removeEventListener("dragenter", this.boundDragEnter);
32
+ this.inputTarget.removeEventListener("dragleave", this.boundDragLeave);
33
+ super.disconnect();
34
+ }
35
+
36
+ /**
37
+ * Handles rendering the file preview state on input change
38
+ */
39
+ handleInput() {
40
+ this.previewsTarget.innerHTML = "";
41
+
42
+ if (!this.inputTarget.files) {
43
+ return;
44
+ }
45
+
46
+ const count = this.inputTarget.files.length;
47
+ this.getDataURLs(this.inputTarget.files, UploaderController.FILE_DISPLAY_LIMIT)
48
+ .then((res: FilePreview[]) => {
49
+ this.handleVisible(true);
50
+ const hasMultipleFiles = res.length > 1;
51
+
52
+ if (hasMultipleFiles) {
53
+ let headingElement = document.createElement("div");
54
+ headingElement.classList.add("s-uploader--previews-heading");
55
+ headingElement.innerText = res.length < count ?
56
+ `Showing ${res.length} of ${count} files` : `${count} items`;
57
+ this.previewsTarget.appendChild(headingElement);
58
+ this.previewsTarget.classList.add("has-multiple");
59
+ } else {
60
+ this.previewsTarget.classList.remove("has-multiple");
61
+ }
62
+ res.forEach((file) => this.addFilePreview(file));
63
+ this.handleUploaderActive(true);
64
+ });
65
+ }
66
+
67
+ /**
68
+ * Resets the Uploader to initial state
69
+ */
70
+ reset() {
71
+ this.inputTarget.value = '';
72
+ this.previewsTarget.innerHTML = "";
73
+ this.handleVisible(false);
74
+ }
75
+
76
+ /**
77
+ * Set hide/show and disabled state on elements depending on preview state
78
+ * @param {boolean} shouldPreview - Uploader is entering a preview state
79
+ */
80
+ private handleVisible(shouldPreview: boolean) {
81
+ const { scope } = this.targets;
82
+ const hideElements = scope.findAllElements('[data-s-uploader-hide-on-input]');
83
+ const showElements = scope.findAllElements('[data-s-uploader-show-on-input]');
84
+ const enableElements = scope.findAllElements('[data-s-uploader-enable-on-input]');
85
+
86
+ if (shouldPreview) {
87
+ hideElements.map(el => el.classList.add("d-none"));
88
+ showElements.map(el => el.classList.remove("d-none"));
89
+ enableElements.map(el => el.removeAttribute("disabled"));
90
+ } else {
91
+ hideElements.map(el => el.classList.remove("d-none"));
92
+ showElements.map(el => el.classList.add("d-none"));
93
+ enableElements.map(el => el.setAttribute("disabled", "true"))
94
+ this.handleUploaderActive(false);
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Adds a DOM element to preview a selected file
100
+ * @param {FilePreview} file
101
+ */
102
+ private addFilePreview(file: FilePreview) {
103
+ if (!file) {
104
+ return;
105
+ }
106
+
107
+ let previewElement = document.createElement("div");
108
+ let thumbElement;
109
+
110
+ if (file.type.match('image/*') && file.data) {
111
+ thumbElement = document.createElement("img");
112
+ thumbElement.src = file.data.toString();
113
+ thumbElement.alt = file.name;
114
+ } else {
115
+ thumbElement = document.createElement("div");
116
+ thumbElement.innerText = file.name;
117
+ }
118
+
119
+ thumbElement.classList.add("s-uploader--preview-thumbnail");
120
+ previewElement.appendChild(thumbElement);
121
+ previewElement.classList.add("s-uploader--preview");
122
+ previewElement.setAttribute('data-filename', file.name);
123
+ this.previewsTarget.appendChild(previewElement);
124
+ }
125
+
126
+ /**
127
+ * Toggles display and disabled state for select elements on valid input
128
+ * @param {boolean} active - Uploader is in active state (typically on 'dragenter')
129
+ */
130
+ private handleUploaderActive(active: boolean) {
131
+ this.uploaderTarget.classList.toggle("is-active", active);
132
+ }
133
+
134
+ /**
135
+ * Converts the file data into a data URL
136
+ * @param {File} file
137
+ * @returns an object containing a FilePreview object
138
+ */
139
+ private fileToDataURL(file: File): Promise<FilePreview> {
140
+ var reader = new FileReader();
141
+ const { name, size, type } = file;
142
+
143
+ if (size < UploaderController.MAX_FILE_SIZE && type.indexOf("image") > -1) {
144
+ return new Promise((resolve, reject) => {
145
+ reader.onload = evt => {
146
+ const res = evt?.target?.result;
147
+ if (res) {
148
+ resolve({ data: res, name, type });
149
+ } else {
150
+ reject();
151
+ }
152
+ }
153
+ reader.readAsDataURL(file);
154
+ });
155
+ } else {
156
+ return Promise.resolve({ name, type });
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Gets an array of FilePreviews from a FileList
162
+ * @param {FileList|[]} files
163
+ * @returns an array of FilePreview objects from a FileList
164
+ */
165
+ private getDataURLs(files: FileList, limit: number): Promise<FilePreview[]> {
166
+ const promises = Array.from(files)
167
+ .slice(0, Math.min(limit, files.length))
168
+ .map(f => this.fileToDataURL(f));
169
+
170
+ return Promise.all(promises);
171
+ }
172
+ };
package/lib/ts/index.ts CHANGED
@@ -1,20 +1,20 @@
1
- import '../css/stacks.less';
2
- import { ExpandableController, ModalController, PopoverController, TableController, TabListController, TooltipController, UploaderController } from './controllers';
3
- import { application, StacksApplication } from './stacks';
4
-
5
- // register all built-in controllers
6
- application.register("s-expandable-control", ExpandableController);
7
- application.register("s-modal", ModalController);
8
- application.register("s-navigation-tablist", TabListController);
9
- application.register("s-popover", PopoverController);
10
- application.register("s-table", TableController);
11
- application.register("s-tooltip", TooltipController);
12
- application.register("s-uploader", UploaderController);
13
-
14
- // finalize the application to guard our controller namespace
15
- StacksApplication.finalize();
16
-
17
- // export all controllers w/ helpers
18
- export * from "./controllers";
19
- // export the entirety of the contents of stacks.ts
20
- export * from "./stacks";
1
+ import '../css/stacks.less';
2
+ import { ExpandableController, ModalController, PopoverController, TableController, TabListController, TooltipController, UploaderController } from './controllers';
3
+ import { application, StacksApplication } from './stacks';
4
+
5
+ // register all built-in controllers
6
+ application.register("s-expandable-control", ExpandableController);
7
+ application.register("s-modal", ModalController);
8
+ application.register("s-navigation-tablist", TabListController);
9
+ application.register("s-popover", PopoverController);
10
+ application.register("s-table", TableController);
11
+ application.register("s-tooltip", TooltipController);
12
+ application.register("s-uploader", UploaderController);
13
+
14
+ // finalize the application to guard our controller namespace
15
+ StacksApplication.finalize();
16
+
17
+ // export all controllers w/ helpers
18
+ export * from "./controllers";
19
+ // export the entirety of the contents of stacks.ts
20
+ export * from "./stacks";
package/lib/ts/stacks.ts CHANGED
@@ -1,88 +1,88 @@
1
- import * as Stimulus from "stimulus";
2
-
3
- export class StacksApplication extends Stimulus.Application {
4
- static _initializing = true;
5
-
6
- load(...definitions: Stimulus.Definition[]): void
7
- load(definitions: Stimulus.Definition[]): void
8
- load(head: Stimulus.Definition | Stimulus.Definition[], ...rest: Stimulus.Definition[]) {
9
- const definitions = Array.isArray(head) ? head : [head, ...rest];
10
-
11
- for (const definition of definitions) {
12
- var hasPrefix = /^s-/.test(definition.identifier);
13
- if (StacksApplication._initializing && !hasPrefix) {
14
- throw "Stacks-created Stimulus controller names must start with \"s-\".";
15
- }
16
- if (!StacksApplication._initializing && hasPrefix) {
17
- throw "The \"s-\" prefix on Stimulus controller names is reserved for Stacks-created controllers.";
18
- }
19
- }
20
-
21
- super.load(definitions);
22
- }
23
-
24
- static start(element?: Element, schema?: Stimulus.Schema): StacksApplication {
25
- const application = new StacksApplication(element, schema);
26
- application.start();
27
- return application;
28
- }
29
-
30
- static finalize() {
31
- StacksApplication._initializing = false;
32
- }
33
- }
34
-
35
- export const application: Stimulus.Application = StacksApplication.start();
36
-
37
- export class StacksController extends Stimulus.Controller {
38
- protected getElementData(element: Element, key: string) {
39
- return element.getAttribute("data-" + this.identifier + "-" + key);
40
- };
41
- protected setElementData(element: Element, key: string, value: string) {
42
- element.setAttribute("data-" + this.identifier + "-" + key, value);
43
- };
44
- protected removeElementData(element: Element, key: string) {
45
- element.removeAttribute("data-" + this.identifier + "-" + key);
46
- };
47
- protected triggerEvent<T>(eventName: string, detail?: T, optionalElement?: Element) {
48
- const namespacedName = this.identifier + ":" + eventName;
49
- var event : CustomEvent<T>;
50
- try {
51
- event = new CustomEvent(namespacedName, {bubbles: true, cancelable: true, detail: detail});
52
- } catch (ex) {
53
- // Internet Explorer
54
- event = document.createEvent("CustomEvent");
55
- event.initCustomEvent(namespacedName, true, true, detail!);
56
- }
57
- (optionalElement || this.element).dispatchEvent(event);
58
- return event;
59
- };
60
- }
61
-
62
- // ControllerDefinition/createController/addController is here to make
63
- // it easier to consume Stimulus from ES5 files (without classes)
64
- export interface ControllerDefinition {
65
- [name: string]: any;
66
- targets?: string[];
67
- }
68
- export function createController(controllerDefinition: ControllerDefinition): typeof StacksController {
69
- const Controller = controllerDefinition.hasOwnProperty("targets")
70
- ? class Controller extends StacksController { static targets = controllerDefinition.targets! }
71
- : class Controller extends StacksController {};
72
-
73
- for (var prop in controllerDefinition) {
74
- if (prop !== "targets" && controllerDefinition.hasOwnProperty(prop)) {
75
- Object.defineProperty(
76
- Controller.prototype,
77
- prop,
78
- Object.getOwnPropertyDescriptor(controllerDefinition, prop)!
79
- );
80
- }
81
- }
82
-
83
- return Controller;
84
- }
85
-
86
- export function addController(name: string, controller: ControllerDefinition) {
87
- application.register(name, createController(controller));
88
- }
1
+ import * as Stimulus from "stimulus";
2
+
3
+ export class StacksApplication extends Stimulus.Application {
4
+ static _initializing = true;
5
+
6
+ load(...definitions: Stimulus.Definition[]): void
7
+ load(definitions: Stimulus.Definition[]): void
8
+ load(head: Stimulus.Definition | Stimulus.Definition[], ...rest: Stimulus.Definition[]) {
9
+ const definitions = Array.isArray(head) ? head : [head, ...rest];
10
+
11
+ for (const definition of definitions) {
12
+ var hasPrefix = /^s-/.test(definition.identifier);
13
+ if (StacksApplication._initializing && !hasPrefix) {
14
+ throw "Stacks-created Stimulus controller names must start with \"s-\".";
15
+ }
16
+ if (!StacksApplication._initializing && hasPrefix) {
17
+ throw "The \"s-\" prefix on Stimulus controller names is reserved for Stacks-created controllers.";
18
+ }
19
+ }
20
+
21
+ super.load(definitions);
22
+ }
23
+
24
+ static start(element?: Element, schema?: Stimulus.Schema): StacksApplication {
25
+ const application = new StacksApplication(element, schema);
26
+ application.start();
27
+ return application;
28
+ }
29
+
30
+ static finalize() {
31
+ StacksApplication._initializing = false;
32
+ }
33
+ }
34
+
35
+ export const application: Stimulus.Application = StacksApplication.start();
36
+
37
+ export class StacksController extends Stimulus.Controller {
38
+ protected getElementData(element: Element, key: string) {
39
+ return element.getAttribute("data-" + this.identifier + "-" + key);
40
+ };
41
+ protected setElementData(element: Element, key: string, value: string) {
42
+ element.setAttribute("data-" + this.identifier + "-" + key, value);
43
+ };
44
+ protected removeElementData(element: Element, key: string) {
45
+ element.removeAttribute("data-" + this.identifier + "-" + key);
46
+ };
47
+ protected triggerEvent<T>(eventName: string, detail?: T, optionalElement?: Element) {
48
+ const namespacedName = this.identifier + ":" + eventName;
49
+ var event : CustomEvent<T>;
50
+ try {
51
+ event = new CustomEvent(namespacedName, {bubbles: true, cancelable: true, detail: detail});
52
+ } catch (ex) {
53
+ // Internet Explorer
54
+ event = document.createEvent("CustomEvent");
55
+ event.initCustomEvent(namespacedName, true, true, detail!);
56
+ }
57
+ (optionalElement || this.element).dispatchEvent(event);
58
+ return event;
59
+ };
60
+ }
61
+
62
+ // ControllerDefinition/createController/addController is here to make
63
+ // it easier to consume Stimulus from ES5 files (without classes)
64
+ export interface ControllerDefinition {
65
+ [name: string]: any;
66
+ targets?: string[];
67
+ }
68
+ export function createController(controllerDefinition: ControllerDefinition): typeof StacksController {
69
+ const Controller = controllerDefinition.hasOwnProperty("targets")
70
+ ? class Controller extends StacksController { static targets = controllerDefinition.targets! }
71
+ : class Controller extends StacksController {};
72
+
73
+ for (var prop in controllerDefinition) {
74
+ if (prop !== "targets" && controllerDefinition.hasOwnProperty(prop)) {
75
+ Object.defineProperty(
76
+ Controller.prototype,
77
+ prop,
78
+ Object.getOwnPropertyDescriptor(controllerDefinition, prop)!
79
+ );
80
+ }
81
+ }
82
+
83
+ return Controller;
84
+ }
85
+
86
+ export function addController(name: string, controller: ControllerDefinition) {
87
+ application.register(name, createController(controller));
88
+ }
package/lib/tsconfig.json CHANGED
@@ -1,13 +1,13 @@
1
- {
2
- "compilerOptions": {
3
- "strict": true,
4
- "target": "es5",
5
- "lib": ["dom", "es6", "dom.iterable", "scripthost"], // es6 stuff is polyfilled by stimulus
6
- "outDir": "../dist",
7
- "sourceMap": true,
8
- "moduleResolution": "node",
9
- "skipLibCheck": true,
10
- "declaration": true
11
- },
12
- "include": ["ts/**/*"]
13
- }
1
+ {
2
+ "compilerOptions": {
3
+ "strict": true,
4
+ "target": "es5",
5
+ "lib": ["dom", "es6", "dom.iterable", "scripthost"], // es6 stuff is polyfilled by stimulus
6
+ "outDir": "../dist",
7
+ "sourceMap": true,
8
+ "moduleResolution": "node",
9
+ "skipLibCheck": true,
10
+ "declaration": true
11
+ },
12
+ "include": ["ts/**/*"]
13
+ }