Last active
November 28, 2023 19:14
-
-
Save sjorsrijsdam/6bbfe5f3a32cb4f4dce52d0c0cc058d8 to your computer and use it in GitHub Desktop.
Custom Enhance element to be able to debug view state
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Custom Enhance element to debug/inspect the `state` property | |
// that is passed to Enhance views. | |
// | |
// Optional `key` attribute can be used to inspect from | |
// a desired depth. | |
// | |
// Default styling is Monokai Midnight, but can be overridden | |
// by changing the various custom properties. | |
// | |
// Usage: | |
// `<d-bug></d-bug>` | |
// or: | |
// `<d-bug key="some.depth.withIndex[4]"></d-bug> | |
export default function dBug ({ html, state }) { | |
const TYPES = Object.freeze({ | |
'string': 'string', | |
'number': 'number', | |
'undefined': 'undefined', | |
'null': 'null', | |
'array': 'array', | |
'object': 'object', | |
'boolean': 'boolean', | |
}); | |
function getType (value) { | |
if (value === null) { | |
return TYPES.null; | |
} | |
if (value === undefined) { | |
return TYPES.undefined; | |
} | |
if (typeof value === 'string') { | |
return TYPES.string; | |
} | |
if (typeof value === 'number') { | |
return TYPES.number; | |
} | |
if (typeof value === 'boolean') { | |
return TYPES.boolean; | |
} | |
if (Array.isArray(value)) { | |
return TYPES.array; | |
} | |
return TYPES.object; | |
} | |
function renderPrimitive (value) { | |
return `<span class="type-${getType(value)}">${value}</span>`; | |
} | |
function renderNonPrimitive (key, value) { | |
const label = key ? `${renderPrimitive(key)}: ` : ''; | |
return [ | |
`<details class="type-${getType(value)}">`, | |
`<summary><span>${label && label}</span></summary>`, | |
render(value), | |
'</details>', | |
].join(''); | |
} | |
function render (value) { | |
const entries = []; | |
if (getType(value) === TYPES.object) { | |
Object.keys(value).forEach(key => { | |
const item = value[key]; | |
const itemType = getType(item); | |
if (itemType === TYPES.array || itemType === TYPES.object) { | |
entries.push( | |
`<div>${renderNonPrimitive(key, item)}</div>` | |
); | |
} else { | |
entries.push(`<div>${renderPrimitive(key)}: ${renderPrimitive(item)}</div>`); | |
} | |
}); | |
} else if (getType(value) === TYPES.array) { | |
value.forEach(item => { | |
const itemType = getType(item); | |
if (itemType === TYPES.array || itemType === TYPES.object) { | |
entries.push(`<div>${renderNonPrimitive('', item)}</div>`); | |
} else { | |
entries.push(`<div>${renderPrimitive(item)}</div>`); | |
} | |
}); | |
} else { | |
entries.push(renderPrimitive(value)); | |
} | |
return entries.join(''); | |
} | |
let debug = state; | |
if (state.attrs.key) { | |
state.attrs.key.split('.').forEach(key => { | |
const keyParts = key.split('['); | |
keyParts.forEach(keyPart => { | |
debug = debug[keyPart.replace(']', '')]; | |
}); | |
}); | |
} | |
return html` | |
<style scope="module"> | |
:host { | |
--string-color: #E6DB74; | |
--number-color: #AE81FF; | |
--boolean-color: #AE81FF; | |
--null-color: #AE81FF; | |
--undefined-color: #AE81FF; | |
--text-color: #FFF; | |
--background-color: #000; | |
display: block; | |
width: fit-content; | |
background-color: var(--background-color); | |
color: var(--text-color); | |
padding: 1ch; | |
} | |
span.type-string { | |
color: var(--string-color); | |
} | |
span.type-string::before, | |
span.type-string::after { | |
content: '"'; | |
} | |
span.type-number { | |
color: var(--number-color); | |
} | |
span.type-undefined { | |
color: var(--undefined-color); | |
} | |
span.type-null { | |
color: var(--null-color); | |
} | |
span.type-boolean { | |
color: var(--boolean-color); | |
} | |
details > div { | |
padding-left: 4ch; | |
} | |
details summary { | |
display: flex; | |
cursor: pointer; | |
} | |
details summary::before { | |
content: ' ▶'; | |
order: 2; | |
} | |
details[open] > summary::before { | |
content: ' ▼'; | |
order: 2; | |
} | |
details.type-array > summary > span::after { | |
content: '[...]'; | |
} | |
details.type-array[open] > summary > span::after { | |
content: '['; | |
} | |
details.type-array[open]::after { | |
content: ']'; | |
display: block; | |
} | |
details.type-object > summary > span::after { | |
content: '{...}'; | |
} | |
details.type-object[open] > summary > span::after { | |
content: '{'; | |
} | |
details.type-object[open]::after { | |
content: '}'; | |
display: block; | |
} | |
</style> | |
<pre><code>${render(debug)}</code></pre> | |
`; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment