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