@openwebf/webf 0.23.7 → 0.24.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.
package/src/vue.ts CHANGED
@@ -2,10 +2,9 @@ import _ from "lodash";
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
4
  import {ParameterType} from "./analyzer";
5
- import {ClassObject, FunctionArgumentType, FunctionDeclaration, ConstObject, EnumObject} from "./declaration";
5
+ import {ClassObject, FunctionArgumentType, FunctionDeclaration, ConstObject, EnumObject, TypeAliasObject} from "./declaration";
6
6
  import {IDLBlob} from "./IDLBlob";
7
- import { debug } from './logger';
8
- import {getPointerType, isPointerType, isUnionType, trimNullTypeFromType} from "./utils";
7
+ import {getPointerType, isPointerType, isUnionType} from "./utils";
9
8
 
10
9
  function readTemplate(name: string) {
11
10
  return fs.readFileSync(path.join(__dirname, '../templates/' + name + '.tpl'), {encoding: 'utf-8'});
@@ -49,18 +48,17 @@ function generateReturnType(type: ParameterType): string {
49
48
  if (pointerType === 'Type') return 'any';
50
49
  if (typeof pointerType === 'string' && pointerType.startsWith('typeof ')) {
51
50
  const ident = pointerType.substring('typeof '.length).trim();
52
- return `typeof __webfTypes.${ident}`;
51
+ return `typeof ${ident}`;
53
52
  }
54
53
  return pointerType;
55
54
  }
56
55
  if (type.isArray && typeof type.value === 'object' && !Array.isArray(type.value)) {
57
- const elemType = getPointerType(type.value);
58
- if (elemType === 'Type') return 'any[]';
59
- if (typeof elemType === 'string' && elemType.startsWith('typeof ')) {
60
- const ident = elemType.substring('typeof '.length).trim();
61
- return `(typeof __webfTypes.${ident})[]`;
56
+ const elemType = generateReturnType(type.value);
57
+ if (!elemType) return 'any[]';
58
+ if (/^[A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(elemType)) {
59
+ return `${elemType}[]`;
62
60
  }
63
- return `${elemType}[]`;
61
+ return `(${elemType})[]`;
64
62
  }
65
63
  switch (type.value) {
66
64
  case FunctionArgumentType.int:
@@ -112,148 +110,139 @@ function generateMethodDeclaration(method: FunctionDeclaration) {
112
110
  return `${methodName}(${args}): ${returnType};`;
113
111
  }
114
112
 
115
- function generateVueComponent(blob: IDLBlob) {
116
- const classObjects = blob.objects as ClassObject[];
117
-
118
- // Skip if no class objects
119
- if (!classObjects || classObjects.length === 0) {
120
- return '';
121
- }
122
- const classObjectDictionary = Object.fromEntries(
123
- classObjects.map(object => {
124
- return [object.name, object];
125
- })
126
- );
113
+ type VueComponentSpec = {
114
+ className: string;
115
+ properties?: ClassObject;
116
+ events?: ClassObject;
117
+ methods?: ClassObject;
118
+ };
127
119
 
128
- const properties = classObjects.filter(object => {
129
- return object.name.endsWith('Properties');
130
- });
131
- const events = classObjects.filter(object => {
132
- return object.name.endsWith('Events');
133
- });
120
+ function getVueComponentSpecs(blob: IDLBlob): VueComponentSpec[] {
121
+ const classObjects = blob.objects.filter(obj => obj instanceof ClassObject) as ClassObject[];
122
+ if (classObjects.length === 0) return [];
134
123
 
135
- const others = classObjects.filter(object => {
136
- return !object.name.endsWith('Properties')
137
- && !object.name.endsWith('Events');
138
- });
124
+ const properties = classObjects.filter(object => object.name.endsWith('Properties'));
125
+ const events = classObjects.filter(object => object.name.endsWith('Events'));
126
+ const methods = classObjects.filter(object => object.name.endsWith('Methods'));
139
127
 
140
- const dependencies = others.map(object => {
141
- if (!object || !object.props || object.props.length === 0) {
142
- return '';
143
- }
128
+ const componentMap = new Map<string, VueComponentSpec>();
144
129
 
145
- const interfaceLines: string[] = [];
130
+ properties.forEach(prop => {
131
+ const className = prop.name.replace(/Properties$/, '');
132
+ if (!componentMap.has(className)) componentMap.set(className, { className });
133
+ componentMap.get(className)!.properties = prop;
134
+ });
146
135
 
147
- if (object.documentation && object.documentation.trim().length > 0) {
148
- interfaceLines.push('/**');
149
- object.documentation.split('\n').forEach(line => {
150
- interfaceLines.push(` * ${line}`);
151
- });
152
- interfaceLines.push(' */');
153
- }
136
+ events.forEach(ev => {
137
+ const className = ev.name.replace(/Events$/, '');
138
+ if (!componentMap.has(className)) componentMap.set(className, { className });
139
+ componentMap.get(className)!.events = ev;
140
+ });
154
141
 
155
- interfaceLines.push(`interface ${object.name} {`);
142
+ methods.forEach(m => {
143
+ const className = m.name.replace(/Methods$/, '');
144
+ if (!componentMap.has(className)) componentMap.set(className, { className });
145
+ componentMap.get(className)!.methods = m;
146
+ });
156
147
 
157
- const propLines = object.props.map(prop => {
158
- const lines: string[] = [];
148
+ return Array.from(componentMap.values())
149
+ .filter(spec => spec.className.trim().length > 0)
150
+ .sort((a, b) => a.className.localeCompare(b.className));
151
+ }
159
152
 
160
- if (prop.documentation && prop.documentation.trim().length > 0) {
161
- lines.push(' /**');
162
- prop.documentation.split('\n').forEach(line => {
163
- lines.push(` * ${line}`);
164
- });
165
- lines.push(' */');
166
- }
153
+ function renderSupportingInterface(object: ClassObject): string {
154
+ const hasProps = !!object.props && object.props.length > 0;
155
+ const hasMethods = !!object.methods && object.methods.length > 0;
156
+ if (!hasProps && !hasMethods) {
157
+ return '';
158
+ }
167
159
 
168
- const optionalToken = prop.optional ? '?' : '';
169
- lines.push(` ${prop.name}${optionalToken}: ${generateReturnType(prop.type)};`);
160
+ const interfaceLines: string[] = [];
170
161
 
171
- return lines.join('\n');
162
+ if (object.documentation && object.documentation.trim().length > 0) {
163
+ interfaceLines.push('/**');
164
+ object.documentation.split('\n').forEach(line => {
165
+ interfaceLines.push(` * ${line}`);
172
166
  });
167
+ interfaceLines.push(' */');
168
+ }
173
169
 
174
- interfaceLines.push(propLines.join('\n'));
175
- interfaceLines.push('}');
170
+ interfaceLines.push(`export interface ${object.name} {`);
176
171
 
177
- return interfaceLines.join('\n');
178
- }).filter(dep => dep.trim() !== '').join('\n\n');
172
+ const propLines = (object.props || []).map(prop => {
173
+ const lines: string[] = [];
179
174
 
180
- const componentProperties = properties.length > 0 ? properties[0] : undefined;
181
- const componentEvents = events.length > 0 ? events[0] : undefined;
182
- const className = (() => {
183
- if (componentProperties) {
184
- return componentProperties.name.replace(/Properties$/, '');
185
- }
186
- if (componentEvents) {
187
- return componentEvents.name.replace(/Events$/, '');
175
+ if (prop.documentation && prop.documentation.trim().length > 0) {
176
+ lines.push(' /**');
177
+ prop.documentation.split('\n').forEach(line => {
178
+ lines.push(` * ${line}`);
179
+ });
180
+ lines.push(' */');
188
181
  }
189
- return '';
190
- })();
191
182
 
192
- if (!className) {
193
- return '';
194
- }
183
+ const optionalToken = prop.optional ? '?' : '';
184
+ lines.push(` ${prop.name}${optionalToken}: ${generateReturnType(prop.type)};`);
195
185
 
196
- const content = _.template(readTemplate('vue.component.partial'))({
197
- className: className,
198
- properties: componentProperties,
199
- events: componentEvents,
200
- classObjectDictionary,
201
- dependencies,
202
- blob,
203
- generateReturnType,
204
- generateMethodDeclaration,
205
- generateEventHandlerType,
186
+ return lines.join('\n');
206
187
  });
207
188
 
208
- const result = content.split('\n').filter(str => {
209
- return str.trim().length > 0;
210
- }).join('\n');
189
+ interfaceLines.push(propLines.join('\n'));
190
+
191
+ if (object.methods && object.methods.length > 0) {
192
+ const methodLines = object.methods.map(method => {
193
+ return ` ${generateMethodDeclaration(method)}`;
194
+ });
195
+ interfaceLines.push(methodLines.join('\n'));
196
+ }
211
197
 
212
- return result;
198
+ interfaceLines.push('}');
199
+
200
+ return interfaceLines.join('\n');
213
201
  }
214
202
 
215
- function toVueTagName(className: string): string {
203
+ function toVueTagName(rawClassName: string): string {
204
+ const className = rawClassName.trim();
205
+
216
206
  if (className.startsWith('WebF')) {
217
207
  const withoutPrefix = className.substring(4);
218
- return 'web-f-' + _.kebabCase(withoutPrefix);
219
- } else if (className.startsWith('Flutter')) {
208
+ const suffix = _.kebabCase(withoutPrefix);
209
+ return suffix.length > 0 ? 'webf-' + suffix : 'webf';
210
+ }
211
+
212
+ if (className.startsWith('Flutter')) {
220
213
  const withoutPrefix = className.substring(7);
221
- return 'flutter-' + _.kebabCase(withoutPrefix);
214
+ const suffix = _.kebabCase(withoutPrefix);
215
+ return suffix.length > 0 ? 'flutter-' + suffix : 'flutter';
222
216
  }
223
- return _.kebabCase(className);
217
+
218
+ const kebab = _.kebabCase(className);
219
+ return kebab.replace(/^web-f-/, 'webf-');
224
220
  }
225
221
 
226
222
  export function generateVueTypings(blobs: IDLBlob[]) {
227
- const componentNames = blobs.map(blob => {
228
- const classObjects = blob.objects as ClassObject[];
229
-
230
- const properties = classObjects.filter(object => {
231
- return object.name.endsWith('Properties');
223
+ const componentSpecMap = new Map<string, VueComponentSpec>();
224
+ blobs
225
+ .flatMap(blob => getVueComponentSpecs(blob))
226
+ .forEach(spec => {
227
+ if (!componentSpecMap.has(spec.className)) componentSpecMap.set(spec.className, spec);
232
228
  });
233
- const events = classObjects.filter(object => {
234
- return object.name.endsWith('Events');
229
+
230
+ const componentSpecs = Array.from(componentSpecMap.values()).sort((a, b) => a.className.localeCompare(b.className));
231
+ const componentNames = componentSpecs.map(spec => spec.className);
232
+
233
+ const components = componentSpecs.map(spec => {
234
+ const content = _.template(readTemplate('vue.component.partial'))({
235
+ className: spec.className,
236
+ properties: spec.properties,
237
+ events: spec.events,
238
+ methods: spec.methods,
239
+ generateReturnType,
240
+ generateMethodDeclaration,
241
+ generateEventHandlerType,
235
242
  });
236
243
 
237
- const componentProperties = properties.length > 0 ? properties[0] : undefined;
238
- const componentEvents = events.length > 0 ? events[0] : undefined;
239
- const className = (() => {
240
- if (componentProperties) {
241
- return componentProperties.name.replace(/Properties$/, '');
242
- }
243
- if (componentEvents) {
244
- return componentEvents.name.replace(/Events$/, '');
245
- }
246
- return '';
247
- })();
248
- return className;
249
- }).filter(name => {
250
- return name.length > 0;
251
- });
252
- const components = blobs.map(blob => {
253
- return generateVueComponent(blob);
254
- }).filter(component => {
255
- return component.length > 0;
256
- }).join('\n\n');
244
+ return content.split('\n').filter(str => str.trim().length > 0).join('\n');
245
+ }).filter(Boolean).join('\n\n');
257
246
 
258
247
  // Collect declare consts across blobs and render as exported ambient declarations
259
248
  const consts = blobs
@@ -267,6 +256,7 @@ export function generateVueTypings(blobs: IDLBlob[]) {
267
256
  });
268
257
 
269
258
  const constDeclarations = Array.from(uniqueConsts.values())
259
+ .sort((a, b) => a.name.localeCompare(b.name))
270
260
  .map(c => `export declare const ${c.name}: ${c.type};`)
271
261
  .join('\n');
272
262
 
@@ -275,14 +265,53 @@ export function generateVueTypings(blobs: IDLBlob[]) {
275
265
  .flatMap(blob => blob.objects)
276
266
  .filter(obj => obj instanceof EnumObject) as EnumObject[];
277
267
 
278
- const enumDeclarations = enums.map(e => {
279
- const members = e.members.map(m => m.initializer ? `${m.name} = ${m.initializer}` : `${m.name}`).join(', ');
280
- return `export declare enum ${e.name} { ${members} }`;
281
- }).join('\n');
268
+ const uniqueEnums = new Map<string, EnumObject>();
269
+ enums.forEach(e => {
270
+ if (!uniqueEnums.has(e.name)) uniqueEnums.set(e.name, e);
271
+ });
272
+
273
+ const enumDeclarations = Array.from(uniqueEnums.values())
274
+ .sort((a, b) => a.name.localeCompare(b.name))
275
+ .map(e => {
276
+ const members = e.members.map(m => m.initializer ? `${m.name} = ${m.initializer}` : `${m.name}`).join(', ');
277
+ return `export declare enum ${e.name} { ${members} }`;
278
+ })
279
+ .join('\n');
280
+
281
+ // Collect type aliases across blobs and render as exported declarations.
282
+ const typeAliases = blobs
283
+ .flatMap(blob => blob.objects)
284
+ .filter(obj => obj instanceof TypeAliasObject) as TypeAliasObject[];
285
+
286
+ const uniqueTypeAliases = new Map<string, TypeAliasObject>();
287
+ typeAliases.forEach(t => {
288
+ if (!uniqueTypeAliases.has(t.name)) uniqueTypeAliases.set(t.name, t);
289
+ });
290
+
291
+ const typeAliasDeclarations = Array.from(uniqueTypeAliases.values())
292
+ .sort((a, b) => a.name.localeCompare(b.name))
293
+ .map(t => `export type ${t.name} = ${t.type};`)
294
+ .join('\n');
295
+
296
+ // Collect supporting interfaces (non-component interfaces) so referenced types exist.
297
+ const supportingInterfaces = blobs
298
+ .flatMap(blob => blob.objects)
299
+ .filter(obj => obj instanceof ClassObject) as ClassObject[];
300
+
301
+ const supporting = supportingInterfaces.filter(obj => {
302
+ return !obj.name.endsWith('Properties') && !obj.name.endsWith('Events') && !obj.name.endsWith('Methods');
303
+ });
304
+
305
+ const uniqueSupporting = new Map<string, ClassObject>();
306
+ supporting.forEach(obj => {
307
+ if (!uniqueSupporting.has(obj.name)) uniqueSupporting.set(obj.name, obj);
308
+ });
282
309
 
283
- // Always import the types namespace to support typeof references
284
- const typesImport = `import * as __webfTypes from './src/types';`;
285
- debug(`[vue] Generating typings; importing types from ./src/types`);
310
+ const supportingDeclarations = Array.from(uniqueSupporting.values())
311
+ .sort((a, b) => a.name.localeCompare(b.name))
312
+ .map(obj => renderSupportingInterface(obj))
313
+ .filter(Boolean)
314
+ .join('\n\n');
286
315
 
287
316
  // Build mapping of template tag names to class names for GlobalComponents
288
317
  const componentMetas = componentNames.map(className => ({
@@ -300,7 +329,8 @@ export function generateVueTypings(blobs: IDLBlob[]) {
300
329
  components,
301
330
  consts: constDeclarations,
302
331
  enums: enumDeclarations,
303
- typesImport,
332
+ typeAliases: typeAliasDeclarations,
333
+ dependencies: supportingDeclarations,
304
334
  });
305
335
 
306
336
  return content.split('\n').filter(str => {
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "<%= packageName %>",
3
+ "version": "<%= version %>",
4
+ "description": "<%= description %>",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "files": ["dist"],
9
+ "scripts": {
10
+ "build": "tsup",
11
+ "dev": "tsup --watch",
12
+ "clean": "rimraf dist",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "keywords": [
16
+ "webf",
17
+ "flutter",
18
+ "native",
19
+ "module"
20
+ ],
21
+ "author": "",
22
+ "license": "Apache-2.0",
23
+ "type": "commonjs",
24
+ "dependencies": {
25
+ "@openwebf/webf-enterprise-typings": "^0.23.7"
26
+ },
27
+ "devDependencies": {
28
+ "rimraf": "^5.0.0",
29
+ "tsup": "^8.5.0",
30
+ "typescript": "^5.8.3"
31
+ },
32
+ "publishConfig": {
33
+ "access": "public"
34
+ }
35
+ }
36
+
@@ -0,0 +1,25 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "lib": ["ES2020", "DOM"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "node",
7
+ "esModuleInterop": true,
8
+ "allowSyntheticDefaultImports": true,
9
+ "strict": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "declaration": true,
13
+ "declarationMap": true,
14
+ "outDir": "dist",
15
+ "rootDir": "src"
16
+ },
17
+ "include": [
18
+ "src/**/*"
19
+ ],
20
+ "exclude": [
21
+ "node_modules",
22
+ "dist"
23
+ ]
24
+ }
25
+
@@ -0,0 +1,13 @@
1
+ import { defineConfig } from 'tsup';
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ format: ['cjs', 'esm'],
6
+ dts: true,
7
+ clean: true,
8
+ splitting: false,
9
+ sourcemap: true,
10
+ minify: false,
11
+ external: [],
12
+ });
13
+
@@ -146,8 +146,8 @@ export const <%= className %> = createWebFComponent<<%= className %>Element, <%=
146
146
  {
147
147
  propName: '<%= propName %>',
148
148
  eventName: '<%= prop.name %>',
149
- handler: (callback) => (event) => {
150
- callback((event as <%= getEventType(prop.type) %>));
149
+ handler: (callback: (event: <%= getEventType(prop.type) %>) => void) => (event: Event) => {
150
+ callback(event as <%= getEventType(prop.type) %>);
151
151
  },
152
152
  },
153
153
  <% }); %>
@@ -3,5 +3,6 @@
3
3
  */
4
4
 
5
5
  <% components.forEach(component => { %>
6
- export { <%= component.className %>, <%= component.className %>Element } from "./<%= component.relativeDir ? component.relativeDir + '/' : '' %><%= component.fileName %>";
6
+ export { <%= component.className %> } from "./<%= component.relativeDir ? component.relativeDir + '/' : '' %><%= component.fileName %>";
7
+ export type { <%= component.className %>Element } from "./<%= component.relativeDir ? component.relativeDir + '/' : '' %><%= component.fileName %>";
7
8
  <% }); %>
@@ -5,7 +5,7 @@
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
8
- "files": ["dist"],
8
+ "files": ["dist", "README.md"],
9
9
  "scripts": {
10
10
  "build": "tsup"
11
11
  },
@@ -15,12 +15,11 @@
15
15
  "type": "commonjs",
16
16
  "peerDependencies": {
17
17
  "react": ">=16.8.0",
18
- "react-dom": ">=16.8.0"
19
- },
20
- "dependencies": {
21
- "@openwebf/react-core-ui": "^0.2.1"
18
+ "react-dom": ">=16.8.0",
19
+ "@openwebf/react-core-ui": "^0.24.1"
22
20
  },
23
21
  "devDependencies": {
22
+ "@openwebf/react-core-ui": "^0.24.1",
24
23
  "@types/react": "^19.1.0",
25
24
  "@types/react-dom": "^19.1.2",
26
25
  "picomatch": "^4.0.2",
@@ -10,7 +10,14 @@
10
10
  "esModuleInterop": true,
11
11
  "skipLibCheck": true,
12
12
  "moduleResolution": "node",
13
- "allowSyntheticDefaultImports": true
13
+ "allowSyntheticDefaultImports": true,
14
+ "baseUrl": ".",
15
+ "paths": {
16
+ "react": ["./node_modules/@types/react/index.d.ts"],
17
+ "react-dom": ["./node_modules/@types/react-dom/index.d.ts"],
18
+ "react/jsx-runtime": ["./node_modules/@types/react/jsx-runtime.d.ts"],
19
+ "react/jsx-dev-runtime": ["./node_modules/@types/react/jsx-dev-runtime.d.ts"]
20
+ }
14
21
  },
15
22
  "include": ["src"]
16
23
  }
@@ -6,5 +6,5 @@ export default defineConfig({
6
6
  dts: true,
7
7
  sourcemap: true,
8
8
  clean: true,
9
- external: ['react', 'react-dom'],
9
+ external: ['react', 'react-dom', '@openwebf/react-core-ui'],
10
10
  })
@@ -8,8 +8,8 @@ export type <%= className %>Props = {
8
8
  <% } %>
9
9
  <% }); %>
10
10
  'id'?: string;
11
- 'class'?: string;
12
- 'style'?: string | Record<string, any>;
11
+ 'class'?: ClassValue;
12
+ 'style'?: StyleValue;
13
13
  }
14
14
 
15
15
  export interface <%= className %>Element {
@@ -21,7 +21,7 @@ export interface <%= className %>Element {
21
21
  <%= propName %>: <%= generateReturnType(prop.type) %>;
22
22
  <% } %>
23
23
  <% }); %>
24
- <% _.forEach(properties?.methods, function(method, index) { %>
24
+ <% _.forEach(methods?.methods, function(method, index) { %>
25
25
  <%= generateMethodDeclaration(method) %>
26
26
  <% }); %>
27
27
  }
@@ -29,6 +29,6 @@ export interface <%= className %>Element {
29
29
  export type <%= className %>Events = {
30
30
  <% _.forEach(events?.props, function(prop, index) { %>
31
31
  <% var propName = prop.name; %>
32
- <%= propName %>?: <%= generateEventHandlerType(prop.type) %>;
32
+ <%= propName %>: <%= generateEventHandlerType(prop.type) %>;
33
33
  <% }); %>
34
34
  }
@@ -3,9 +3,10 @@
3
3
  */
4
4
  // Based on the Vue 3 documentation for defining custom elements:
5
5
  // https://vuejs.org/guide/extras/web-components
6
- import { EmitFn, PublicProps, HTMLAttributes } from 'vue';
6
+ import type { EmitFn, PublicProps, StyleValue, ClassValue } from 'vue';
7
+ import '@openwebf/vue-core-ui';
7
8
 
8
- <%= typesImport %>
9
+ <%= typeAliases %>
9
10
 
10
11
  type EventMap = {
11
12
  [event: string]: Event
@@ -13,29 +14,29 @@ type EventMap = {
13
14
 
14
15
  // This maps an EventMap to the format that Vue's $emit type expects.
15
16
  type VueEmit<T extends EventMap> = EmitFn<{
16
- [K in keyof T]: (event: T[K]) => void
17
+ [K in keyof T]: (event: NonNullable<T[K]>) => void
17
18
  }>
18
19
 
19
20
  // Vue 3 event listener properties for template usage
20
21
  type VueEventListeners<T extends EventMap> = {
21
- [K in keyof T as `on${Capitalize<string & K>}`]?: (event: T[K]) => any
22
+ [K in keyof T as `on${Capitalize<string & K>}`]?: (event: NonNullable<T[K]>) => any
22
23
  }
23
24
 
24
25
  <%= consts %>
25
26
  <%= enums %>
27
+ <%= dependencies %>
26
28
 
27
29
  type DefineCustomElement<
28
30
  ElementType,
31
+ Props,
29
32
  Events extends EventMap = {},
30
- SelectedAttributes extends keyof ElementType = keyof ElementType
31
33
  > = new () => ElementType & VueEventListeners<Events> & {
32
34
  // Use $props to define the properties exposed to template type checking. Vue
33
35
  // specifically reads prop definitions from the `$props` type. Note that we
34
- // combine the element's props with the global HTML props and Vue's special
35
- // props.
36
+ // combine the element's props with Vue's special props.
36
37
  /** @deprecated Do not use the $props property on a Custom Element ref,
37
38
  this is for template prop types only. */
38
- $props: Partial<Pick<ElementType, SelectedAttributes>> & PublicProps & VueEventListeners<Events>
39
+ $props: Props & PublicProps & VueEventListeners<Events>
39
40
 
40
41
  // Use $emit to specifically define event types. Vue specifically reads event
41
42
  // types from the `$emit` type. Note that `$emit` expects a particular format
@@ -47,13 +48,27 @@ type DefineCustomElement<
47
48
 
48
49
  <%= components %>
49
50
 
50
- declare module 'vue' {
51
+ declare const flutterAttached: (typeof import('@openwebf/vue-core-ui')) extends { flutterAttached: infer T } ? T : any;
52
+
53
+ declare module '@vue/runtime-core' {
54
+ interface GlobalDirectives {
55
+ vFlutterAttached: typeof flutterAttached;
56
+ }
57
+
51
58
  interface GlobalComponents {
52
59
  <% componentMetas.forEach(comp => { %>
53
60
  '<%= comp.tagName %>': DefineCustomElement<
61
+ <%= comp.className %>Element,
54
62
  <%= comp.className %>Props,
55
63
  <%= comp.className %>Events
56
64
  >
57
65
  <% }) %>
58
66
  }
59
67
  }
68
+
69
+ // Some tooling (older IDE integrations) look for global directive/component typing
70
+ // augmentations on the `vue` module name instead of `@vue/runtime-core`.
71
+ declare module 'vue' {
72
+ interface GlobalDirectives extends import('@vue/runtime-core').GlobalDirectives {}
73
+ interface GlobalComponents extends import('@vue/runtime-core').GlobalComponents {}
74
+ }
@@ -4,14 +4,16 @@
4
4
  "description": "<%= description %>",
5
5
  "main": "",
6
6
  "types": "index.d.ts",
7
- "files": ["index.d.ts"],
7
+ "files": ["index.d.ts", "README.md"],
8
8
  "keywords": [],
9
9
  "author": "",
10
10
  "license": "ISC",
11
11
  "peerDependencies": {
12
- "vue": "^3.0.0"
12
+ "vue": "^3.0.0",
13
+ "@openwebf/vue-core-ui": "^0.24.0"
13
14
  },
14
15
  "devDependencies": {
16
+ "@openwebf/vue-core-ui": "^0.24.0",
15
17
  "vue": "^3.0.0"
16
18
  }
17
19
  }