import { splitByCase, upperFirst, camelCase, kebabCase } from 'scule' const playground = ({ name }) => { const upperName = splitByCase(name).map(p => upperFirst(p)).join('') const kebabName = kebabCase(name) return { filename: `playgrounds/nuxt/app/pages/components/${kebabName}.vue`, contents: ` ` } } const component = ({ name, primitive, prose, content }) => { const upperName = splitByCase(name).map(p => upperFirst(p)).join('') const camelName = camelCase(name) const kebabName = kebabCase(name) const nested = prose || content const dirPrefix = prose ? 'prose/' : (content ? 'content/' : '') const importPrefix = nested ? '../..' : '..' const componentKey = prose ? `prose.${camelName}` : camelName const componentConfigArgs = prose ? `typeof theme, AppConfig, '${camelName}', 'ui.prose'` : `typeof theme, AppConfig, '${camelName}'` const appConfigLookup = prose ? `appConfig.ui?.prose?.${camelName}` : `appConfig.ui?.${camelName}` return { filename: `src/runtime/components/${dirPrefix}${upperName}.vue`, contents: primitive ? ` ` : ` ` } } const theme = ({ name, prose, content }) => { const kebabName = kebabCase(name) return { filename: `src/theme/${prose ? 'prose/' : ''}${content ? 'content/' : ''}${kebabName}.ts`, contents: prose ? ` export default { base: '' } ` : ` export default { slots: { root: '' } } ` } } const test = ({ name, prose, content }) => { const upperName = splitByCase(name).map(p => upperFirst(p)).join('') return { filename: `test/components/${content ? 'content/' : ''}${upperName}.spec.ts`, contents: prose ? undefined : ` import { describe, it, expect } from 'vitest' import { axe } from 'vitest-axe' import { mountSuspended } from '@nuxt/test-utils/runtime' import ${upperName} from '../../${content ? '../' : ''}src/runtime/components/${content ? 'content/' : ''}${upperName}.vue' import { renderEach } from '../${content ? '../' : ''}component-render' describe('${upperName}', () => { const props = {} renderEach(${upperName}, [ // Props ['with as', { props: { as: 'section' } }], ['with class', { props: { class: '' } }], ['with ui', { props: { ui: {} } }], // Slots ['with default slot', { props, slots: { default: () => 'Default slot' } }] ]) it('passes accessibility tests', async () => { const wrapper = await mountSuspended(${upperName}, { props }) expect(await axe(wrapper.element)).toHaveNoViolations() }) }) ` } } const docs = ({ name, primitive }) => { const kebabName = kebabCase(name) const upperName = splitByCase(name).map(p => upperFirst(p)).join('') return { filename: `docs/content/docs/2.components/${kebabName}.md`, contents: `--- title: ${upperName} description: '' links:${primitive ? '' : ` - label: ${upperName} icon: i-custom-reka-ui to: https://reka-ui.com/docs/components/${kebabName}`} - label: GitHub icon: i-simple-icons-github to: https://github.com/nuxt/ui/blob/v4/src/runtime/components/${upperName}.vue navigation.badge: Soon --- ## Usage ## Examples ## API ### Props :component-props ### Slots :component-slots ### Emits :component-emits ## Theme :component-theme ## Changelog :component-changelog ` } } export default { playground, component, theme, test, docs }