Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 4 additions & 1 deletion alias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ const tsconfig = JSON.parse(raw)
tsconfig.compilerOptions.paths = Object.fromEntries(
Object.entries(alias)
.filter(([key]) => !key.endsWith('.css'))
.map(([key, value]) => [key, [`./${relative(root, value)}`]]),
.map(([key, value]) => [
key,
[`./${relative(root, value)}`],
]),
)
const newRaw = JSON.stringify(tsconfig, null, 2)
if (newRaw !== raw)
Expand Down
7 changes: 6 additions & 1 deletion bump.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export default defineConfig({
*/
execute: async (operation) => {
await syncStarterVersion(operation.state.newVersion)
await x('pnpm', ['install', '--frozen-lockfile=false'], { nodeOptions: { stdio: 'inherit', cwd: process.cwd() } })
await x('pnpm', ['install', '--frozen-lockfile=false'], {
nodeOptions: {
stdio: 'inherit',
cwd: process.cwd(),
},
})
},
})
9 changes: 7 additions & 2 deletions design/build-shadow-css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,19 @@ export async function buildShadowCss(options: BuildShadowCssOptions): Promise<Bu
const generator = await createGenerator(config)

const tokens = new Set<string>()
for (const file of [...files, ...designFiles]) {
for (const file of [
...files,
...designFiles,
]) {
const content = await fs.readFile(file, 'utf-8')
await generator.applyExtractors(content, file, tokens)
}

// Hand-written stylesheets may use `--at-apply`. Run each through the
// configured transformers before merging them in the caller's order.
const userStylePaths = typeof userStylePath === 'string' ? [userStylePath] : (userStylePath ?? [])
const userStylePaths = typeof userStylePath === 'string'
? [userStylePath]
: (userStylePath ?? [])
const userStyles: string[] = []
for (const userStylePath of userStylePaths) {
const userStyle = new MagicString(await fs.readFile(userStylePath, 'utf-8').catch(() => ''))
Expand Down
16 changes: 12 additions & 4 deletions design/design.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ export function button({ variant = 'primary', size = 'md', class: extra }: Butto
link: 'inline-flex items-center gap-1.5 color-active hover:underline underline-offset-2',
}
const sizeClass = size === 'sm'
? (variant === 'primary' ? 'text-sm px-2.5! py-1!' : 'text-sm')
: size === 'lg' ? 'text-base px-4! py-2!' : ''
? (variant === 'primary'
? 'text-sm px-2.5! py-1!'
: 'text-sm')
: size === 'lg'
? 'text-base px-4! py-2!'
: ''
return cx(variantClass[variant], sizeClass, extra)
}

Expand All @@ -37,8 +41,12 @@ export type IconButtonSize = 'md' | 'sm'
export interface IconButtonProps { variant?: IconButtonVariant, size?: IconButtonSize, class?: string }

export function iconButton({ variant = 'outline', size = 'md', class: extra }: IconButtonProps = {}): string {
const base = variant === 'ghost' ? 'btn-icon' : 'btn-icon-square'
const sizeClass = size === 'sm' ? 'w-7! h-7! text-sm' : ''
const base = variant === 'ghost'
? 'btn-icon'
: 'btn-icon-square'
const sizeClass = size === 'sm'
? 'w-7! h-7! text-sm'
: ''
return cx(base, sizeClass, extra)
}

Expand Down
4 changes: 3 additions & 1 deletion design/dock-icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ const ICONIFY_ID = /^(?:i-)?([\w-]+):([\w-]+)$/
* await dockIconSvg('ph:git-branch-duotone') // → '<svg ...>...</svg>'
*/
export async function dockIconSvg(name: string | { light: string, dark: string } | undefined): Promise<string | undefined> {
const id = typeof name === 'string' ? name : name?.light
const id = typeof name === 'string'
? name
: name?.light
if (!id)
return undefined
const match = id.match(ICONIFY_ID)
Expand Down
27 changes: 21 additions & 6 deletions design/uno.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,24 @@ export function createDesignConfig(options: CreateDesignConfigOptions = {}) {
return defineConfig({
presets: [
presetAnthonyDesign({ primary: '#3a6a45' }),
...(Array.isArray(base) ? base : [base]),
...(Array.isArray(base)
? base
: [base]),
presetIcons({ scale: 1.1 }),
],
transformers: [transformerDirectives(), transformerVariantGroup()],
transformers: [
transformerDirectives(),
transformerVariantGroup(),
],
/**
* The shared class-helper builders (`design/design.ts`) assemble their class
* chains at runtime, so every app scans that one file (it carries
* `@unocss-include`) for extraction regardless of its own framework globs.
*/
content: {
filesystem: [fileURLToPath(new URL('./design.ts', import.meta.url))],
filesystem: [
fileURLToPath(new URL('./design.ts', import.meta.url)),
],
/**
* Restates UnoCSS's default pipeline exclude. Without it, `mergeConfigs`
* leaves `exclude: []`, and UnoCSS 66.11 then treats every module as
Expand All @@ -68,11 +75,17 @@ export function createDesignConfig(options: CreateDesignConfigOptions = {}) {
* Wind leaves bare `border`/`border-b` at currentColor; restore the subtle
* shared border color (matching `border-base`) for unqualified borders.
*/
preflights: [{ getCSS: () => '*,::before,::after{border-color:#8882}' }],
preflights: [
{
getCSS: () => '*,::before,::after{border-color:#8882}',
},
],
theme: {
// Stable palette for status marks and preview content that intentionally
// keeps the default accent when the surrounding panel adopts a theme.
colors: { devframe: resolvePrimary('#3a6a45') },
colors: {
devframe: resolvePrimary('#3a6a45'),
},
},
shortcuts: {
/** Fixed semantic colors stay independent of the panel's primary accent. */
Expand Down Expand Up @@ -193,7 +206,9 @@ export function rewireBakedPrimaryColors(css: string, primaryRamp: Record<string
const rgb = hex && hexToRgbTriplet(hex)
if (!rgb)
continue
const varName = stop === 'DEFAULT' ? '--colors-primary-DEFAULT' : `--colors-primary-${stop}`
const varName = stop === 'DEFAULT'
? '--colors-primary-DEFAULT'
: `--colors-primary-${stop}`
out = out.replace(
new RegExp(String.raw`rgb\(${rgb}(?!\d)`, 'g'),
`rgb(from var(${varName}, ${hex}) r g b`,
Expand Down
35 changes: 29 additions & 6 deletions docs/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,31 @@ export default defineAppConfig({
label: 'Adapters',
sections: ['adapters', 'frameworks'],
},
{ label: 'Add-ons', sections: ['add-ons'], link: 'section' as const },
{ label: 'Ecosystem', sections: ['ecosystem'], link: 'section' as const },
{ label: 'Reference', sections: ['references'], link: 'section' as const },
{ label: 'Errors', sections: ['errors'], link: 'section' as const },
{ label: 'Blog', sections: ['posts'], link: 'section' as const },
{
label: 'Add-ons',
sections: ['add-ons'],
link: 'section' as const,
},
{
label: 'Ecosystem',
sections: ['ecosystem'],
link: 'section' as const,
},
{
label: 'Reference',
sections: ['references'],
link: 'section' as const,
},
{
label: 'Errors',
sections: ['errors'],
link: 'section' as const,
},
{
label: 'Blog',
sections: ['posts'],
link: 'section' as const,
},
{
label: `v${devframePkg.version}`,
to: '/migrations',
Expand Down Expand Up @@ -126,7 +146,10 @@ export default defineAppConfig({
'/guide/security',
],
},
{ title: 'Agentic', items: ['/guide/agent-native'] },
{
title: 'Agentic',
items: ['/guide/agent-native'],
},
{
title: 'Compose a hub',
items: [
Expand Down
36 changes: 28 additions & 8 deletions docs/app/components/AssistantChat.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ const { messages, status, error, sendMessage, regenerate, stop } = useChat({
transport: new DefaultChatTransport({ api: '/api/assistant' }),
})

const plugins = [highlight()]
const plugins = [
highlight(),
]

// Suggestions grouped by category, shown before the first message.
const questions = computed(() => assistant?.faqQuestions ?? [])
Expand Down Expand Up @@ -58,7 +60,9 @@ async function copyConversation() {
const text = messages.value
.map((message) => {
const content = message.parts.filter(isTextUIPart).map(part => part.text).join('\n')
return `${message.role === 'user' ? 'User' : 'Assistant'}:\n${content}`
return `${message.role === 'user'
? 'User'
: 'Assistant'}:\n${content}`
})
.join('\n\n')
await navigator.clipboard.writeText(text)
Expand All @@ -76,12 +80,23 @@ function toolMeta(part: ToolUIPart | DynamicToolUIPart) {
const streaming = isToolStreaming(part)
const input = part.input as Record<string, string> | undefined
if (name === 'search_docs') {
return { icon: 'i-lucide-text-search', text: streaming ? 'Searching the docs' : 'Searched the docs', suffix: input?.query }
return {
icon: 'i-lucide-text-search',
text: streaming ? 'Searching the docs' : 'Searched the docs',
suffix: input?.query,
}
}
if (name === 'get_page') {
return { icon: 'i-lucide-book-open', text: streaming ? 'Reading a page' : 'Read a page', suffix: input?.path }
return {
icon: 'i-lucide-book-open',
text: streaming ? 'Reading a page' : 'Read a page',
suffix: input?.path,
}
}
return {
icon: 'i-lucide-wrench',
text: name.replace(/_/g, ' '),
}
return { icon: 'i-lucide-wrench', text: name.replace(/_/g, ' ') }
}

/** Live tool rows show while the answer streams; once done they collapse into one "Used N sources" row. */
Expand All @@ -100,8 +115,11 @@ function messageSources(message: UIMessage) {
for (const part of message.parts) {
if (isToolUIPart(part) && getToolName(part) === 'get_page') {
const path = (part.input as { path?: string } | undefined)?.path
if (path)
paths.add(path.startsWith('/') ? path : `/${path}`)
if (path) {
paths.add(path.startsWith('/')
? path
: `/${path}`)
}
}
}
return [...paths]
Expand All @@ -113,7 +131,9 @@ function messageToolCount(message: UIMessage) {

function sourcesLabel(message: UIMessage) {
const count = messageSources(message).length || messageToolCount(message)
return `Used ${count} source${count === 1 ? '' : 's'}`
return `Used ${count} source${count === 1
? ''
: 's'}`
}
</script>

Expand Down
4 changes: 3 additions & 1 deletion docs/app/components/BrandAssetCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ async function copySvg(): Promise<void> {

function downloadSvg(): void {
triggerDownload(
URL.createObjectURL(new Blob([withXmlns(props.svg)], { type: 'image/svg+xml;charset=utf-8' })),
URL.createObjectURL(new Blob([
withXmlns(props.svg),
], { type: 'image/svg+xml;charset=utf-8' })),
`${props.file}.svg`,
)
}
Expand Down
4 changes: 3 additions & 1 deletion docs/app/components/OgImage/OgImageDocs.satori.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ const { seo, docs } = useAppConfig()
const site = useSiteConfig()

const siteName = seo?.siteName || site.name || ''
const host = site.url ? site.url.replace(/^https?:\/\//, '').replace(/\/$/, '') : ''
const host = site.url
? site.url.replace(/^https?:\/\//, '').replace(/\/$/, '')
: ''
const accent = docs?.ogImage?.accent || '#fafafa'
</script>

Expand Down
4 changes: 3 additions & 1 deletion docs/app/components/global/DevToolsStack.vue
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,9 @@ const activePart = computed(() => activePartId.value ? parts[activePartId.value]
const activeGroup = computed(() => activePartId.value ? parts[activePartId.value].group : undefined)

function togglePart(id: PartId) {
selectedPart.value = selectedPart.value === id ? undefined : id
selectedPart.value = selectedPart.value === id
? undefined
: id
}

function partStateClass(id: PartId) {
Expand Down
49 changes: 38 additions & 11 deletions docs/app/components/global/DevframeEcosystemMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,9 @@ const nodes: EcosystemNode[] = [
source: 'devframe',
emphasis: true,
label: 'initDevframe()',
waypoints: [{ x: 70, y: 320 }],
waypoints: [
{ x: 70, y: 320 },
],
},
{ source: 'hub', emphasis: true, label: 'initHub()' },
],
Expand Down Expand Up @@ -309,7 +311,10 @@ const nodes: EcosystemNode[] = [
},
{
id: 'nuxt-devtools',
linksFrom: [{ source: 'vite-devtools', emphasis: true }, 'vue-devtools'],
linksFrom: [
{ source: 'vite-devtools', emphasis: true },
'vue-devtools',
],
label: 'Nuxt DevTools',
icon: 'i-logos-nuxt-icon',
href: 'https://devtools.nuxt.com/guide/getting-started',
Expand All @@ -325,14 +330,21 @@ const edges: EcosystemEdge[] = nodes.flatMap((node) => {
if (!node.linksFrom)
return []

const links = Array.isArray(node.linksFrom) ? node.linksFrom : [node.linksFrom]
const links = Array.isArray(node.linksFrom)
? node.linksFrom
: [node.linksFrom]
return links.map(link => ({
...(typeof link === 'string' ? { source: link } : link),
...(typeof link === 'string'
? { source: link }
: link),
target: node.id,
}))
})

const rawLayoutNodes: LayoutNode[] = nodes.map(({ position, ...node }) => ({ ...node, ...position }))
const rawLayoutNodes: LayoutNode[] = nodes.map(({ position, ...node }) => ({
...node,
...position,
}))
const bounds = layoutBounds(rawLayoutNodes)
const diagramWidth = bounds.width + diagramPadding.x * 2
const diagramHeight = bounds.height + diagramPadding.y * 2
Expand Down Expand Up @@ -384,7 +396,12 @@ function layoutBounds(layout: LayoutNode[]) {
const right = Math.max(...layout.map(node => node.x + node.width / 2))
const top = Math.min(...layout.map(node => node.y - node.height / 2))
const bottom = Math.max(...layout.map(node => node.y + node.height / 2))
return { left, top, width: right - left, height: bottom - top }
return {
left,
top,
width: right - left,
height: bottom - top,
}
}

function clipEdge(points: Point[], source: LayoutNode, target: LayoutNode): Point[] {
Expand All @@ -400,8 +417,12 @@ function clipEdge(points: Point[], source: LayoutNode, target: LayoutNode): Poin
function pointOnNodeBoundary(center: Point, toward: Point, node: LayoutNode): Point {
const dx = toward.x - center.x
const dy = toward.y - center.y
const scaleX = dx === 0 ? Number.POSITIVE_INFINITY : node.width / 2 / Math.abs(dx)
const scaleY = dy === 0 ? Number.POSITIVE_INFINITY : node.height / 2 / Math.abs(dy)
const scaleX = dx === 0
? Number.POSITIVE_INFINITY
: node.width / 2 / Math.abs(dx)
const scaleY = dy === 0
? Number.POSITIVE_INFINITY
: node.height / 2 / Math.abs(dy)
const scale = Math.min(scaleX, scaleY)
return { x: center.x + dx * scale, y: center.y + dy * scale }
}
Expand All @@ -425,9 +446,15 @@ function pointAlongPolyline(points: Point[], ratio: number, offset = 0): Point {
continue
}

const progress = segment.length === 0 ? 0 : distance / segment.length
const normalX = segment.length === 0 ? 0 : -segment.dy / segment.length
const normalY = segment.length === 0 ? 0 : segment.dx / segment.length
const progress = segment.length === 0
? 0
: distance / segment.length
const normalX = segment.length === 0
? 0
: -segment.dy / segment.length
const normalY = segment.length === 0
? 0
: segment.dx / segment.length
return {
x: segment.previous.x + segment.dx * progress + normalX * offset,
y: segment.previous.y + segment.dy * progress + normalY * offset,
Expand Down
Loading
Loading