Skip to content

Commit a84174a

Browse files
committed
feat: add ability to include CSS links
1 parent 19ed153 commit a84174a

File tree

4 files changed

+59
-5
lines changed

4 files changed

+59
-5
lines changed

src/editor/FileSelector.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ const store = inject('store') as Store
77
const pending = ref(false)
88
const pendingFilename = ref('Comp.vue')
99
const importMapFile = 'import-map.json'
10+
const linksFile = 'links.json'
1011
const showImportMap = inject('import-map') as Ref<boolean>
1112
const files = computed(() =>
1213
Object.entries(store.state.files)
13-
.filter(([name, file]) => name !== importMapFile && !file.hidden)
14+
.filter(([name, file]) => ![importMapFile, linksFile].includes(name) && !file.hidden)
1415
.map(([name]) => name)
1516
)
1617
@@ -120,6 +121,9 @@ const activeFile = computed({
120121
<v-tab v-if="showImportMap" class="file import-map" size="small" :value="importMapFile">
121122
Import Map
122123
</v-tab>
124+
<v-tab class="file" size="small" :value="linksFile">
125+
Links
126+
</v-tab>
123127
</v-tabs>
124128
</template>
125129

src/output/Preview.vue

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ watch(
4848
}
4949
)
5050
51+
watch(
52+
() => store.state.files['links.json'].code,
53+
() => {
54+
try {
55+
createSandbox()
56+
} catch (e) {
57+
store.state.errors = [e as Error]
58+
}
59+
}
60+
)
61+
5162
// reset sandbox when version changes
5263
watch(() => store.state.resetFlip, createSandbox)
5364
@@ -85,10 +96,23 @@ function createSandbox() {
8596
if (!importMap.imports.vue) {
8697
importMap.imports.vue = store.state.vueRuntimeURL
8798
}
88-
const sandboxSrc = srcdoc.replace(
89-
/<!--IMPORT_MAP-->/,
90-
JSON.stringify(importMap)
91-
)
99+
100+
const links = store.getLinks()
101+
102+
if (!links.css) {
103+
links.css = []
104+
}
105+
106+
const sandboxSrc = srcdoc
107+
.replace(
108+
/<!--IMPORT_MAP-->/,
109+
JSON.stringify(importMap)
110+
)
111+
.replace(
112+
/<!--CSS-->/,
113+
links.css.map((link: string) => `<link rel="stylesheet" type="text/css" href="${link}" />`).join('\n')
114+
)
115+
92116
sandbox.srcdoc = sandboxSrc
93117
container.value.appendChild(sandbox)
94118

src/output/srcdoc.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@
252252
<!-- ES Module Shims: Import maps polyfill for modules browsers without import maps support (all except Chrome 89+) -->
253253
<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.wasm.js"></script>
254254
<script type="importmap"><!--IMPORT_MAP--></script>
255+
<!--CSS-->
255256
</head>
256257
<body></body>
257258
</html>

src/store.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export interface Store {
7070
getImportMap: () => any
7171
initialShowOutput: boolean
7272
initialOutputMode: OutputModes
73+
getLinks: () => any
7374
}
7475

7576
export interface StoreOptions {
@@ -133,6 +134,7 @@ export class ReplStore implements Store {
133134
})
134135

135136
this.initImportMap()
137+
this.initLinks()
136138
}
137139

138140
// don't start compiling until the options are set
@@ -193,6 +195,7 @@ export class ReplStore implements Store {
193195
this.state.mainFile = mainFile
194196
this.state.files = files
195197
this.initImportMap()
198+
this.initLinks()
196199
this.setActive(mainFile)
197200
this.forceSandboxReset()
198201
}
@@ -231,6 +234,18 @@ export class ReplStore implements Store {
231234
}
232235
}
233236

237+
private initLinks() {
238+
const links = this.state.files['links.json']
239+
if (!links) {
240+
this.state.files['links.json'] = new File(
241+
'links.json',
242+
JSON.stringify({
243+
css: []
244+
}, null, 2)
245+
)
246+
}
247+
}
248+
234249
getImportMap() {
235250
try {
236251
return JSON.parse(this.state.files['import-map.json'].code)
@@ -281,4 +296,14 @@ export class ReplStore implements Store {
281296
this.forceSandboxReset()
282297
console.info(`[@vue/repl] Now using default Vue version`)
283298
}
299+
300+
getLinks() {
301+
try {
302+
return JSON.parse(this.state.files['links.json'].code)
303+
} catch (e) {
304+
this.state.errors = [
305+
`Syntax error in links.json: ${(e as Error).message}`
306+
]
307+
}
308+
}
284309
}

0 commit comments

Comments
 (0)