custom-elements-ts 0.0.16 → 0.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 (69) hide show
  1. package/.eslintrc.json +46 -0
  2. package/.github/workflows/ci.yml +49 -0
  3. package/.prettierrc +7 -0
  4. package/LICENSE +20 -0
  5. package/README.md +426 -168
  6. package/demos/counter/counter.element.html +1 -0
  7. package/demos/counter/counter.element.scss +234 -0
  8. package/demos/counter/counter.element.ts +68 -0
  9. package/demos/counter/index.html +205 -0
  10. package/demos/counter/index.ts +1 -0
  11. package/demos/site/code-example/code-example.element.scss +168 -0
  12. package/demos/site/code-example/code-example.element.ts +88 -0
  13. package/demos/site/event-log/event-log.element.scss +179 -0
  14. package/demos/site/event-log/event-log.element.ts +134 -0
  15. package/demos/site/favicon.svg +14 -0
  16. package/demos/site/index.html +346 -0
  17. package/demos/site/index.ts +13 -0
  18. package/demos/site/message/message.element.scss +75 -0
  19. package/demos/site/message/message.element.ts +76 -0
  20. package/demos/site/og-image.png +0 -0
  21. package/demos/site/styles/site.css +1023 -0
  22. package/demos/site/styles/tokens.css +56 -0
  23. package/demos/site/toast/toast.element.scss +110 -0
  24. package/demos/site/toast/toast.element.ts +63 -0
  25. package/demos/todo-dashboard/index.html +141 -0
  26. package/demos/todo-dashboard/index.ts +4 -0
  27. package/demos/todo-dashboard/todo-dashboard.element.scss +1145 -0
  28. package/demos/todo-dashboard/todo-dashboard.element.ts +332 -0
  29. package/demos/todo-dashboard/todo-filters.element.ts +54 -0
  30. package/demos/todo-dashboard/todo-item.element.ts +126 -0
  31. package/demos/todo-dashboard/todo-stats.element.ts +189 -0
  32. package/package.json +73 -29
  33. package/src/custom-element.ts +206 -0
  34. package/{index.d.ts → src/index.ts} +2 -0
  35. package/src/listen.ts +70 -0
  36. package/src/prop.ts +92 -0
  37. package/src/state.ts +129 -0
  38. package/src/template-runtime.ts +435 -0
  39. package/src/toggle.ts +66 -0
  40. package/src/tsconfig.json +24 -0
  41. package/src/util.ts +33 -0
  42. package/src/watch.ts +14 -0
  43. package/tests/basic.spec.ts +70 -0
  44. package/tests/custom-element.spec.ts +77 -0
  45. package/tests/dispatch.spec.ts +52 -0
  46. package/tests/init.spec.ts +94 -0
  47. package/tests/listen.spec.ts +118 -0
  48. package/tests/prop.spec.ts +118 -0
  49. package/tests/templating-runtime.spec.ts +575 -0
  50. package/tests/toggle.spec.ts +92 -0
  51. package/tests/watch.spec.ts +183 -0
  52. package/tools/build.js +119 -0
  53. package/tools/bundle.js +167 -0
  54. package/tools/rollup-config.js +70 -0
  55. package/tools/start.js +188 -0
  56. package/tsconfig.json +38 -0
  57. package/vite.config.mts +30 -0
  58. package/bundles/custom-elements-ts.umd.js +0 -315
  59. package/bundles/custom-elements-ts.umd.js.map +0 -1
  60. package/custom-element.d.ts +0 -12
  61. package/esm2015/custom-elements-ts.js +0 -260
  62. package/esm2015/custom-elements-ts.js.map +0 -1
  63. package/esm5/custom-elements-ts.js +0 -298
  64. package/esm5/custom-elements-ts.js.map +0 -1
  65. package/listen.d.ts +0 -17
  66. package/prop.d.ts +0 -2
  67. package/toggle.d.ts +0 -1
  68. package/util.d.ts +0 -4
  69. package/watch.d.ts +0 -1
@@ -0,0 +1,183 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { CustomElement, Prop, Toggle, Watch } from 'custom-elements-ts';
3
+
4
+ @CustomElement({
5
+ tag: 'watch-element',
6
+ template: '<span>my element</span>',
7
+ style: ':host{border:0}',
8
+ })
9
+ class WatchElement extends HTMLElement {
10
+ @Prop() name: any;
11
+
12
+ @Watch('name')
13
+ setSpan(value: any) {
14
+ const span = this.shadowRoot!.querySelector('span');
15
+ span!.innerHTML = value.new;
16
+ }
17
+
18
+ set label(value: any) {
19
+ this.setAttribute('label', value);
20
+ }
21
+ get label(): any {
22
+ return this.getAttribute('label') || '';
23
+ }
24
+
25
+ newLabel = '';
26
+ @Watch('label')
27
+ setLabel(value: any) {
28
+ this.newLabel = value.new;
29
+ }
30
+
31
+ newColor = '';
32
+ @Prop() color = 'blue';
33
+ initialColor = '';
34
+ @Watch('color')
35
+ changeColor(value: any) {
36
+ this.initialColor ||= value.new;
37
+ this.newColor = this.color;
38
+ }
39
+
40
+ caseChanged = false;
41
+ @Prop() setCase: any;
42
+ @Watch('setCase')
43
+ changeCase(value: any) {
44
+ this.caseChanged = this.setCase === value.new;
45
+ }
46
+
47
+ @Watch('set-kebab')
48
+ changeKebabCase(value: any) {
49
+ this.caseChanged = this.setCase === value.new;
50
+ }
51
+
52
+ menuChanged = false;
53
+ @Prop() menus = 'a';
54
+ @Watch('menus')
55
+ changeMenus(value: any) {
56
+ this.menuChanged = this.menus === value.new;
57
+ }
58
+
59
+ enabledChanged = false;
60
+ @Toggle() enabled: any;
61
+ @Watch('enabled')
62
+ changeEnable(value: any) {
63
+ this.enabledChanged = this.enabled.toString() === value.new;
64
+ }
65
+ }
66
+
67
+ describe('watch decorator', () => {
68
+ let myElementInstance: any;
69
+
70
+ beforeEach(() => {
71
+ const myElement = document.createElement('watch-element');
72
+ myElementInstance = document.body.appendChild(myElement);
73
+ });
74
+
75
+ afterEach(() => {
76
+ document.body.innerHTML = '';
77
+ });
78
+
79
+ it('should re-render setting property', () => {
80
+ myElementInstance.name = 'Aivan';
81
+ expect(myElementInstance.shadowRoot.querySelector('span').innerHTML).toEqual('Aivan');
82
+ });
83
+
84
+ it('should call method decorated with @Watch on prop change', () => {
85
+ const watchSpy = vi.spyOn(myElementInstance, 'setSpan');
86
+ myElementInstance.name = 'Aivan';
87
+ expect(watchSpy).toHaveBeenCalled();
88
+ });
89
+
90
+ it('should call method decorated with @Watch on prop change', () => {
91
+ const watchSpy = vi.spyOn(myElementInstance, 'setSpan');
92
+ myElementInstance.setAttribute('name', 'Mario');
93
+ expect(watchSpy).toHaveBeenCalledWith(...[{ old: null, new: 'Mario' }]);
94
+ expect(myElementInstance.name).toEqual('Mario');
95
+ });
96
+
97
+ it('should call @Watch on attribute change with new property value', () => {
98
+ myElementInstance.setAttribute('color', 'red');
99
+ expect(myElementInstance.newColor).toEqual('red');
100
+ });
101
+
102
+ it('should call @Watch for initial kebab-resolved default prop value', () => {
103
+ expect(myElementInstance.initialColor).toEqual('blue');
104
+ });
105
+
106
+ it('should call @Watch for plain get/set with correct value.new', () => {
107
+ myElementInstance.setAttribute('label', 'Name');
108
+ expect(myElementInstance.newLabel).toEqual('Name');
109
+ });
110
+
111
+ it('should call non kebab @Watch on kebab attribute change with new property value', () => {
112
+ myElementInstance.setAttribute('set-case', 'kebab');
113
+ expect(myElementInstance.setCase).toEqual('kebab');
114
+ expect(myElementInstance.caseChanged).toBeTruthy();
115
+ });
116
+
117
+ it('should call kebab @Watch on kebab attribute change with new property value', () => {
118
+ myElementInstance.setAttribute('set-case', 'snake');
119
+ expect(myElementInstance.setCase).toEqual('snake');
120
+ expect(myElementInstance.caseChanged).toBeTruthy();
121
+ });
122
+
123
+ it('should call @Watch on property change with new property value', () => {
124
+ const menus = [
125
+ {
126
+ text: 'Colors',
127
+ link: '/user-interface/style-guides/colors',
128
+ },
129
+ {
130
+ text: 'Logo',
131
+ link: '/user-interface/style-guides/logo',
132
+ },
133
+ ];
134
+ myElementInstance.menus = menus;
135
+ expect(myElementInstance.menus).toEqual(menus);
136
+ expect(myElementInstance.menuChanged).toBeTruthy();
137
+ });
138
+
139
+ it('should call @Watch on toggle attribute with new property value', () => {
140
+ myElementInstance.enabled = true;
141
+ expect(myElementInstance.enabledChanged).toBeTruthy();
142
+ });
143
+
144
+ it('should register watch metadata on the constructor for all watched attributes', () => {
145
+ const meta = (WatchElement as any).watchAttributes as Record<string, string>;
146
+ const propsInit = (WatchElement as any).propsInit as Record<string, unknown>;
147
+
148
+ expect(meta['name']).toBe('setSpan');
149
+ expect(meta['label']).toBe('setLabel');
150
+ expect(meta['color']).toBe('changeColor');
151
+ // camelCase key is kebab-cased in metadata
152
+ expect(meta['set-case']).toBe('changeCase');
153
+ // kebab key is preserved
154
+ expect(meta['set-kebab']).toBe('changeKebabCase');
155
+ expect(meta['menus']).toBe('changeMenus');
156
+ expect(meta['enabled']).toBe('changeEnable');
157
+
158
+ // propsInit entries are created (null placeholders)
159
+ ['name', 'label', 'color', 'setCase', 'set-kebab', 'menus', 'enabled'].forEach((k) => {
160
+ expect(propsInit).toHaveProperty(k);
161
+ });
162
+ });
163
+ });
164
+
165
+ // Ensure subsequent @Watch registrations on the same attribute update the mapping (last one wins)
166
+ @CustomElement({
167
+ tag: 'dupe-watch-element',
168
+ template: '<span>dupe</span>',
169
+ })
170
+ class DupeWatchElement extends HTMLElement {
171
+ @Watch('foo')
172
+ first(_v: any) {}
173
+
174
+ @Watch('foo')
175
+ second(_v: any) {}
176
+ }
177
+
178
+ describe('watch decorator duplicate attribute handling', () => {
179
+ it('last @Watch for same attribute should win in metadata map', () => {
180
+ const meta = (DupeWatchElement as any).watchAttributes as Record<string, string>;
181
+ expect(meta['foo']).toBe('second');
182
+ });
183
+ });
package/tools/build.js ADDED
@@ -0,0 +1,119 @@
1
+ const { execSync } = require('child_process');
2
+ const { existsSync, mkdirSync, copyFileSync } = require('fs');
3
+ const path = require('path');
4
+ const { config, ELEMENT_NAME } = require('./rollup-config');
5
+ const rollup = require('rollup');
6
+ const rimraf = require('rimraf');
7
+ const { copyFile } = require('fs').promises;
8
+ const glob = require('glob');
9
+ const { readFileSync, writeFileSync } = require('fs');
10
+
11
+ const DEST_PATH = 'dist';
12
+ // Inline every demo source so a demo (like `site`) can freely import sibling
13
+ // demos and have their templateUrl/styleUrl references resolved.
14
+ const SRC_PATH = `demos/**/*.ts`;
15
+ const SRC_TMP_PATH = `.tmp`;
16
+
17
+ const STATIC_ASSET_EXTS = new Set([
18
+ '.css', '.svg', '.png', '.jpg', '.jpeg', '.gif',
19
+ '.ico', '.webp', '.woff', '.woff2', '.ttf', '.otf'
20
+ ]);
21
+
22
+ function copyStaticAssets(srcDir, destDir) {
23
+ const files = glob.sync(`${srcDir}/**/*`, { nodir: true });
24
+ for (const file of files) {
25
+ const ext = path.extname(file).toLowerCase();
26
+ if (!STATIC_ASSET_EXTS.has(ext)) continue;
27
+ const rel = path.relative(srcDir, file);
28
+ const dest = path.join(destDir, rel);
29
+ const destSubDir = path.dirname(dest);
30
+ if (!existsSync(destSubDir)) mkdirSync(destSubDir, { recursive: true });
31
+ copyFileSync(file, dest);
32
+ }
33
+ }
34
+
35
+ function copyDemoShell() {
36
+ if (!existsSync(DEST_PATH)) mkdirSync(DEST_PATH, { recursive: true });
37
+ const indexSrc = `demos/${ELEMENT_NAME}/index.html`;
38
+ if (existsSync(indexSrc)) {
39
+ copyFileSync(indexSrc, path.join(DEST_PATH, 'index.html'));
40
+ }
41
+ copyStaticAssets(`demos/${ELEMENT_NAME}`, DEST_PATH);
42
+ }
43
+
44
+ async function clean(dir) {
45
+ return new Promise((resolve, reject) => {
46
+ rimraf(dir, (err) => {
47
+ if (err) reject(err);
48
+ else resolve();
49
+ });
50
+ });
51
+ }
52
+
53
+ async function inlineSources(srcPattern, destPath) {
54
+ const files = glob.sync(srcPattern);
55
+
56
+ if (!existsSync(destPath)) {
57
+ mkdirSync(destPath, { recursive: true });
58
+ }
59
+
60
+ for (const file of files) {
61
+ let content = readFileSync(file, 'utf-8');
62
+ const relativePath = path.relative('demos', file);
63
+ const destFile = path.join(destPath, relativePath);
64
+ const destDir = path.dirname(destFile);
65
+
66
+ if (!existsSync(destDir)) {
67
+ mkdirSync(destDir, { recursive: true });
68
+ }
69
+
70
+ // Inline templateUrl and styleUrl references
71
+ content = inlineTemplates(content, path.dirname(file));
72
+
73
+ writeFileSync(destFile, content);
74
+ }
75
+ }
76
+
77
+ function inlineTemplates(content, basePath) {
78
+ // Match templateUrl: './file.html'
79
+ const templateUrlRegex = /templateUrl:\s*['"`]([^'"`]+)['"`]/g;
80
+ content = content.replace(templateUrlRegex, (match, filePath) => {
81
+ const fullPath = path.join(basePath, filePath);
82
+ if (existsSync(fullPath)) {
83
+ const template = readFileSync(fullPath, 'utf-8')
84
+ .replace(/`/g, '\\`')
85
+ .replace(/\$/g, '\\$');
86
+ return `template: \`${template}\``;
87
+ }
88
+ return match;
89
+ });
90
+
91
+ // Match styleUrl: './file.scss' or './file.css'
92
+ const styleUrlRegex = /styleUrl:\s*['"`]([^'"`]+)['"`]/g;
93
+ content = content.replace(styleUrlRegex, (match, filePath) => {
94
+ const fullPath = path.join(basePath, filePath);
95
+ if (existsSync(fullPath)) {
96
+ let style = readFileSync(fullPath, 'utf-8');
97
+ // For SCSS files, we'd normally compile them, but for now just use as CSS
98
+ style = style.replace(/`/g, '\\`').replace(/\$/g, '\\$');
99
+ return `style: \`${style}\``;
100
+ }
101
+ return match;
102
+ });
103
+
104
+ return content;
105
+ }
106
+
107
+ async function rollupGenerate(config) {
108
+ const bundle = await rollup.rollup(config.inputOptions);
109
+ await bundle.write(config.outputOptions);
110
+ }
111
+
112
+ Promise.all([clean(DEST_PATH), clean(SRC_TMP_PATH)])
113
+ .then(() => inlineSources(SRC_PATH, SRC_TMP_PATH))
114
+ .then(() => rollupGenerate(config))
115
+ .then(() => copyDemoShell())
116
+ .catch(err => {
117
+ console.error('Build failed:', err);
118
+ process.exit(1);
119
+ });
@@ -0,0 +1,167 @@
1
+ const path = require('path');
2
+ const rollup = require('rollup');
3
+ const { nodeResolve } = require('@rollup/plugin-node-resolve');
4
+ const typescript = require('rollup-plugin-typescript2');
5
+ const ts = require('typescript');
6
+ const rimraf = require('rimraf');
7
+ const { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync } = require('fs');
8
+ const MagicString = require('magic-string');
9
+
10
+ const LIB_NAME = 'custom-elements-ts';
11
+
12
+ // removing custom comment-strip plugin; modern toolchain handles comments safely
13
+
14
+ const createConfig = () => {
15
+ return ['umd', 'esm5', 'esm2015'].map((format) => {
16
+ const tsConfig = {
17
+ compilerOptions: {
18
+ target: format.includes('esm2015') ? 'es2015' : 'es5',
19
+ declaration: false,
20
+ },
21
+ };
22
+
23
+ const file = format.includes('umd')
24
+ ? path.join('dist', 'bundles', `${LIB_NAME}.umd.js`)
25
+ : path.join('dist', format, `${LIB_NAME}.js`);
26
+
27
+ const formatType = format.includes('umd') ? 'umd' : 'es';
28
+
29
+ return {
30
+ inputOptions: {
31
+ treeshake: true,
32
+ input: 'src/index.ts',
33
+ plugins: [
34
+ typescript({
35
+ tsconfig: 'src/tsconfig.json',
36
+ tsconfigOverride: { ...tsConfig },
37
+ check: false,
38
+ cacheRoot: path.join(path.resolve(), 'node_modules/.tmp/.rts2_cache'),
39
+ // ensure tslib helpers are injected correctly for ES5 target
40
+ tslib: require.resolve('tslib'),
41
+ }),
42
+ nodeResolve(),
43
+ ],
44
+ onwarn(warning) {
45
+ if (warning.code === 'THIS_IS_UNDEFINED') {
46
+ return;
47
+ }
48
+ console.log('Rollup warning: ', warning.message);
49
+ },
50
+ },
51
+ outputOptions: {
52
+ sourcemap: true,
53
+ file: file,
54
+ name: LIB_NAME,
55
+ format: formatType,
56
+ },
57
+ };
58
+ });
59
+ };
60
+
61
+ async function clean(dir) {
62
+ return new Promise((resolve, reject) => {
63
+ rimraf(dir, (err) => {
64
+ if (err) reject(err);
65
+ else resolve();
66
+ });
67
+ });
68
+ }
69
+
70
+ async function rollupBuild(config) {
71
+ const bundle = await rollup.rollup(config.inputOptions);
72
+ await bundle.write(config.outputOptions);
73
+ }
74
+
75
+ const emitDtsFiles = () => {
76
+ const configPath = path.resolve('src', 'tsconfig.json');
77
+ const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
78
+ if (configFile.error) {
79
+ throw new Error(ts.formatDiagnosticsWithColorAndContext([configFile.error], formatHost));
80
+ }
81
+
82
+ const parsedConfig = ts.parseJsonConfigFileContent(
83
+ configFile.config,
84
+ ts.sys,
85
+ path.resolve('src'),
86
+ {
87
+ declaration: true,
88
+ declarationDir: path.resolve('dist'),
89
+ emitDeclarationOnly: true,
90
+ outDir: path.resolve('dist'),
91
+ rootDir: path.resolve('src'),
92
+ sourceMap: false,
93
+ },
94
+ configPath
95
+ );
96
+
97
+ const program = ts.createProgram(parsedConfig.fileNames, parsedConfig.options);
98
+ const emitResult = program.emit();
99
+ const diagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
100
+ const errors = diagnostics.filter(
101
+ (diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error
102
+ );
103
+ if (errors.length > 0) {
104
+ throw new Error(ts.formatDiagnosticsWithColorAndContext(errors, formatHost));
105
+ }
106
+ };
107
+
108
+ const formatHost = {
109
+ getCanonicalFileName: (fileName) => fileName,
110
+ getCurrentDirectory: () => process.cwd(),
111
+ getNewLine: () => '\n',
112
+ };
113
+
114
+ const copyReadMe = () => {
115
+ if (existsSync('README.md')) {
116
+ copyFileSync('README.md', path.join('dist', 'README.md'));
117
+ }
118
+ };
119
+
120
+ const buildCopyPackageFile = (libName, paths) => {
121
+ const pkg = JSON.parse(readFileSync('package.json', 'utf-8'));
122
+ const distPkg = {
123
+ name: libName,
124
+ version: pkg.version,
125
+ description: pkg.description,
126
+ main: paths.main,
127
+ module: paths.module,
128
+ esm5: paths.esm5,
129
+ esm2015: paths.esm2015,
130
+ typings: paths.typings,
131
+ peerDependencies: pkg.peerDependencies,
132
+ repository: pkg.repository,
133
+ keywords: pkg.keywords,
134
+ author: pkg.author,
135
+ license: pkg.license,
136
+ bugs: pkg.bugs,
137
+ homepage: pkg.homepage,
138
+ };
139
+
140
+ if (!existsSync('dist')) {
141
+ mkdirSync('dist', { recursive: true });
142
+ }
143
+
144
+ if (!existsSync('dist/bundles')) {
145
+ mkdirSync('dist/bundles', { recursive: true });
146
+ }
147
+
148
+ writeFileSync(path.join('dist', 'package.json'), JSON.stringify(distPkg, null, 2));
149
+ };
150
+
151
+ const copyPkgFile = () =>
152
+ buildCopyPackageFile(LIB_NAME, {
153
+ main: `./bundles/${LIB_NAME}.umd.js`,
154
+ esm5: `./esm5/${LIB_NAME}.js`,
155
+ module: `./esm2015/${LIB_NAME}.js`,
156
+ esm2015: `./esm2015/${LIB_NAME}.js`,
157
+ typings: 'index.d.ts',
158
+ });
159
+
160
+ Promise.all([clean('dist'), clean('.tmp')])
161
+ .then(() => Promise.all(createConfig().map((config) => rollupBuild(config))))
162
+ .then(() => emitDtsFiles())
163
+ .then(() => Promise.all([copyPkgFile(), copyReadMe()]))
164
+ .catch((err) => {
165
+ console.error('Bundle failed:', err);
166
+ process.exit(1);
167
+ });
@@ -0,0 +1,70 @@
1
+ const path = require('path');
2
+ const typescript = require('rollup-plugin-typescript2');
3
+ const { nodeResolve } = require('@rollup/plugin-node-resolve');
4
+ const terserPlugin = require('@rollup/plugin-terser');
5
+ const terser = terserPlugin.terser || terserPlugin;
6
+ const { existsSync } = require('fs');
7
+
8
+ const ELEMENT_NAME = process.argv[2];
9
+ const DEST_PATH = 'dist';
10
+
11
+ const prodModeParams = ['--prod', '--prod=true', '--prod true'];
12
+
13
+ const ELEMENT_PATH = `${ELEMENT_NAME}/index.ts`;
14
+ const INPUT_PATH = path.join('.tmp', ELEMENT_PATH);
15
+
16
+ if (ELEMENT_NAME == undefined) {
17
+ console.log('specify which element to start');
18
+ console.log(' ↳ eg. npm start element-name');
19
+ process.exit();
20
+ }
21
+
22
+ if (!existsSync(`demos/${ELEMENT_PATH}`)) {
23
+ console.log('element does not exist');
24
+ process.exit();
25
+ }
26
+
27
+ const toPascalCase = (text) => {
28
+ return text.replace(/-\w/g, m => m[1].toUpperCase())
29
+ .replace(/^\w/, c => c.toUpperCase());
30
+ }
31
+
32
+ function isProcess(params) {
33
+ return params.some(param => process.argv.includes(param));
34
+ }
35
+
36
+ const config = {
37
+ inputOptions: {
38
+ treeshake: true,
39
+ input: INPUT_PATH,
40
+ plugins: [
41
+ typescript({
42
+ useTsconfigDeclarationDir: true,
43
+ check: false,
44
+ cacheRoot: path.join(path.resolve(), 'node_modules/.tmp/.rts2_cache')
45
+ }),
46
+ nodeResolve()
47
+ ],
48
+ onwarn(warning) {
49
+ if (warning.code === 'THIS_IS_UNDEFINED') { return; }
50
+ console.log("Rollup warning: ", warning.message);
51
+ }
52
+ },
53
+ outputOptions: {
54
+ sourcemap: true,
55
+ exports: 'named',
56
+ name: toPascalCase(ELEMENT_NAME),
57
+ file: `${DEST_PATH}/${ELEMENT_NAME}.umd.js`,
58
+ format: 'umd'
59
+ }
60
+ };
61
+
62
+ if (isProcess(prodModeParams)) {
63
+ const options = {
64
+ mangle: { keep_fnames: true }
65
+ };
66
+ config.inputOptions.plugins.push(terser(options));
67
+ }
68
+
69
+ exports.config = config;
70
+ exports.ELEMENT_NAME = ELEMENT_NAME;