Skip to content

Commit

Permalink
feat(playground): transfrom custom css (#3065)
Browse files Browse the repository at this point in the history
  • Loading branch information
zyyv committed Sep 2, 2023
1 parent a80d1af commit bccd4fd
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 34 deletions.
5 changes: 2 additions & 3 deletions packages/inspector/client/components/TitleBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,19 @@ const emit = defineEmits<{
style="background-color: var(--cm-background)"
border="l y gray/20"
text="gray/80"
p1
min-h-30px
max-h-30px
select-none
flex
all:my-auto
>
<div flex @click="e => emit('titleClick', e)">
<div p1 flex @click="e => emit('titleClick', e)">
<slot name="before" />
<div mr-2 op-60 shrink-0>
{{ title }}
</div>
</div>
<div flex gap-2 flex-auto>
<div px1 flex gap-2 flex-auto h-full>
<slot />
</div>
</div>
Expand Down
3 changes: 3 additions & 0 deletions playground/src/auto-imports.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ declare global {
const toValue: typeof import('vue')['toValue']
const toggleDark: typeof import('./composables/dark')['toggleDark']
const togglePanel: typeof import('./composables/panel')['togglePanel']
const transformedCSS: typeof import('./composables/uno')['transformedCSS']
const transformedHTML: typeof import('./composables/uno')['transformedHTML']
const triggerRef: typeof import('vue')['triggerRef']
const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount']
Expand Down Expand Up @@ -466,6 +467,7 @@ declare module 'vue' {
readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
readonly toggleDark: UnwrapRef<typeof import('./composables/dark')['toggleDark']>
readonly togglePanel: UnwrapRef<typeof import('./composables/panel')['togglePanel']>
readonly transformedCSS: UnwrapRef<typeof import('./composables/uno')['transformedCSS']>
readonly transformedHTML: UnwrapRef<typeof import('./composables/uno')['transformedHTML']>
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
readonly tryOnBeforeMount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeMount']>
Expand Down Expand Up @@ -795,6 +797,7 @@ declare module '@vue/runtime-core' {
readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
readonly toggleDark: UnwrapRef<typeof import('./composables/dark')['toggleDark']>
readonly togglePanel: UnwrapRef<typeof import('./composables/panel')['togglePanel']>
readonly transformedCSS: UnwrapRef<typeof import('./composables/uno')['transformedCSS']>
readonly transformedHTML: UnwrapRef<typeof import('./composables/uno')['transformedHTML']>
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
readonly tryOnBeforeMount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeMount']>
Expand Down
2 changes: 1 addition & 1 deletion playground/src/components/HeaderBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function handleReset() {
if (confirm('Reset all settings? It can NOT be undone.')) {
inputHTML.value = defaultHTML
customConfigRaw.value = defaultConfigRaw
options.value.transform = false
options.value.transformHtml = false
customCSS.value = defaultCSS
}
}
Expand Down
4 changes: 2 additions & 2 deletions playground/src/components/panel/PanelConfig.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ if (!customConfigRaw.value)
/>
</template>
<div
flex flex-1 justify-end items-center w-full gap2
flex flex-1 justify-end items-center w-full h-full gap2
transition duration-400
:class="isCollapsed(index) ? 'op0' : ''"
un-children="inline-flex items-center cursor-pointer gap1"
>
<div w-1px h-28px my--1 bg-gray:20 />
<div w-1px h-full bg-gray:20 />
<button
i-ri-mist-line icon-btn
title="Format"
Expand Down
25 changes: 22 additions & 3 deletions playground/src/components/panel/PanelCustomCss.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ import { Pane } from 'splitpanes'
import { customCSS } from '../../composables/url'
defineProps<{ index: number }>()
const computedCustomCSS = computed({
get: () => unref(options.value.transformCustomCSS ? transformedCSS : customCSS),
set: (value) => {
customCSS.value = value
},
})
</script>

<template>
Expand All @@ -20,12 +27,16 @@ defineProps<{ index: number }>()
/>
</template>
<div
flex justify-end items-center w-full gap2
flex justify-end items-center w-full h-full gap2
transition duration-400
:class="isCollapsed(index) ? 'op0' : ''"
un-children="inline-flex items-center cursor-pointer gap-1"
>
<div w-1px h-28px my--1 bg-gray:20 />
<label>
<input v-model="options.transformCustomCSS" type="checkbox">
<span text-sm>Transform</span>
</label>
<div w-1px h-full my--1 bg-gray:20 />
<button
i-ri-mist-line icon-btn
title="Format"
Expand All @@ -34,6 +45,14 @@ defineProps<{ index: number }>()
</div>
</TitleBar>
</div>
<CodeMirror v-model="customCSS" flex-auto mode="css" border="l gray-400/20" class="scrolls" />
<CodeMirror
v-model="computedCustomCSS"
:read-only="options.transformCustomCSS"
flex-auto
mode="css"
border="l
gray-400/20"
class="scrolls"
/>
</Pane>
</template>
10 changes: 5 additions & 5 deletions playground/src/components/panel/PanelHtml.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ if (!inputHTML.value)
inputHTML.value = defaultHTML
const computedInputHTML = computed({
get: () => unref(options.value.transform ? transformedHTML : inputHTML),
get: () => unref(options.value.transformHtml ? transformedHTML : inputHTML),
set: (value) => {
inputHTML.value = value
},
Expand All @@ -30,16 +30,16 @@ const computedInputHTML = computed({
/>
</template>
<div
flex justify-end items-center w-full gap2
flex justify-end items-center w-full h-full gap2
transition duration-400
:class="isCollapsed(index) ? 'op0' : ''"
un-children="inline-flex items-center cursor-pointer gap-1"
>
<label>
<input v-model="options.transform" type="checkbox">
<input v-model="options.transformHtml" type="checkbox">
<span text-sm>Transform</span>
</label>
<div w-1px h-28px my--1 bg-gray:20 />
<div w-1px h-full bg-gray:20 />
<button
i-ri-mist-line icon-btn
title="Format"
Expand All @@ -56,7 +56,7 @@ const computedInputHTML = computed({
:matched="output?.matched || new Set()"
:annotations="annotations"
:get-hint="getHint"
:read-only="options.transform"
:read-only="options.transformHtml"
/>
</Pane>
</template>
4 changes: 3 additions & 1 deletion playground/src/components/panel/PanelOutputCss.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ defineProps<{ index: number }>()
/>
</template>
<div
flex justify-end items-center w-full gap2 transition duration-400 :class="isCollapsed(index) ? 'op0' : ''"
flex justify-end items-center w-full h-full
gap2 transition duration-400
:class="isCollapsed(index) ? 'op0' : ''"
un-children="inline-flex items-center cursor-pointer gap1"
>
<label>
Expand Down
9 changes: 8 additions & 1 deletion playground/src/composables/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@ export const defaultHTML = `

export { defaultConfigRaw, version }

export const defaultCSS = ''
export const defaultCSS = `
/* Write custom CSS here, and transformer support. For example: */
/* .custom {
font-weight: 500;
@apply p1 text-(white xl);
background-color: theme('colors.red.400');
} */
`.trim()
export const customCSSLayerName = 'playground'

export const defaultOptions = '{}'
Expand Down
4 changes: 2 additions & 2 deletions playground/src/composables/prettier.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { useCSSPrettify, useHTMLPrettify, useJSPrettify } from '../../../packages/inspector/client/composables/usePrettify'

export function formatHTML() {
inputHTML.value = useHTMLPrettify(options.value.transform ? transformedHTML : inputHTML).value
inputHTML.value = useHTMLPrettify(options.value.transformHtml ? transformedHTML : inputHTML).value
}

export function formatConfig() {
customConfigRaw.value = useJSPrettify(customConfigRaw).value
}

export function formatCSS() {
customCSS.value = useCSSPrettify(customCSS).value
customCSS.value = useCSSPrettify(options.value.transformCustomCSS ? transformedCSS : customCSS).value
}

export const showPreflights = ref(false)
Expand Down
39 changes: 26 additions & 13 deletions playground/src/composables/uno.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ let customConfig: UserConfig = {}
let autocomplete = createAutocomplete(uno)
let initial = true

const { transformedHTML, transformed, getTransformed } = useTransformer()
const { transformedHTML, transformed, getTransformed, transformedCSS } = useTransformer()

export async function generate() {
output.value = await uno.generate(transformedHTML.value || '')
Expand Down Expand Up @@ -62,16 +62,22 @@ debouncedWatch(
const preflights = (result.preflights ?? []).filter(p => p.layer !== customCSSLayerName)
preflights.push({
layer: customCSSLayerName,
getCSS: () => customCSS.value,
getCSS: () => transformedCSS.value,
})

result.preflights = preflights
customConfig = result
reGenerate()
if (initial) {
const { transformers = [] } = uno.config
if (transformers.length)
transformed.value = await getTransformed()
if (transformers.length) {
transformed.value = await getTransformed('html')
const _p = uno.config.preflights.find(i => i.layer === customCSSLayerName)
_p!.getCSS = async () => {
transformedCSS.value = (await getTransformed('css')).output
return transformedCSS.value
}
}
initial = false
}
}
Expand All @@ -85,16 +91,17 @@ debouncedWatch(
)

watch(
transformed,
transformedHTML,
generate,
{ immediate: true },
)

watch(defaultConfig, reGenerate)

function useTransformer() {
const transformed = computedAsync(async () => await getTransformed())
const transformedHTML = computed(() => transformed.value?.html)
const transformed = computedAsync(async () => await getTransformed('html'))
const transformedHTML = computed(() => transformed.value?.output)
const transformedCSS = computedAsync(async () => (await getTransformed('css')).output)

async function applyTransformers(code: MagicString, id: string, enforce?: 'pre' | 'post') {
let { transformers } = uno.config
Expand All @@ -116,17 +123,23 @@ function useTransformer() {
return annotations
}

async function getTransformed() {
const id = 'input.html'
const input = new MagicString(inputHTML.value)
async function getTransformed(type: 'html' | 'css') {
const id = type === 'html' ? 'input.html' : 'input.css'
const input = new MagicString(type === 'html' ? inputHTML.value : customCSS.value)
const annotations = []
annotations.push(...await applyTransformers(input, id, 'pre'))
annotations.push(...await applyTransformers(input, id))
annotations.push(...await applyTransformers(input, id, 'post'))
return { html: input.toString(), annotations }
return { output: type === 'css' ? cleanOutput(input.toString()) : input.toString(), annotations }
}

return { transformedHTML, transformed, getTransformed }
function cleanOutput(code: string) {
return code.replace(/\/\*\s*?[\s\S]*?\s*?\*\//g, '')
.replace(/\n\s+/g, '\n')
.trim()
}

return { transformedHTML, transformed, getTransformed, transformedCSS }
}

export { transformedHTML }
export { transformedHTML, transformedCSS }
7 changes: 4 additions & 3 deletions playground/src/composables/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ import { decompressFromEncodedURIComponent as decode, compressToEncodedURICompon
const params = new URLSearchParams(window.location.search || localStorage.getItem(STORAGE_KEY) || '')

interface Options {
transform?: boolean
transformHtml?: boolean
transformCustomCSS?: boolean
responsive?: boolean
width?: number
height?: number
}

export const customConfigRaw = ref(decode(params.get('config') || '') || defaultConfigRaw)
export const inputHTML = ref(decode(params.get('html') || '') || defaultHTML)
export const options = ref<Options>(JSON.parse(decode(params.get('options') || '') || defaultOptions))
export const customConfigRaw = ref(decode(params.get('config') || '') || defaultConfigRaw)
export const customCSS = ref(decode(params.get('css') || '') || defaultCSS)
export const options = ref<Options>(JSON.parse(decode(params.get('options') || '') || defaultOptions))

throttledWatch(
[customConfigRaw, inputHTML, customCSS, options],
Expand Down

0 comments on commit bccd4fd

Please sign in to comment.