@stencil/react-output-target
Version:
React output target for @stencil/core components.
80 lines (71 loc) • 10.9 kB
JavaScript
;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const N=require("node:path"),_=require("ts-morph"),F=o=>o.toLowerCase().split("-").map(s=>s.charAt(0).toUpperCase()+s.slice(1)).join(""),U=o=>o.replace(/-([_a-z])/g,(s,u)=>u.toUpperCase()),z=o=>o.replace(/\/([a-z])/g,(s,u)=>u.toUpperCase()),H=o=>{const s=z(o);return U(`on-${s}`)},x=o=>o.replace(/\/\/.*$/gm,"").replace(/\n/g," ").replace(/\s{2,}/g," ").trim(),q=async({components:o,project:s,outDir:u})=>{const i=s||new _.Project({useInMemoryFileSystem:!0}),n=`/* eslint-disable */
`,y=`/**
* This file was automatically generated by the Stencil React Output Target.
* Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
*/
`,f=N.join(u||"","components.ts"),d=i.createSourceFile(f,y+n,{overwrite:!0});for(const $ of o){const b=$.tagName,v=F(b),T=$.tagName;d.addExportDeclaration({moduleSpecifier:`./${T}.js`,namedExports:[v]})}return d.organizeImports(),d.formatText(),await d.save(),d},M=({components:o,stencilPackageName:s,customElementsDir:u,hydrateModule:i,clientModule:n,serializeShadowRoot:y,transformTag:f})=>{const d=new _.Project({useInMemoryFileSystem:!0}),$=i?"":`'use client';
`,b=`/**
* This file was automatically generated by the Stencil React Output Target.
* Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
*/
`,v=`/* eslint-disable */
`,T=f?`import { getTagTransformer } from './tag-transformer.js';
`:"",l=i?["// @ts-ignore - ignore potential type issues as the project is importing itself",`import * as clientComponents from '${n}';`,T,"import { createComponent, type SerializeShadowRootOptions, type HydrateModule, type ReactWebComponent, type DynamicFunction } from '@stencil/react-output-target/ssr';"].filter(Boolean).join(`
`):"import { createComponent } from '@stencil/react-output-target/runtime';",c=f?`import { transformTag } from './tag-transformer.js';
`:"",e=d.createSourceFile("component.ts",`${$}${b}${v}
import React from 'react';
${l}
import type { EventName, StencilReactComponent } from '@stencil/react-output-target/runtime';
${c}
`);i&&e.addVariableStatement({isExported:!0,declarationKind:_.VariableDeclarationKind.Const,declarations:[{name:"serializeShadowRoot",type:"SerializeShadowRootOptions",initializer:y?JSON.stringify(y):'{ default: "declarative-shadow-dom" }'}]});for(const h of o){const a=h.tagName,r=F(a),t=`${r}Element`,g=`${r}CustomEvent`;e.addImportDeclaration({moduleSpecifier:`${s}/${u}/${a}.js`,namedImports:[{name:r,alias:t},{name:"defineCustomElement",alias:`define${r}`}]});const E=(h.events||[]).filter(m=>m.internal===!1),S=[],p=new Set;let j=!1;for(const m of E){if(Object.keys(m.complexType.references).length>0)for(const I of Object.keys(m.complexType.references))!(m.complexType.references[I].location==="global")&&!p.has(I)&&(p.add(I),e.addImportDeclaration({moduleSpecifier:s,namedImports:[{name:I,isTypeOnly:!0}]}));j||(j=!0,e.addImportDeclaration({moduleSpecifier:s,namedImports:[{name:g,isTypeOnly:!0}]})),S.push({originalName:m.name,name:H(m.name),type:`EventName<${g}<${x(m.complexType.original)}>>`})}const w=`${r}Events`;e.addTypeAlias({isExported:!0,name:w,type:S.length>0?`{ ${S.map(m=>`${m.name}: ${m.type}`).join(`,
`)} }`:"NonNullable<unknown>"});const R=f?`,
transformTag`:"",A=`/*@__PURE__*/ createComponent<${t}, ${w}>({
tagName: '${a}',
elementClass: ${t},
// @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
react: React,
events: {${S.map(m=>`${m.name}: '${m.originalName}'`).join(`,
`)}} as ${w},
defineCustomElement: define${r}${R}
})`,D=f?`,
getTagTransformer`:"",L=`/*@__PURE__*/ createComponent<${t}, ${w}>({
tagName: '${a}',
properties: {${h.properties.filter(m=>!!m.attribute).map(m=>`${m.name}: '${m.attribute}'`).join(`,
`)}},
hydrateModule: import('${i}') as Promise<HydrateModule>,
clientModule: clientComponents.${r} as ReactWebComponent<${t}, ${w}>,
serializeShadowRoot${D}
})`;e.addVariableStatement({isExported:!0,declarationKind:_.VariableDeclarationKind.Const,declarations:[{name:r,type:`StencilReactComponent<${t}, ${w}>`,initializer:i?L:A}]})}return e.organizeImports(),e.formatText(),e.getFullText()},K=({stencilPackageName:o,customElementsDir:s})=>`/* eslint-disable */
/* tslint:disable */
import { setTagTransformer as clientSetTagTransformer } from '${o}/${s}/index.js';
let tagTransformer: ((tagName: string) => string) | undefined;
export const setTagTransformer = (transformer: (tagName: string) => string) => {
clientSetTagTransformer(transformer);
tagTransformer = transformer;
};
export const transformTag = (tag: string): string => {
return tagTransformer ? tagTransformer(tag) : tag;
};
export const getTagTransformer = () => tagTransformer;
`,V=async({stencilPackageName:o,components:s,outDir:u,esModules:i,customElementsDir:n,excludeComponents:y,project:f,hydrateModule:d,clientModule:$,excludeServerSideRenderingFor:b,serializeShadowRoot:v,transformTag:T})=>{const l=[],c=s.filter(a=>!(a.internal===!0||y!=null&&y.includes(a.tagName)));if(c.length===0)return[];const e={};function h(a,r="components"){const t=N.join(u,`${r}.ts`),g=M({components:a,stencilPackageName:o,customElementsDir:n,transformTag:T});if(e[t]=g,T){const E=N.join(u,"tag-transformer.ts");e[E]=K({stencilPackageName:o,customElementsDir:n})}if(d){const E=N.join(u,`${r}.server.ts`),S=M({components:a.filter(p=>!b||!b.includes(p.tagName)),stencilPackageName:o,customElementsDir:n,hydrateModule:d,clientModule:$,serializeShadowRoot:v,transformTag:T});e[E]=S}}if(i){for(const r of c)h([r],r.tagName);const a=await q({components:c,project:f,outDir:u});l.push(a)}else h(c);return await Promise.all(Object.entries(e).map(async([a,r])=>{const t=f.createSourceFile(a,r,{overwrite:!0});await t.save(),l.push(t)})),l},J=o=>`on${o.toLowerCase()}`,G=({components:o,stencilPackageName:s,excludeComponents:u})=>{var $,b,v,T,l,c;const i=o.filter(e=>!(e.internal===!0||u!=null&&u.includes(e.tagName)));if(i.length===0)return"";const n=[];n.push(`/**
* This file was automatically generated by the Stencil React Output Target.
* Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
*
* This file provides TypeScript type definitions for using Stencil web components
* as native custom elements in React 19+.
*
* Usage:
* Import this file in your React application to get type support for custom elements:
* \`\`\`tsx
* import '${s}/react-native-types';
* \`\`\`
*/
/* eslint-disable */
/* tslint:disable */
`),n.push("// @ts-ignore - React types may not be available in all build contexts"),n.push("import 'react';"),n.push("// @ts-ignore - React types may not be available in all build contexts"),n.push("import type { DetailedHTMLProps, HTMLAttributes } from 'react';");const y=new Set,f=new Set;for(const e of i){const h=F(e.tagName),a=(e.events||[]).filter(t=>!t.internal);a.length>0&&y.add(`${h}CustomEvent`);for(const t of a)if(($=t.complexType)!=null&&$.references)for(const[g,E]of Object.entries(t.complexType.references))E.location!=="global"&&f.add(g);const r=(e.properties||[]).filter(t=>!t.internal);for(const t of r)if((b=t.complexType)!=null&&b.references)for(const[g,E]of Object.entries(t.complexType.references))E.location!=="global"&&f.add(g)}const d=new Set([...y,...f]);d.size>0&&n.push(`import type { ${Array.from(d).sort().join(", ")} } from '${s}';`),n.push("");for(const e of i){const h=e.tagName,a=F(h),r=`${a}NativeProps`,t=`${a}CustomEvent`,g=[],E=(e.properties||[]).filter(p=>!p.internal);for(const p of E){const j=((v=p.complexType)==null?void 0:v.original)||"any",w=(T=p.docs)!=null&&T.text?` /** ${p.docs.text.trim()} */
`:"",R=p.name;g.push(`${w} '${R}'?: ${x(j)};`)}const S=(e.events||[]).filter(p=>!p.internal);for(const p of S){const j=x(((l=p.complexType)==null?void 0:l.original)||"void"),w=(c=p.docs)!=null&&c.text?` /** Event: ${p.name} - ${p.docs.text.trim()} */
`:` /** Event: ${p.name} */
`,R=J(p.name);g.push(`${w} '${R}'?: (event: ${t}<${j}>) => void;`)}g.length>0?(n.push(`interface ${r} {`),n.push(g.join(`
`)),n.push("}")):n.push(`interface ${r} {}`),n.push("")}n.push("declare module 'react/jsx-runtime' {"),n.push(" namespace JSX {"),n.push(" interface IntrinsicElements {");for(const e of i){const h=e.tagName,a=F(h),r=`${a}NativeProps`,t=`HTML${a}Element`;n.push(` '${h}': DetailedHTMLProps<HTMLAttributes<${t}> & ${r}, ${t}>;`)}return n.push(" }"),n.push(" }"),n.push("}"),n.push(""),n.join(`
`)},W="react-native-types.d.ts",C="react-output-target",k="dist/components",O="dist-custom-elements",P="dist-hydrate-script",B=({outDir:o,nativeTypesPath:s,esModules:u,stencilPackageName:i,excludeComponents:n,customElementsDir:y,hydrateModule:f,clientModule:d,excludeServerSideRenderingFor:$,serializeShadowRoot:b,transformTag:v})=>{let T=k;return{type:"custom",name:C,validate(l){if(!o&&!s)throw new Error(`The '${C}' requires either 'outDir' or 'nativeTypesPath' to be specified.`);if(o){if(y)T=y;else{const c=(l.outputTargets||[]).find(e=>e.type===O);if(c==null)throw new Error(`The '${C}' requires '${O}' output target when 'outDir' is specified. Add { type: '${O}' }, to the outputTargets config.`);if(c.dir!==void 0&&(T=c.dir),c.externalRuntime!==!1)throw new Error(`The '${C}' requires the '${O}' output target to have 'externalRuntime: false' set in its configuration.`)}if(f){if((l.outputTargets||[]).find(e=>e.type===P)==null)throw new Error(`The '${C}' requires '${P}' output target when the 'hydrateModule' option is set. Add { type: '${P}' }, to the outputTargets config.`);if(d==null)throw new Error(`The '${C}' requires the 'clientModule' option when the 'hydrateModule' option is set. Please provide the clientModule manually to the ${C} output target.`)}}if(i===void 0){if(l.sys&&l.packageJsonFilePath){const{name:c}=JSON.parse(l.sys.readFileSync(l.packageJsonFilePath,"utf8"));i=c}if(!i)throw new Error(`Unable to find the package name in the package.json file: ${l.packageJsonFilePath}. Please provide the stencilPackageName manually to the ${C} output target.`)}},async generator(l,c,e){const h=e.createTimeSpan(`generate ${C} started`,!0),a=e.components;if(o){const r=new _.Project,t=await V({outDir:o,components:a,stencilPackageName:i,customElementsDir:T,excludeComponents:n,esModules:u===!0,project:r,hydrateModule:f,clientModule:d,excludeServerSideRenderingFor:$,serializeShadowRoot:b,transformTag:v});await Promise.all(t.map(g=>c.fs.writeFile(g.getFilePath(),g.getFullText())))}if(s){const r=G({components:a,stencilPackageName:i,excludeComponents:n});if(r){let t=s.endsWith(".d.ts")?s:N.join(s,W);!N.isAbsolute(t)&&l.rootDir&&(t=N.join(l.rootDir,t)),await c.fs.writeFile(t,r)}}h.finish(`generate ${C} finished`)},__internal_getCustomElementsDir(){return T}}};exports.reactOutputTarget=B;
//# sourceMappingURL=index.cjs.map