-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Package
v4.x
Description
First of all, thank you for this great Nuxt Module and a comprehensive documentation.
I just found it a bit difficult to read some complex component prop type with inline code, and I think that we can make the documentation easier to read.
Problem
For example:
Sometimes, we have inline code block with long content in:
- API Props Type
- API Props Default
- API Slots Type
- (haven't confirmed, but maybe API Emits Type as well)
Their contents can be:
- Nested type
- Union with a lot of members
- Many properties
- etc.
For props with nested type like LocaleSelect.virtualize and LocaleSelect.createItem, we can click "Show properties" to view detail.
But for props like ui, which is usually a type with a lot of properties, it's hard to read and find what properties there are.
Solution suggestion
All of the above example are rendered with <HighlightInlineType> component.
1. Use Markdown code block + format content with prettier
Screenshots
- ✅ Complex type / value looks better now
⚠️ We need to do some string processing to the formatted content like the implementation below⚠️ We might need to give min-width to each table column, otherwise some code block will be shrinked⚠️ This component is called<HighlightInlineType>, but now it can produce type with code block- ❌ Prettier might be too opinionated and sometimes make the type more difficult to read. (e.g. line wrap)
- ❌ Even for simple type like
boolean, it will become a code block, which takes more spaces- In the screenshot of my prototype, I've tried to add a multiline check to keep simple type inline.
- ❌ It looks ugly for prop name a inline text, while prop type in the row a code block. Their margin-top are different.
- Maybe we can fix by give them universal margin
- ❓ Not sure about how performance of page rendering will be affected.
- I've measured the
formatTypefunction withpreformance.now(), and it takes about 30ms in average.
- I've measured the
- ❓ Not sure about what is the appropriate value of the
printWidthprettier config
Implementation
import prettier from 'prettier/standalone'
import typescriptPlugin from 'prettier/plugins/typescript'
import estreePlugin from 'prettier/plugins/estree'
const formatType = async (type: string) => {
const TYPE_WRAPPER = 'type __Formatted'
const INDENT = ' '
let formatted: string
try {
formatted = await prettier.format(
`${TYPE_WRAPPER} = ${type}`,
{
parser: 'typescript',
plugins: [typescriptPlugin, estreePlugin],
tabWidth: 2,
semi: false,
printWidth: 40
}
)
} catch {
return null
}
formatted = formatted
.replace(/^type\s+__Formatted\s*=\s*/m, '')
.replace(/^\|\s*/m, '') // Remove leading `|` added by union formatting
const allLinesShareIndent = formatted
.split('\n')
.every(line => line.trim() === '' || line.startsWith(INDENT))
return allLinesShareIndent
? formatted.replace(new RegExp(`^${INDENT}`, 'gm'), '')
: formatted
}
onMounted(async () => {
const formattedType = await formatType(type.value) ?? ''
const md = formattedType.split('\n').length > 2
? `\`\`\`ts-type\n${formattedType}\n\`\`\`` // Code block
: `\`\` ${type.value} \`\`{lang="ts-type"}` // Inline code
ast.value = await parseMarkdown(md)
})2. Use Markdown code block + simple string processing
Screenshot
- Simply do line break for union
- For
ui, simply change it toPartial<Record<TKeys, ClassNameValue>>
- ✅ No need to execute runtime prettier format
- ❌ Corner cases like union in nested properties are not considered
- Others are same as ## 1.
Implementation
const formatType = (type: string) => {
if (!type.includes('?: ClassNameValue;')) return type.replaceAll(' | ', '\n | ')
const keys = type.matchAll(/\s(\S+?)\?/g)
.map(match => match[1])
.map(key => JSON.stringify(key))
.toArray()
.join('\n | ')
return `Partial<Record<\n ${keys},\n ClassNameValue\n>>`
}3. Convert only type of ui prop to <Partial<Record<TKeys, ClassNameValue>> + render in code block
Actually this is the main motivation of creating this issue. I want to have at least the ui prop to be easier to read.
Any ideas are appreciated.
Additional context
No response






