@stackoverflow/stacks 1.0.0 → 1.0.1

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 (71) hide show
  1. package/README.md +47 -47
  2. package/dist/css/stacks.css +108 -0
  3. package/dist/css/stacks.min.css +1 -1
  4. package/lib/css/atomic/borders.less +378 -378
  5. package/lib/css/atomic/colors.less +209 -209
  6. package/lib/css/atomic/flex.less +375 -375
  7. package/lib/css/atomic/grid.less +174 -174
  8. package/lib/css/atomic/misc.less +343 -343
  9. package/lib/css/atomic/spacing.less +332 -314
  10. package/lib/css/atomic/typography.less +273 -273
  11. package/lib/css/atomic/width-height.less +194 -194
  12. package/lib/css/base/body.less +44 -44
  13. package/lib/css/base/configuration-static.less +61 -61
  14. package/lib/css/base/icons.less +20 -20
  15. package/lib/css/base/internals.less +220 -220
  16. package/lib/css/base/reset-meyer.less +64 -64
  17. package/lib/css/base/reset-normalize.less +449 -449
  18. package/lib/css/base/reset.less +20 -20
  19. package/lib/css/components/activity-indicator.less +45 -45
  20. package/lib/css/components/avatars.less +189 -189
  21. package/lib/css/components/badges.less +209 -209
  22. package/lib/css/components/banners.less +80 -80
  23. package/lib/css/components/blank-states.less +26 -26
  24. package/lib/css/components/breadcrumbs.less +44 -44
  25. package/lib/css/components/button-groups.less +104 -104
  26. package/lib/css/components/buttons.less +665 -665
  27. package/lib/css/components/cards.less +44 -44
  28. package/lib/css/components/code-blocks.less +130 -130
  29. package/lib/css/components/collapsible.less +104 -104
  30. package/lib/css/components/inputs.less +728 -728
  31. package/lib/css/components/link-previews.less +136 -136
  32. package/lib/css/components/links.less +218 -218
  33. package/lib/css/components/menu.less +47 -47
  34. package/lib/css/components/modals.less +133 -133
  35. package/lib/css/components/navigation.less +146 -146
  36. package/lib/css/components/notices.less +233 -233
  37. package/lib/css/components/page-titles.less +60 -60
  38. package/lib/css/components/pagination.less +55 -55
  39. package/lib/css/components/popovers.less +197 -197
  40. package/lib/css/components/post-summary.less +425 -425
  41. package/lib/css/components/progress-bars.less +330 -330
  42. package/lib/css/components/prose.less +503 -503
  43. package/lib/css/components/spinner.less +107 -107
  44. package/lib/css/components/tables.less +341 -341
  45. package/lib/css/components/tags.less +236 -236
  46. package/lib/css/components/toggle-switches.less +144 -144
  47. package/lib/css/components/topbar.less +427 -427
  48. package/lib/css/components/uploader.less +210 -210
  49. package/lib/css/components/user-cards.less +169 -169
  50. package/lib/css/components/widget-dynamic.less +33 -33
  51. package/lib/css/components/widget-static.less +273 -273
  52. package/lib/css/exports/constants-colors.less +1092 -1092
  53. package/lib/css/exports/constants-helpers.less +108 -108
  54. package/lib/css/exports/constants-type.less +153 -153
  55. package/lib/css/exports/exports.less +15 -15
  56. package/lib/css/exports/mixins.less +237 -237
  57. package/lib/css/stacks-dynamic.less +35 -35
  58. package/lib/css/stacks-static.less +86 -86
  59. package/lib/css/stacks.less +13 -13
  60. package/lib/ts/controllers/index.ts +7 -7
  61. package/lib/ts/controllers/s-expandable-control.ts +188 -188
  62. package/lib/ts/controllers/s-modal.ts +321 -321
  63. package/lib/ts/controllers/s-navigation-tablist.ts +117 -117
  64. package/lib/ts/controllers/s-popover.ts +547 -547
  65. package/lib/ts/controllers/s-table.ts +220 -220
  66. package/lib/ts/controllers/s-tooltip.ts +246 -246
  67. package/lib/ts/controllers/s-uploader.ts +172 -172
  68. package/lib/ts/index.ts +20 -20
  69. package/lib/ts/stacks.ts +88 -88
  70. package/lib/tsconfig.json +13 -13
  71. package/package.json +87 -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
+ }