@iyulab/components 1.9.0 → 1.10.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/CHANGELOG.md +23 -0
- package/README.md +8 -0
- package/dist/_virtual/{_@oxc-project_runtime@0.139.0 → _@oxc-project_runtime@0.142.0}/helpers/esm/decorate.js +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.139.0 → _@oxc-project_runtime@0.142.0}/helpers/esm/decorateMetadata.js +1 -1
- package/dist/_virtual/_glob-assets_raw/dark.css.e8ac080d.js +1 -1
- package/dist/_virtual/_glob-assets_raw/light.css.637cb2f8.js +1 -1
- package/dist/components/UElement.d.ts +1 -4
- package/dist/components/UElement.js +3 -4
- package/dist/components/UFloatingElement.js +2 -2
- package/dist/components/UFormControlElement.js +2 -2
- package/dist/components/UOverlayElement.d.ts +3 -0
- package/dist/components/UOverlayElement.js +5 -2
- package/dist/components/alert/UAlert.js +2 -2
- package/dist/components/avatar/UAvatar.js +2 -2
- package/dist/components/badge/UBadge.js +2 -2
- package/dist/components/breadcrumb/UBreadcrumb.js +1 -1
- package/dist/components/breadcrumb-item/UBreadcrumbItem.js +2 -2
- package/dist/components/button/UButton.d.ts +16 -0
- package/dist/components/button/UButton.js +2 -2
- package/dist/components/button/UButton.styles.js +28 -17
- package/dist/components/button-group/UButtonGroup.js +2 -2
- package/dist/components/card/UCard.js +2 -2
- package/dist/components/carousel/UCarousel.js +2 -2
- package/dist/components/checkbox/UCheckbox.d.ts +2 -0
- package/dist/components/checkbox/UCheckbox.js +2 -2
- package/dist/components/chip/UChip.js +2 -2
- package/dist/components/copy-button/UCopyButton.js +2 -2
- package/dist/components/dialog/UDialog.js +2 -2
- package/dist/components/divider/UDivider.js +2 -2
- package/dist/components/drawer/UDrawer.d.ts +1 -1
- package/dist/components/drawer/UDrawer.js +2 -2
- package/dist/components/field/UField.js +2 -2
- package/dist/components/form/UForm.js +2 -2
- package/dist/components/icon/UIcon.js +2 -2
- package/dist/components/icon-button/UIconButton.js +2 -2
- package/dist/components/input/UInput.d.ts +4 -0
- package/dist/components/input/UInput.js +2 -4
- package/dist/components/input/UInput.styles.js +3 -0
- package/dist/components/menu/UMenu.js +2 -3
- package/dist/components/menu-item/UMenuItem.d.ts +2 -0
- package/dist/components/menu-item/UMenuItem.js +3 -2
- package/dist/components/option/UOption.d.ts +2 -0
- package/dist/components/option/UOption.js +2 -2
- package/dist/components/panel/UPanel.js +2 -2
- package/dist/components/popover/UPopover.js +2 -3
- package/dist/components/progress-bar/UProgressBar.js +4 -3
- package/dist/components/progress-ring/UProgressRing.js +2 -2
- package/dist/components/radio/URadio.d.ts +3 -0
- package/dist/components/radio/URadio.js +2 -3
- package/dist/components/rating/URating.js +2 -2
- package/dist/components/select/USelect.js +2 -4
- package/dist/components/skeleton/USkeleton.js +2 -2
- package/dist/components/slider/USlider.js +2 -2
- package/dist/components/spinner/USpinner.js +2 -2
- package/dist/components/split-panel/USplitPanel.js +2 -2
- package/dist/components/switch/USwitch.js +2 -2
- package/dist/components/tab/UTab.js +2 -2
- package/dist/components/tab-panel/UTabPanel.d.ts +2 -0
- package/dist/components/tab-panel/UTabPanel.js +2 -2
- package/dist/components/tag/UTag.d.ts +1 -0
- package/dist/components/tag/UTag.js +2 -2
- package/dist/components/textarea/UTextarea.js +2 -2
- package/dist/components/tooltip/UTooltip.js +2 -2
- package/dist/components/tree/UTree.d.ts +6 -0
- package/dist/components/tree/UTree.js +2 -2
- package/dist/components/tree-item/UTreeItem.d.ts +2 -0
- package/dist/components/tree-item/UTreeItem.js +2 -2
- package/dist/react/UDialog.d.ts +5 -1
- package/dist/react/UDialog.js +4 -1
- package/dist/react/UDrawer.d.ts +5 -1
- package/dist/react/UDrawer.js +4 -1
- package/dist/react/UPopover.d.ts +4 -2
- package/dist/react/UTooltip.d.ts +4 -2
- package/dist/styles/dark.css +1 -0
- package/dist/styles/light.css +1 -0
- package/dist/styles/tokens.css +17 -0
- package/dist/utilities/Theme.js +4 -0
- package/package.json +6 -4
- package/plugins/vite-plugin-glob-resolve.d.ts +0 -12
- package/plugins/vite-plugin-glob-resolve.js +0 -66
- package/plugins/vite-plugin-react-wrapper.d.ts +0 -14
- package/plugins/vite-plugin-react-wrapper.js +0 -235
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'fs';
|
|
2
|
-
import { resolve, dirname, basename } from 'path';
|
|
3
|
-
import { createHash } from 'crypto';
|
|
4
|
-
const VIRTUAL_PREFIX = '\0glob-assets';
|
|
5
|
-
const SUPPORTED_QUERIES = ['?raw', '?inline', '?url'];
|
|
6
|
-
function shortHash(input) {
|
|
7
|
-
return createHash('md5').update(input).digest('hex').slice(0, 8);
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Rolldown의 preserveModules 모드에서 import.meta.glob의 query 옵션 사용 시
|
|
11
|
-
* 빈 export가 생성되는 문제를 해결하는 플러그인.
|
|
12
|
-
*
|
|
13
|
-
* - `?raw`: 파일 내용을 문자열로 반환
|
|
14
|
-
* - `?inline`: 파일 내용을 문자열로 반환
|
|
15
|
-
* - `?url`: 파일을 asset으로 emit하고 URL을 반환
|
|
16
|
-
*
|
|
17
|
-
* 가상 모듈(\0 prefix)로 변환하여 파일명에 `?`가 포함되는 것을 방지합니다.
|
|
18
|
-
*/
|
|
19
|
-
export default function globResolve() {
|
|
20
|
-
const idToAbsPath = new Map();
|
|
21
|
-
return {
|
|
22
|
-
name: 'vite:glob-resolve',
|
|
23
|
-
enforce: 'pre',
|
|
24
|
-
resolveId(source, importer) {
|
|
25
|
-
for (const query of SUPPORTED_QUERIES) {
|
|
26
|
-
if (source.endsWith(query)) {
|
|
27
|
-
const rawPath = source.slice(0, -query.length);
|
|
28
|
-
const absPath = importer
|
|
29
|
-
? resolve(dirname(importer), rawPath)
|
|
30
|
-
: rawPath;
|
|
31
|
-
const name = basename(absPath);
|
|
32
|
-
const hash = shortHash(absPath);
|
|
33
|
-
const queryName = query.slice(1);
|
|
34
|
-
const virtualId = `${VIRTUAL_PREFIX}_${queryName}/${name}.${hash}`;
|
|
35
|
-
idToAbsPath.set(virtualId, absPath);
|
|
36
|
-
return virtualId;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return null;
|
|
40
|
-
},
|
|
41
|
-
load(id) {
|
|
42
|
-
if (!id.startsWith(VIRTUAL_PREFIX))
|
|
43
|
-
return null;
|
|
44
|
-
const absPath = idToAbsPath.get(id);
|
|
45
|
-
if (!absPath)
|
|
46
|
-
return null;
|
|
47
|
-
// virtualId에서 queryName 추출: "\0glob-assets_{queryName}/..."
|
|
48
|
-
const queryName = id.slice(VIRTUAL_PREFIX.length + 1).split('/')[0];
|
|
49
|
-
if (queryName === 'raw' || queryName === 'inline') {
|
|
50
|
-
const content = readFileSync(absPath, 'utf-8');
|
|
51
|
-
return `export default ${JSON.stringify(content)};`;
|
|
52
|
-
}
|
|
53
|
-
if (queryName === 'url') {
|
|
54
|
-
const source = readFileSync(absPath);
|
|
55
|
-
const fileName = basename(absPath);
|
|
56
|
-
const ref = this.emitFile({
|
|
57
|
-
type: 'asset',
|
|
58
|
-
name: fileName,
|
|
59
|
-
source,
|
|
60
|
-
});
|
|
61
|
-
return `export default import.meta.ROLLUP_FILE_URL_${ref};`;
|
|
62
|
-
}
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from 'vite';
|
|
2
|
-
interface PluginOptions {
|
|
3
|
-
/** 컴포넌트 소스 디렉토리 경로 (기본값: 'src/components') */
|
|
4
|
-
input?: string;
|
|
5
|
-
/** React 래퍼 출력 폴더 - 빌드 outDir 기준 상대 경로 (기본값: 'react') */
|
|
6
|
-
output?: string;
|
|
7
|
-
/** 래퍼 생성에서 제외할 glob 패턴 목록 (cwd: 프로젝트 루트) */
|
|
8
|
-
exclude?: string[];
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Lit Element 컴포넌트를 React 래퍼로 자동 생성하는 Vite 플러그인
|
|
12
|
-
*/
|
|
13
|
-
export default function reactWrapperPlugin(options: PluginOptions): Plugin;
|
|
14
|
-
export {};
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
import { resolve, join, relative, dirname, basename } from 'path';
|
|
2
|
-
import { readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
3
|
-
import { gzipSync } from 'zlib';
|
|
4
|
-
import { globSync } from 'glob';
|
|
5
|
-
/**
|
|
6
|
-
* Lit Element 컴포넌트를 React 래퍼로 자동 생성하는 Vite 플러그인
|
|
7
|
-
*/
|
|
8
|
-
export default function reactWrapperPlugin(options) {
|
|
9
|
-
let rootDir;
|
|
10
|
-
let buildOutDir;
|
|
11
|
-
let outDir;
|
|
12
|
-
return {
|
|
13
|
-
name: 'vite-plugin-react-wrapper',
|
|
14
|
-
configResolved(config) {
|
|
15
|
-
rootDir = config.root;
|
|
16
|
-
buildOutDir = resolve(rootDir, config.build.outDir);
|
|
17
|
-
outDir = resolve(buildOutDir, options.output || 'react');
|
|
18
|
-
},
|
|
19
|
-
closeBundle() {
|
|
20
|
-
const log = (msg) => console.log(`\x1b[36m[react-wrapper]\x1b[0m ${msg}`);
|
|
21
|
-
log('Generating React wrappers...');
|
|
22
|
-
// 컴포넌트 수집
|
|
23
|
-
const inputPattern = (options.input || 'src/components') + '/**/*.ts';
|
|
24
|
-
let files = globSync(inputPattern, { cwd: rootDir, absolute: true });
|
|
25
|
-
if (options.exclude?.length) {
|
|
26
|
-
const excluded = new Set(options.exclude.flatMap(p => globSync(p, { cwd: rootDir, absolute: true })));
|
|
27
|
-
files = files.filter((f) => !excluded.has(f));
|
|
28
|
-
}
|
|
29
|
-
const components = files.flatMap((f) => parseComponent(f));
|
|
30
|
-
if (components.length === 0) {
|
|
31
|
-
log('No components found.');
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
// 출력 디렉토리 생성
|
|
35
|
-
mkdirSync(outDir, { recursive: true });
|
|
36
|
-
// 래퍼 생성
|
|
37
|
-
const generated = [];
|
|
38
|
-
for (const comp of components) {
|
|
39
|
-
generated.push(...writeWrapper(comp, outDir, buildOutDir));
|
|
40
|
-
}
|
|
41
|
-
generated.push(...writeIndex(components, outDir, buildOutDir));
|
|
42
|
-
// 결과 출력
|
|
43
|
-
generated.sort((a, b) => a.size - b.size);
|
|
44
|
-
for (const f of generated) {
|
|
45
|
-
const kb = (f.size / 1024).toFixed(2);
|
|
46
|
-
const gzKb = (f.gzipSize / 1024).toFixed(2);
|
|
47
|
-
const pad = ' '.repeat(Math.max(0, 50 - f.path.length));
|
|
48
|
-
console.log(`${f.path}${pad}${kb.padStart(6)} kB │ gzip: ${gzKb.padStart(6)} kB`);
|
|
49
|
-
}
|
|
50
|
-
log(`Generated ${components.length} React wrappers.`);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
// --- 컴포넌트 파싱 ---
|
|
55
|
-
function parseComponent(filePath) {
|
|
56
|
-
const content = readFileSync(filePath, 'utf-8');
|
|
57
|
-
// @customElement('tag-name') 데코레이터 확인
|
|
58
|
-
const tagMatch = content.match(/@customElement\s*\(\s*['"]([^'"]+)['"]\s*\)/);
|
|
59
|
-
if (!tagMatch)
|
|
60
|
-
return [];
|
|
61
|
-
// export class ClassName 추출
|
|
62
|
-
const classMatch = content.match(/export\s+class\s+(\w+)/);
|
|
63
|
-
if (!classMatch)
|
|
64
|
-
return [];
|
|
65
|
-
const events = collectEvents(content);
|
|
66
|
-
// 이벤트를 발생시키지만(relay/dispatchEvent) 정적으로 이름을 도출할 수 없는 컴포넌트가
|
|
67
|
-
// @event 태그도 없으면 events 맵이 빈 채로 생성되어 React 소비자가 이벤트를 구독할 수 없다.
|
|
68
|
-
// (this.fire<T>('name')은 이름이 문자열 리터럴로 잡히므로 이 경고 대상이 아님)
|
|
69
|
-
if (events.length === 0 && /this\.(relay|dispatchEvent)\s*\(/.test(content)) {
|
|
70
|
-
console.warn(`\x1b[33m[react-wrapper]\x1b[0m ${classMatch[1]} (${tagMatch[1]}): ` +
|
|
71
|
-
`이벤트를 발생시키지만(relay/dispatchEvent) @event 태그가 없어 React 래퍼에 이벤트 prop이 노출되지 않습니다. ` +
|
|
72
|
-
`클래스 JSDoc에 '@event <name>'을 추가하세요.`);
|
|
73
|
-
}
|
|
74
|
-
return [{
|
|
75
|
-
className: classMatch[1],
|
|
76
|
-
tagName: tagMatch[1],
|
|
77
|
-
filePath,
|
|
78
|
-
events,
|
|
79
|
-
}];
|
|
80
|
-
}
|
|
81
|
-
function collectEvents(content) {
|
|
82
|
-
// import 구문에서 타입명 → 소스 경로 매핑 수집
|
|
83
|
-
// 예: import { ShowEventDetail } from '../../events/ShowEvent.js';
|
|
84
|
-
const typeImportMap = new Map();
|
|
85
|
-
for (const m of content.matchAll(/import\s+\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]/g)) {
|
|
86
|
-
const importPath = m[2];
|
|
87
|
-
for (const name of m[1].split(',')) {
|
|
88
|
-
const typeName = name.replace(/type\s+/, '').trim();
|
|
89
|
-
if (typeName)
|
|
90
|
-
typeImportMap.set(typeName, importPath);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
const eventMap = new Map();
|
|
94
|
-
// JSDoc @event 패턴: @event eventName
|
|
95
|
-
for (const m of content.matchAll(/@event\s+([\w-]+)/g)) {
|
|
96
|
-
if (!eventMap.has(m[1]))
|
|
97
|
-
eventMap.set(m[1], { detailType: 'unknown', importPath: '' });
|
|
98
|
-
}
|
|
99
|
-
// this.fire<DetailType>('eventName') 패턴 - 제네릭 타입 추출
|
|
100
|
-
for (const m of content.matchAll(/this\.fire\s*(?:<([^>]+)>)?\s*\(\s*['"]([\w-]+)['"]/g)) {
|
|
101
|
-
const detailType = m[1] || 'unknown';
|
|
102
|
-
const importPath = typeImportMap.get(detailType) || '';
|
|
103
|
-
eventMap.set(m[2], { detailType, importPath });
|
|
104
|
-
}
|
|
105
|
-
return Array.from(eventMap, ([name, { detailType, importPath }]) => ({
|
|
106
|
-
name,
|
|
107
|
-
reactName: toCamelEvent(name),
|
|
108
|
-
detailType,
|
|
109
|
-
importPath,
|
|
110
|
-
}));
|
|
111
|
-
}
|
|
112
|
-
/** kebab-case 이벤트명을 onCamelCase로 변환 (예: shift-start → onShiftStart) */
|
|
113
|
-
function toCamelEvent(name) {
|
|
114
|
-
return 'on' + name.split('-').map(s => s.charAt(0).toUpperCase() + s.slice(1)).join('');
|
|
115
|
-
}
|
|
116
|
-
function writeFile(filePath, content, buildOutDir) {
|
|
117
|
-
writeFileSync(filePath, content, 'utf-8');
|
|
118
|
-
return {
|
|
119
|
-
path: relative(buildOutDir, filePath).replace(/\\/g, '/'),
|
|
120
|
-
size: Buffer.byteLength(content, 'utf-8'),
|
|
121
|
-
gzipSize: gzipSync(content).length,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
function computeImportPath(from, to) {
|
|
125
|
-
let rel = relative(dirname(from), to).replace(/\\/g, '/').replace(/\.ts$/, '');
|
|
126
|
-
if (!rel.startsWith('.'))
|
|
127
|
-
rel = './' + rel;
|
|
128
|
-
return rel;
|
|
129
|
-
}
|
|
130
|
-
function writeWrapper(comp, outDir, buildOutDir) {
|
|
131
|
-
const { className, tagName, events } = comp;
|
|
132
|
-
const jsPath = join(outDir, `${className}.js`);
|
|
133
|
-
const dtsPath = join(outDir, `${className}.d.ts`);
|
|
134
|
-
// 소스 파일의 빌드 출력 경로 추정 (src/ → 빌드 outDir 매핑)
|
|
135
|
-
const srcIndex = comp.filePath.replace(/\\/g, '/').indexOf('/src/');
|
|
136
|
-
const relFromSrc = srcIndex >= 0
|
|
137
|
-
? comp.filePath.substring(srcIndex + 5).replace(/\\/g, '/').replace(/\.ts$/, '')
|
|
138
|
-
: basename(comp.filePath, '.ts');
|
|
139
|
-
const builtModulePath = resolve(buildOutDir, relFromSrc + '.js');
|
|
140
|
-
const importPath = computeImportPath(jsPath, builtModulePath);
|
|
141
|
-
// events 객체 생성
|
|
142
|
-
const eventsObj = events.length > 0
|
|
143
|
-
? `{\n${events.map(e => ` ${e.reactName}: '${e.name}',`).join('\n')}\n }`
|
|
144
|
-
: '{}';
|
|
145
|
-
// .js
|
|
146
|
-
const js = `import React from 'react';
|
|
147
|
-
import { createComponent } from '@lit/react';
|
|
148
|
-
import { ${className} as ${className}Element } from '${importPath}';
|
|
149
|
-
|
|
150
|
-
export const ${className} = createComponent({
|
|
151
|
-
react: React,
|
|
152
|
-
tagName: '${tagName}',
|
|
153
|
-
elementClass: ${className}Element,
|
|
154
|
-
events: ${eventsObj},
|
|
155
|
-
});
|
|
156
|
-
`;
|
|
157
|
-
// .d.ts - import 구문 생성
|
|
158
|
-
const dtsImportPath = importPath.replace(/\.js$/, '');
|
|
159
|
-
const dtsImports = [
|
|
160
|
-
`import React from 'react';`,
|
|
161
|
-
`import { ${className} as ${className}Element } from '${dtsImportPath}';`,
|
|
162
|
-
];
|
|
163
|
-
// 이벤트 detail 타입별 import - 소스 원본 경로 기준으로 빌드 경로 계산
|
|
164
|
-
const srcDir = dirname(comp.filePath);
|
|
165
|
-
const detailImportMap = new Map(); // 빌드경로 → [타입명]
|
|
166
|
-
for (const e of events) {
|
|
167
|
-
if (e.detailType === 'unknown' || !e.importPath)
|
|
168
|
-
continue;
|
|
169
|
-
// 소스 상대경로를 절대경로로 변환 후 빌드 경로 계산
|
|
170
|
-
const absEventSrc = resolve(srcDir, e.importPath).replace(/\\/g, '/');
|
|
171
|
-
const eventSrcIndex = absEventSrc.indexOf('/src/');
|
|
172
|
-
const relFromSrc = eventSrcIndex >= 0
|
|
173
|
-
? absEventSrc.substring(eventSrcIndex + 5).replace(/\.js$/, '')
|
|
174
|
-
: '';
|
|
175
|
-
if (!relFromSrc)
|
|
176
|
-
continue;
|
|
177
|
-
const absEventBuilt = resolve(buildOutDir, relFromSrc);
|
|
178
|
-
const eventImportPath = computeImportPath(dtsPath, absEventBuilt + '.js').replace(/\.js$/, '');
|
|
179
|
-
const types = detailImportMap.get(eventImportPath) || [];
|
|
180
|
-
if (!types.includes(e.detailType))
|
|
181
|
-
types.push(e.detailType);
|
|
182
|
-
detailImportMap.set(eventImportPath, types);
|
|
183
|
-
}
|
|
184
|
-
for (const [path, types] of detailImportMap) {
|
|
185
|
-
dtsImports.push(`import { type ${types.join(', type ')} } from '${path}';`);
|
|
186
|
-
}
|
|
187
|
-
const eventTypes = events.length > 0
|
|
188
|
-
? events.map(e => {
|
|
189
|
-
const type = e.detailType !== 'unknown' ? `CustomEvent<${e.detailType}>` : 'CustomEvent';
|
|
190
|
-
return ` ${e.reactName}?: (event: ${type}) => void;`;
|
|
191
|
-
}).join('\n') + '\n'
|
|
192
|
-
: '';
|
|
193
|
-
// 래퍼 이벤트 prop(onChange 등)은 React.HTMLAttributes 의 동명 핸들러와 교집합되면
|
|
194
|
-
// 어떤 시그니처도 대입 불가가 된다. HTMLAttributes 쪽에서 해당 키를 제거해 CustomEvent
|
|
195
|
-
// 시그니처만 남긴다. 이벤트가 없으면 Omit<…, never> 로 HTMLAttributes 원형 유지.
|
|
196
|
-
const eventKeyUnion = events.length > 0
|
|
197
|
-
? events.map(e => `'${e.reactName}'`).join(' | ')
|
|
198
|
-
: 'never';
|
|
199
|
-
// Partial<Element> 은 DOM 프로퍼티(children: HTMLCollection 등)를 포함해 React 의 JSX
|
|
200
|
-
// children/이벤트/className 등과 충돌한다. keyof React.HTMLAttributes 를 제거해 컴포넌트
|
|
201
|
-
// 고유 prop만 남기고, React 친화 타입(children: ReactNode 포함)은 HTMLAttributes 가 제공한다.
|
|
202
|
-
//
|
|
203
|
-
// `React.RefAttributes` 를 반드시 교집합에 넣는다 — `ForwardRefExoticComponent<P>` 는 P 에
|
|
204
|
-
// ref 를 자동으로 더해 주지 않는다. @lit/react 의 `ReactWebComponent` 자신이
|
|
205
|
-
// `PropsWithoutRef<…> & React.RefAttributes<I>` 로 선언돼 있으므로(런타임은 ref 를 전달한다),
|
|
206
|
-
// 이것을 빠뜨리면 **런타임은 되는데 타입만 거부하는** 괴리가 생긴다.
|
|
207
|
-
const dts = `${dtsImports.join('\n')}
|
|
208
|
-
|
|
209
|
-
export declare const ${className}: React.ForwardRefExoticComponent<
|
|
210
|
-
Omit<Partial<${className}Element>, keyof React.HTMLAttributes<${className}Element>>
|
|
211
|
-
& Omit<React.HTMLAttributes<${className}Element>, ${eventKeyUnion}>
|
|
212
|
-
& React.RefAttributes<${className}Element>
|
|
213
|
-
& {
|
|
214
|
-
${eventTypes} }
|
|
215
|
-
>;
|
|
216
|
-
|
|
217
|
-
export type ${className}Props = React.ComponentProps<typeof ${className}>;
|
|
218
|
-
`;
|
|
219
|
-
return [
|
|
220
|
-
writeFile(jsPath, js, buildOutDir),
|
|
221
|
-
writeFile(dtsPath, dts, buildOutDir),
|
|
222
|
-
];
|
|
223
|
-
}
|
|
224
|
-
function writeIndex(components, outDir, buildOutDir) {
|
|
225
|
-
const jsExports = components
|
|
226
|
-
.map(c => `export { ${c.className} } from './${c.className}.js';`)
|
|
227
|
-
.join('\n');
|
|
228
|
-
const dtsExports = components
|
|
229
|
-
.map(c => `export { ${c.className}, ${c.className}Props } from './${c.className}';`)
|
|
230
|
-
.join('\n');
|
|
231
|
-
return [
|
|
232
|
-
writeFile(join(outDir, 'index.js'), jsExports + '\n', buildOutDir),
|
|
233
|
-
writeFile(join(outDir, 'index.d.ts'), dtsExports + '\n', buildOutDir),
|
|
234
|
-
];
|
|
235
|
-
}
|