@symbiote-native/vue 0.3.7 → 0.4.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/build/components/flat-list/index.js +18 -34
- package/build/components/image-background.js +4 -14
- package/build/components/image.js +9 -20
- package/build/components/keyboard-avoiding-view.js +10 -19
- package/build/components/modal/index.d.ts +4 -4
- package/build/components/pressable.js +24 -31
- package/build/components/refresh-control.js +12 -18
- package/build/components/scroll-view/index.android.js +21 -33
- package/build/components/scroll-view/shared.js +76 -121
- package/build/components/scroll-view/sticky-header.js +104 -104
- package/build/components/section-list/index.js +12 -19
- package/build/components/switch/shared.js +17 -29
- package/build/components/text-input/index.js +29 -49
- package/build/components/touchable.js +30 -50
- package/build/components/virtualized-list/index.js +174 -273
- package/build/components/virtualized-section-list/index.js +19 -29
- package/build/components.js +1 -3
- package/build/host-instance/index.js +2 -4
- package/build/index.d.ts +2 -1
- package/build/index.js +11 -45
- package/build/modules/animated/create-animated-component.js +34 -97
- package/build/modules/animated/index.js +13 -17
- package/build/modules/app-registry/index.js +7 -11
- package/build/modules/status-bar.js +8 -15
- package/build/renderer/index.js +11 -6
- package/build/runtime-helpers/index.js +16 -26
- package/metro-css-parser.cjs +9 -14
- package/metro-vue-transformer.cjs +112 -135
- package/package.json +4 -4
|
@@ -1,37 +1,33 @@
|
|
|
1
|
-
// Metro babel transformer that teaches the bundler to read Vue SFCs (.vue). Metro has no
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// component module, then hand the JS to RN's own babel transformer
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// vue/runtime-dom.
|
|
1
|
+
// Metro babel transformer that teaches the bundler to read Vue SFCs (.vue). Metro has no Vue
|
|
2
|
+
// plugin (unplugin-vue only ships vite/webpack/esbuild/rollup adapters), so we do the
|
|
3
|
+
// single-pass compile here: parse the SFC, compile <script setup> + <template> into one
|
|
4
|
+
// component module, then hand the JS to RN's own babel transformer - the Metro twin of
|
|
5
|
+
// @vitejs/plugin-vue. Imports get retargeted from 'vue' to @symbiote-native/vue/runtime-helpers
|
|
6
|
+
// (not bare @vue/runtime-core) because that shim also supplies our own `vShow` - compiled
|
|
7
|
+
// v-show imports it by name, and only @vue/runtime-dom's DOM-based version exists otherwise.
|
|
8
8
|
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
// Ships as a package-level export (`@symbiote-native/vue/metro-vue-transformer`) rather than living
|
|
14
|
-
// in each consuming app: a consumer's own metro.config.js just points babelTransformerPath at it.
|
|
9
|
+
// Ships as a package-level export (`@symbiote-native/vue/metro-vue-transformer`) rather than
|
|
10
|
+
// living in each consuming app: a consumer's own metro.config.js just points
|
|
11
|
+
// babelTransformerPath at it.
|
|
15
12
|
|
|
16
13
|
const nodeFs = require('fs');
|
|
17
14
|
const { parse, compileScript, registerTS } = require('@vue/compiler-sfc');
|
|
18
15
|
const { createCompoundExpression } = require('@vue/compiler-core');
|
|
19
16
|
|
|
20
|
-
// A bare-specifier type import (`import type { X } from '@symbiote-native/navigation/vue'
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
// lazy loader for the real `typescript` package, which resolves the specifier via
|
|
26
|
-
// `ts.resolveModuleName` and self-supplies `ts.sys` as the fs fallback.
|
|
17
|
+
// A bare-specifier type import (`import type { X } from '@symbiote-native/navigation/vue'`) needs
|
|
18
|
+
// real node_modules resolution to turn the specifier into a file path - compileScript's own `fs`
|
|
19
|
+
// option only reads paths it's already given, it can't resolve. registerTS (the same hook
|
|
20
|
+
// @vitejs/plugin-vue and vue-tsc use) hands the compiler a lazy `typescript` loader that resolves
|
|
21
|
+
// via `ts.resolveModuleName` and self-supplies `ts.sys` as the fs fallback.
|
|
27
22
|
registerTS(() => require('typescript'));
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
// straight from this package's own node_modules under pnpm.
|
|
23
|
+
// Required directly (not via the ./metro-css-parser public subpath, which exists for CONSUMERS)
|
|
24
|
+
// so it resolves from this package's own node_modules under pnpm.
|
|
31
25
|
const {
|
|
26
|
+
classTokensIn,
|
|
32
27
|
compile: compilePreprocessor,
|
|
33
28
|
compileCssFile,
|
|
34
29
|
globalClassNamesIn,
|
|
30
|
+
globalClassTokensIn,
|
|
35
31
|
hashFilePath,
|
|
36
32
|
isStyleFile,
|
|
37
33
|
kebabToCamel,
|
|
@@ -42,14 +38,13 @@ const {
|
|
|
42
38
|
const upstreamTransformer = resolveUpstreamTransformer();
|
|
43
39
|
|
|
44
40
|
// compileScript needs file system access to resolve a type-only `defineProps<ISomeProps>()`
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
// as a loader (registerTS), and this file already runs in Node at Metro build time.
|
|
41
|
+
// imported from another file - without it, Metro's worker process (a real Node process, but one
|
|
42
|
+
// @vue/compiler-sfc doesn't auto-detect without registerTS) throws "No fs option provided ...
|
|
43
|
+
// in non-Node environment". Wiring Node's own `fs` straight through is simpler than a second
|
|
44
|
+
// registerTS-style loader.
|
|
50
45
|
const compileScriptFs = {
|
|
51
|
-
fileExists:
|
|
52
|
-
readFile:
|
|
46
|
+
fileExists: file => nodeFs.existsSync(file),
|
|
47
|
+
readFile: file => {
|
|
53
48
|
try {
|
|
54
49
|
return nodeFs.readFileSync(file, 'utf-8');
|
|
55
50
|
} catch {
|
|
@@ -58,34 +53,23 @@ const compileScriptFs = {
|
|
|
58
53
|
},
|
|
59
54
|
};
|
|
60
55
|
|
|
61
|
-
// Rewrites a Vue template AST so every `class`/`:class` binding
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
// can't reproduce that merge safely; letting Vue's own transformElement do the merge on our
|
|
67
|
-
// already-rewritten nodes reuses that logic instead of reimplementing it).
|
|
56
|
+
// Rewrites a Vue template AST so every `class`/`:class` binding resolves against this file's
|
|
57
|
+
// scoped class names via @symbiote-native/engine's scopeClassName(value, localNames, scopeId).
|
|
58
|
+
// AST-level, not a raw-text regex: Vue merges a static class= and a dynamic :class= on the same
|
|
59
|
+
// element into ONE codegen entry, and text substitution can't reproduce that merge safely -
|
|
60
|
+
// letting Vue's own transformElement do the merge on our rewritten nodes reuses that logic.
|
|
68
61
|
//
|
|
69
|
-
// A static class="foo bar"
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
// FIRST (kebabToCamel) — a template may write class="section-label" (idiomatic CSS) instead of
|
|
73
|
-
// class="sectionLabel"; the css-parser always registers the CAMEL form, and localNames (built
|
|
74
|
-
// from that same registration) is camelCase-keyed, so the scoping check below only recognizes a
|
|
75
|
-
// token once it is in that form. The emitted string is always camelCase, suffixed or not.
|
|
62
|
+
// A static class="foo bar" (AttributeNode, prop.type === 6) resolves to its final string here
|
|
63
|
+
// at compile time - no runtime call needed. Each token is normalized kebab->camel FIRST since
|
|
64
|
+
// css-parser always registers the camel form and localNames is camelCase-keyed.
|
|
76
65
|
//
|
|
77
|
-
// A dynamic :class="expr"
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
// a single child inside `scopeClassName(<original>, __localScopedClassNames, __scopeId)`, so
|
|
85
|
-
// codegen emits the call with the original expression source reproduced unchanged inside it —
|
|
86
|
-
// this needs no per-shape branching, and correctly defers even a fully opaque runtime value
|
|
87
|
-
// (`:class="dynamicClass"`) to scopeClassName's own runtime token-matching, so there is no
|
|
88
|
-
// unresolved gap for dynamic scoped classes.
|
|
66
|
+
// A dynamic :class="expr" (bind DirectiveNode, prop.type === 7) targeting `class`: by the time
|
|
67
|
+
// our transform runs, Vue's own transformExpression has already turned prop.exp into either a
|
|
68
|
+
// COMPOUND_EXPRESSION (type 8) or, for a bare identifier binding, a SIMPLE_EXPRESSION (type 4).
|
|
69
|
+
// createCompoundExpression wraps the original exp node as-is inside
|
|
70
|
+
// scopeClassName(<original>, __localScopedClassNames, __scopeId), so codegen reproduces the
|
|
71
|
+
// original expression unchanged - no per-shape branching needed, and a fully opaque runtime
|
|
72
|
+
// value (`:class="dynamicClass"`) still defers correctly to scopeClassName's own token matching.
|
|
89
73
|
function createScopeClassNodeTransform(localNames, scopeId) {
|
|
90
74
|
return function scopeClassNodeTransform(node) {
|
|
91
75
|
if (node.type !== 1 /* NodeTypes.ELEMENT */) return;
|
|
@@ -95,7 +79,7 @@ function createScopeClassNodeTransform(localNames, scopeId) {
|
|
|
95
79
|
prop.value.content = prop.value.content
|
|
96
80
|
.split(/\s+/)
|
|
97
81
|
.filter(Boolean)
|
|
98
|
-
.map(
|
|
82
|
+
.map(token => {
|
|
99
83
|
const camelToken = kebabToCamel(token);
|
|
100
84
|
return localNames.has(camelToken) ? `${camelToken}__${scopeId}` : camelToken;
|
|
101
85
|
})
|
|
@@ -120,10 +104,9 @@ function createScopeClassNodeTransform(localNames, scopeId) {
|
|
|
120
104
|
};
|
|
121
105
|
}
|
|
122
106
|
|
|
123
|
-
// A short, stable id per file, used as the SFC scope id
|
|
124
|
-
//
|
|
125
|
-
//
|
|
126
|
-
// standalone .module.css compiler's identical need (metro-css-module.ts).
|
|
107
|
+
// A short, stable id per file, used as the SFC scope id regardless of whether the file has
|
|
108
|
+
// scoped styles - built on css-parser's shared hashFilePath so the algorithm isn't duplicated
|
|
109
|
+
// against the standalone .module.css compiler's identical need.
|
|
127
110
|
function scopeIdFor(filename) {
|
|
128
111
|
return 'data-v-' + hashFilePath(filename);
|
|
129
112
|
}
|
|
@@ -139,9 +122,7 @@ const SFC_STYLE_LANG_TO_PREPROCESSOR = new Map([
|
|
|
139
122
|
]);
|
|
140
123
|
|
|
141
124
|
// Reduces one <style> block down to plain CSS text. A lang-less or lang="css" block passes
|
|
142
|
-
// through unchanged
|
|
143
|
-
// (a typo, or a genuinely unsupported lang) still throws, same message as before this feature
|
|
144
|
-
// existed.
|
|
125
|
+
// through unchanged. Anything outside the four recognized preprocessor langs throws.
|
|
145
126
|
async function compileStyleBlockContent(style, filename) {
|
|
146
127
|
if (style.lang == null || style.lang === 'css') return style.content;
|
|
147
128
|
|
|
@@ -170,54 +151,39 @@ async function compileSfc(src, filename) {
|
|
|
170
151
|
|
|
171
152
|
const scopeId = scopeIdFor(filename);
|
|
172
153
|
|
|
173
|
-
//
|
|
174
|
-
//
|
|
175
|
-
// to re-extract style blocks with a regex.
|
|
154
|
+
// descriptor.styles is already parsed by @vue/compiler-sfc (one entry per <style> block,
|
|
155
|
+
// content pre-trimmed, scoped as a plain boolean) - no need to re-extract with a regex.
|
|
176
156
|
//
|
|
177
|
-
// A scoped block's classes get their key SUFFIXED with this file's scopeId
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
//
|
|
181
|
-
//
|
|
182
|
-
// register exactly as before: no suffix, globally shared. `:global(...)` selectors inside a
|
|
183
|
-
// scoped block are the one exception — @symbiote-native/css-parser already unwraps them to their
|
|
184
|
-
// plain class name (`:global(.reset)` parses like `.reset`), so `globalClassNamesIn` re-scans
|
|
185
|
-
// the block's own raw text to find which specific keys should be exempted from suffixing.
|
|
157
|
+
// A scoped block's classes get their key SUFFIXED with this file's scopeId (`card` ->
|
|
158
|
+
// `card__data-v-xxxxxxxx`) so two components can each define `.card` without colliding in the
|
|
159
|
+
// shared global registry - our name-suffix equivalent of Vue's `data-v-hash` attribute (we
|
|
160
|
+
// have no DOM/attribute-selector matching). `:global(...)` selectors are exempted from
|
|
161
|
+
// suffixing; globalClassNamesIn re-walks the block's selectors to find which keys to exempt.
|
|
186
162
|
//
|
|
187
|
-
//
|
|
188
|
-
// blocks too: only each block's OWN css-parser output is scoped independently, then merged.
|
|
163
|
+
// Multiple blocks cascade last-block-wins, same as CSS, after each block is scoped independently.
|
|
189
164
|
//
|
|
190
|
-
// <style module> (CSS Modules) reuses this
|
|
191
|
-
//
|
|
192
|
-
//
|
|
193
|
-
//
|
|
194
|
-
//
|
|
195
|
-
//
|
|
196
|
-
//
|
|
197
|
-
//
|
|
198
|
-
// rewrites literal class strings for `scoped` blocks). The registry key gets an extra
|
|
199
|
-
// `module` tag (`card__module__<scopeId>`, vs scoped's plain `card__<scopeId>`) so a file
|
|
200
|
-
// that happens to mix `<style scoped>` and `<style module>` with the same class name can't
|
|
201
|
-
// collide in the shared registry.
|
|
165
|
+
// <style module> (CSS Modules) reuses this same suffixing machinery: `.card` still goes
|
|
166
|
+
// through parseCSS and registerStyles unchanged, just under a suffixed key - the only new
|
|
167
|
+
// output is a name->scopedName object ($style by default) emitted as a preamble const, so
|
|
168
|
+
// `:class="$style.card"` passes the already-scoped string straight to resolveClassName's
|
|
169
|
+
// exact-match path. Unlike `scoped`, module classes are NEVER auto-applied to a literal
|
|
170
|
+
// class="..." (opt-in via $style.x only), so they're kept out of localScopedNames. The
|
|
171
|
+
// registry key gets an extra `module` tag (`card__module__<scopeId>` vs scoped's
|
|
172
|
+
// `card__<scopeId>`) so a file mixing both kinds can't collide.
|
|
202
173
|
const styles = {};
|
|
203
174
|
const localScopedNames = new Set();
|
|
204
175
|
const cssModuleBindings = new Map();
|
|
205
176
|
|
|
206
177
|
for (const style of descriptor.styles) {
|
|
207
|
-
// Reduces a preprocessor block
|
|
208
|
-
//
|
|
209
|
-
// plain-CSS output, same as it always did for a lang-less/lang="css" block. Anything other
|
|
210
|
-
// than the four recognized preprocessor langs (a typo, or a genuinely unsupported lang)
|
|
211
|
-
// still throws, unchanged from before.
|
|
178
|
+
// Reduces a preprocessor block to plain CSS BEFORE the scoping logic below runs - that
|
|
179
|
+
// logic is language-agnostic, it only ever sees parseCSS's plain-CSS output.
|
|
212
180
|
const content = await compileStyleBlockContent(style, filename);
|
|
213
181
|
const parsed = parseCSS(content, { filename });
|
|
214
182
|
|
|
215
183
|
if (style.module) {
|
|
216
184
|
const bindingName = typeof style.module === 'string' ? style.module : '$style';
|
|
217
|
-
// Scanned against the COMPILED content, not style.content
|
|
218
|
-
//
|
|
219
|
-
// unchanged), but scanning the compiler's actual output can't drift under nesting/
|
|
220
|
-
// interpolation the way assuming source-and-output stay textually identical could.
|
|
185
|
+
// Scanned against the COMPILED content, not style.content, so it can't drift under
|
|
186
|
+
// preprocessor nesting/interpolation.
|
|
221
187
|
const exemptFromScope = globalClassNamesIn(content);
|
|
222
188
|
const classMap = cssModuleBindings.get(bindingName) ?? {};
|
|
223
189
|
for (const [className, props] of Object.entries(parsed)) {
|
|
@@ -229,10 +195,25 @@ async function compileSfc(src, filename) {
|
|
|
229
195
|
cssModuleBindings.set(bindingName, classMap);
|
|
230
196
|
} else if (style.scoped) {
|
|
231
197
|
const exemptFromScope = globalClassNamesIn(content);
|
|
198
|
+
// A compound/descendant selector registers under ONE collapsed key (`.card.big` ->
|
|
199
|
+
// `cardBig`) that never appears in the template - the template writes
|
|
200
|
+
// `class="card big"` - so the nodeTransform must recognize the individual TOKENS, not
|
|
201
|
+
// just the collapsed key.
|
|
202
|
+
const tokensByName = classTokensIn(content, { filename });
|
|
203
|
+
// ...and a token out of a `:global(...)` payload is the one exception to that: in
|
|
204
|
+
// `.card :global(.reset)` the KEY (`cardReset`) is this file's own, because `.card` is,
|
|
205
|
+
// but `reset` was written precisely to name markup this file does not own. Suffixing it
|
|
206
|
+
// along with the rest of its chain scope-mangles the escape hatch into matching nothing.
|
|
207
|
+
const globalTokens = globalClassTokensIn(content, { filename });
|
|
232
208
|
for (const [className, props] of Object.entries(parsed)) {
|
|
233
209
|
const isExempt = exemptFromScope.has(className);
|
|
234
210
|
const registeredName = isExempt ? className : `${className}__${scopeId}`;
|
|
235
|
-
if (!isExempt)
|
|
211
|
+
if (!isExempt) {
|
|
212
|
+
localScopedNames.add(className);
|
|
213
|
+
for (const token of tokensByName.get(className) ?? []) {
|
|
214
|
+
if (!globalTokens.has(token)) localScopedNames.add(token);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
236
217
|
styles[registeredName] = { ...styles[registeredName], ...props };
|
|
237
218
|
}
|
|
238
219
|
} else {
|
|
@@ -242,10 +223,8 @@ async function compileSfc(src, filename) {
|
|
|
242
223
|
}
|
|
243
224
|
}
|
|
244
225
|
|
|
245
|
-
//
|
|
246
|
-
//
|
|
247
|
-
// even passed to the compiler) when nothing in this file is scoped, so a .vue with only
|
|
248
|
-
// unscoped/no styles compiles exactly as before, zero added runtime cost or behavior change.
|
|
226
|
+
// Skipped entirely (not even passed to the compiler) when nothing in this file is scoped, so
|
|
227
|
+
// a .vue with only unscoped/no styles compiles with zero added runtime cost.
|
|
249
228
|
const templateOptions =
|
|
250
229
|
localScopedNames.size > 0
|
|
251
230
|
? {
|
|
@@ -263,18 +242,17 @@ async function compileSfc(src, filename) {
|
|
|
263
242
|
templateOptions,
|
|
264
243
|
fs: compileScriptFs,
|
|
265
244
|
});
|
|
266
|
-
//
|
|
267
|
-
//
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
245
|
+
// Retargets every Vue import (compiler-injected helpers AND the user's own `from 'vue'`) at
|
|
246
|
+
// the runtime-helpers shim - no vue/runtime-dom in a native bundle.
|
|
247
|
+
const code = compiled.content.replace(
|
|
248
|
+
/from\s*(['"])vue\1/g,
|
|
249
|
+
'from "@symbiote-native/vue/runtime-helpers"',
|
|
250
|
+
);
|
|
271
251
|
|
|
272
252
|
if (Object.keys(styles).length === 0) return code;
|
|
273
253
|
|
|
274
|
-
// Only a scoped file needs scopeClassName + its two per-file constants
|
|
275
|
-
//
|
|
276
|
-
// localScopedNames is non-empty, so these stay unimported/undeclared (and absent from the
|
|
277
|
-
// bundle) for every non-scoped .vue file.
|
|
254
|
+
// Only a scoped file needs scopeClassName + its two per-file constants, so these stay
|
|
255
|
+
// unimported for every non-scoped .vue file.
|
|
278
256
|
const engineImports =
|
|
279
257
|
localScopedNames.size > 0 ? 'registerStyles, scopeClassName as __scopeClass' : 'registerStyles';
|
|
280
258
|
|
|
@@ -285,49 +263,48 @@ async function compileSfc(src, filename) {
|
|
|
285
263
|
`const __scopeId = ${JSON.stringify(scopeId)};`,
|
|
286
264
|
);
|
|
287
265
|
}
|
|
288
|
-
// Each <style module> binding becomes a
|
|
289
|
-
//
|
|
290
|
-
//
|
|
291
|
-
// usable both from the inlined template (`:class="$style.card"`) and from <script setup> code
|
|
292
|
-
// itself (`$style.card`), no extra wiring needed on either side.
|
|
266
|
+
// Each <style module> binding becomes a top-level const holding its name->scopedName map,
|
|
267
|
+
// placed before the compiled `export default {...}` so it's a closed-over module-scope
|
|
268
|
+
// variable usable both from the inlined template and from <script setup> code itself.
|
|
293
269
|
for (const [bindingName, classMap] of cssModuleBindings) {
|
|
294
270
|
preamble.push(`const ${bindingName} = ${JSON.stringify(classMap)};`);
|
|
295
271
|
}
|
|
296
272
|
|
|
297
|
-
return
|
|
273
|
+
return (
|
|
274
|
+
[`import { ${engineImports} } from '@symbiote-native/engine';`, ...preamble, code].join('\n') +
|
|
275
|
+
'\n'
|
|
276
|
+
);
|
|
298
277
|
}
|
|
299
278
|
|
|
300
279
|
// Exported separately from `transform` so tests can assert on the compiled SFC output
|
|
301
280
|
// (imports, injected `registerStyles` call) without driving the full upstream RN Babel preset.
|
|
302
281
|
module.exports.compileSfc = compileSfc;
|
|
303
282
|
|
|
304
|
-
// Async uniformly, including
|
|
305
|
-
//
|
|
306
|
-
//
|
|
307
|
-
//
|
|
308
|
-
//
|
|
309
|
-
// exercised shape, not a hack. A sync fast-path for
|
|
310
|
-
// the no-preprocessor branches would fork this function into two shapes to save a single
|
|
311
|
-
// microtask on a call that only ever runs at Metro build time, content-hash-cached — not worth
|
|
312
|
-
// the duplication.
|
|
283
|
+
// Async uniformly, including branches that never touch a preprocessor: compileSfc() itself is
|
|
284
|
+
// async now (a scss/sass/less/stylus block awaits preprocessors.ts's compile()), and Metro's own
|
|
285
|
+
// metro-transform-worker already awaits transformer.transform(...), so this is a supported
|
|
286
|
+
// shape - not worth forking a sync fast-path to save one microtask on a build-time,
|
|
287
|
+
// content-hash-cached call.
|
|
313
288
|
module.exports.transform = async function transform(params) {
|
|
314
289
|
if (params.filename.endsWith('.vue')) {
|
|
315
290
|
const code = await compileSfc(params.src, params.filename);
|
|
316
|
-
// Re-label as .tsx so RN's transformer strips
|
|
317
|
-
//
|
|
291
|
+
// Re-label as .tsx so RN's transformer strips TS from <script setup lang="ts">. Metro
|
|
292
|
+
// tracks the real path separately.
|
|
318
293
|
return upstreamTransformer.transform({
|
|
319
294
|
...params,
|
|
320
295
|
src: code,
|
|
321
296
|
filename: params.filename + '.tsx',
|
|
322
297
|
});
|
|
323
298
|
}
|
|
324
|
-
// A standalone style file (
|
|
325
|
-
//
|
|
326
|
-
// .vue files exactly like from any other adapter's example. isStyleFile recognizes
|
|
327
|
-
// .css/.scss/.sass/.less/.styl/.stylus (+ each .module.* twin).
|
|
299
|
+
// A standalone style file (not a .vue file's inline <style> block) via the framework-agnostic
|
|
300
|
+
// compileCssFile path. isStyleFile recognizes .css/.scss/.sass/.less/.styl/.stylus (+ .module.* twins).
|
|
328
301
|
if (isStyleFile(params.filename)) {
|
|
329
302
|
const { code } = await compileCssFile(params.src, params.filename);
|
|
330
|
-
return upstreamTransformer.transform({
|
|
303
|
+
return upstreamTransformer.transform({
|
|
304
|
+
...params,
|
|
305
|
+
src: code,
|
|
306
|
+
filename: params.filename + '.js',
|
|
307
|
+
});
|
|
331
308
|
}
|
|
332
309
|
return upstreamTransformer.transform(params);
|
|
333
310
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbiote-native/vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "SymbioteNative's Vue adapter — a @vue/runtime-core createRenderer driving real native iOS/Android views through the same engine as the React adapter.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"@vue/compiler-sfc": "^3.5.13",
|
|
47
47
|
"@vue/runtime-core": "^3.5.13",
|
|
48
48
|
"typescript": "~6.0.0",
|
|
49
|
-
"@symbiote-native/components": "0.
|
|
50
|
-
"@symbiote-native/css-parser": "0.
|
|
49
|
+
"@symbiote-native/components": "0.4.0",
|
|
50
|
+
"@symbiote-native/css-parser": "0.3.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"@symbiote-native/engine": ">=0.1.7",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"react-native": ">=0.86"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@symbiote-native/engine": "0.
|
|
58
|
+
"@symbiote-native/engine": "0.2.0",
|
|
59
59
|
"@symbiote-native/test-utils": "0.1.6"
|
|
60
60
|
},
|
|
61
61
|
"scripts": {
|