Package Info
Package name, version change and dependency list.
Breaking: new JSX transform, ref as prop.
Adds versioned transaction helpers.
Fixes an edge case in unions.
Quote and swap API client.
Breaking: new JSX transform, ref as prop.
Adds versioned transaction helpers.
Fixes an edge case in unions.
Quote and swap API client.
Breaking: new JSX transform, ref as prop.
Adds versioned transaction helpers.
Fixes an edge case in unions.
Quote and swap API client.
import { PackageInfo, PackageInfoChangeType, PackageInfoContent, PackageInfoDependencies, PackageInfoDependency, PackageInfoDescription, PackageInfoHeader, PackageInfoName, PackageInfoVersion,} from "@/components/ai/package-info";
const changes = [ { name: "react", from: "18.3.1", to: "19.0.0", type: "major", note: "Breaking: new JSX transform, ref as prop.", }, { name: "@solana/web3.js", from: "1.95.2", to: "1.98.0", type: "minor", note: "Adds versioned transaction helpers.", }, { name: "zod", from: "3.23.8", to: "3.23.9", type: "patch", note: "Fixes an edge case in unions.", }, { name: "@jup-ag/api", from: undefined, to: "6.0.30", type: "added", note: "Quote and swap API client.", },] as const;
export default function Demo() { return ( <div className="flex w-full max-w-md flex-col gap-2.5"> {changes.map((c) => ( <PackageInfo changeType={c.type} currentVersion={c.from} key={c.name} name={c.name} newVersion={c.to} > <PackageInfoHeader> <PackageInfoName /> <PackageInfoChangeType /> <PackageInfoVersion /> </PackageInfoHeader> <PackageInfoDescription>{c.note}</PackageInfoDescription> </PackageInfo> ))} <PackageInfo changeType="minor" currentVersion="1.2.0" name="@edmi-ui/tokens" newVersion="1.3.0" > <PackageInfoHeader> <PackageInfoName /> <PackageInfoChangeType /> <PackageInfoVersion /> </PackageInfoHeader> <PackageInfoContent> <PackageInfoDependencies> <PackageInfoDependency name="tailwindcss" version="^4.1.0" /> <PackageInfoDependency name="shiki" version="^4.5.0" /> </PackageInfoDependencies> </PackageInfoContent> </PackageInfo> </div> );}<script setup lang="ts">import { PackageInfo, PackageInfoChangeType, PackageInfoContent, PackageInfoDependencies, PackageInfoDependency, PackageInfoDescription, PackageInfoHeader, PackageInfoName, PackageInfoVersion,} from "@/components/ai/package-info";
const changes = [ { name: "react", from: "18.3.1", to: "19.0.0", type: "major", note: "Breaking: new JSX transform, ref as prop." }, { name: "@solana/web3.js", from: "1.95.2", to: "1.98.0", type: "minor", note: "Adds versioned transaction helpers." }, { name: "zod", from: "3.23.8", to: "3.23.9", type: "patch", note: "Fixes an edge case in unions." }, { name: "@jup-ag/api", from: undefined, to: "6.0.30", type: "added", note: "Quote and swap API client." },] as const;</script>
<template> <div class="flex w-full max-w-md flex-col gap-2.5"> <PackageInfo v-for="c in changes" :key="c.name" :change-type="c.type" :current-version="c.from" :name="c.name" :new-version="c.to" > <PackageInfoHeader> <PackageInfoName /> <PackageInfoChangeType /> <PackageInfoVersion /> </PackageInfoHeader> <PackageInfoDescription>{{ c.note }}</PackageInfoDescription> </PackageInfo> <PackageInfo change-type="minor" current-version="1.2.0" name="@edmi-ui/tokens" new-version="1.3.0"> <PackageInfoHeader> <PackageInfoName /> <PackageInfoChangeType /> <PackageInfoVersion /> </PackageInfoHeader> <PackageInfoContent> <PackageInfoDependencies> <PackageInfoDependency name="tailwindcss" version="^4.1.0" /> <PackageInfoDependency name="shiki" version="^4.5.0" /> </PackageInfoDependencies> </PackageInfoContent> </PackageInfo> </div></template><script lang="ts"> import { PackageInfo, PackageInfoChangeType, PackageInfoContent, PackageInfoDependencies, PackageInfoDependency, PackageInfoDescription, PackageInfoHeader, PackageInfoName, PackageInfoVersion, } from "$lib/components/ai/package-info";
const changes = [ { name: "react", from: "18.3.1", to: "19.0.0", type: "major", note: "Breaking: new JSX transform, ref as prop." }, { name: "@solana/web3.js", from: "1.95.2", to: "1.98.0", type: "minor", note: "Adds versioned transaction helpers." }, { name: "zod", from: "3.23.8", to: "3.23.9", type: "patch", note: "Fixes an edge case in unions." }, { name: "@jup-ag/api", from: undefined, to: "6.0.30", type: "added", note: "Quote and swap API client." }, ] as const;</script>
<div class="flex w-full max-w-md flex-col gap-2.5"> {#each changes as c (c.name)} <PackageInfo changeType={c.type} currentVersion={c.from} name={c.name} newVersion={c.to}> <PackageInfoHeader> <PackageInfoName /> <PackageInfoChangeType /> <PackageInfoVersion /> </PackageInfoHeader> <PackageInfoDescription>{c.note}</PackageInfoDescription> </PackageInfo> {/each} <PackageInfo changeType="minor" currentVersion="1.2.0" name="@edmi-ui/tokens" newVersion="1.3.0"> <PackageInfoHeader> <PackageInfoName /> <PackageInfoChangeType /> <PackageInfoVersion /> </PackageInfoHeader> <PackageInfoContent> <PackageInfoDependencies> <PackageInfoDependency name="tailwindcss" version="^4.1.0" /> <PackageInfoDependency name="shiki" version="^4.5.0" /> </PackageInfoDependencies> </PackageInfoContent> </PackageInfo></div>Built on badge.
Installation
Section titled “Installation”npx shadcn@latest add @edmi-ui/ai-package-infopnpm dlx shadcn@latest add @edmi-ui/ai-package-infoyarn dlx shadcn@latest add @edmi-ui/ai-package-infobunx shadcn@latest add @edmi-ui/ai-package-infoPick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.
Add the Edmi components this one builds on:
badge.Copy the code from Component source into your project and update the import paths to match your aliases.
npx shadcn-vue@latest add @edmi-ui/ai-package-infopnpm dlx shadcn-vue@latest add @edmi-ui/ai-package-infoyarn dlx shadcn-vue@latest add @edmi-ui/ai-package-infobunx shadcn-vue@latest add @edmi-ui/ai-package-infoPick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.
Install the dependencies:
Terminal window npm install @lucide/vueTerminal window pnpm add @lucide/vueTerminal window yarn add @lucide/vueTerminal window bun add @lucide/vueAdd the Edmi components this one builds on:
badge.Copy the code from Component source into your project and update the import paths to match your aliases.
npx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/ai-package-info.jsonpnpm dlx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/ai-package-info.jsonyarn dlx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/ai-package-info.jsonbunx --bun shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/ai-package-info.jsonPick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.
Add the Edmi components this one builds on:
badge.Copy the code from Component source into your project and update the import paths to match your aliases.
import { PackageInfo, PackageInfoChangeType, PackageInfoContent, PackageInfoDependencies, PackageInfoDependency, PackageInfoHeader, PackageInfoName, PackageInfoVersion,} from "@/components/ai/package-info";
<div className="flex w-full max-w-md flex-col gap-2.5"> <PackageInfo changeType="minor" currentVersion="1.2.0" name="@edmi-ui/tokens" newVersion="1.3.0" > <PackageInfoHeader> <PackageInfoName /> <PackageInfoChangeType /> <PackageInfoVersion /> </PackageInfoHeader> <PackageInfoContent> <PackageInfoDependencies> <PackageInfoDependency name="tailwindcss" version="^4.1.0" /> <PackageInfoDependency name="shiki" version="^4.5.0" /> </PackageInfoDependencies> </PackageInfoContent> </PackageInfo></div><script setup lang="ts">import { PackageInfo, PackageInfoChangeType, PackageInfoDescription, PackageInfoHeader, PackageInfoName, PackageInfoVersion,} from "@/components/ai/package-info";</script>
<template> <div class="flex w-full max-w-md flex-col gap-2.5"> <PackageInfo :key="c.name" :change-type="c.type" :current-version="c.from" :name="c.name" :new-version="c.to" > <PackageInfoHeader> <PackageInfoName /> <PackageInfoChangeType /> <PackageInfoVersion /> </PackageInfoHeader> <PackageInfoDescription>{{ c.note }}</PackageInfoDescription> </PackageInfo> <!-- … --> </div></template><script lang="ts"> import { PackageInfo, PackageInfoChangeType, PackageInfoContent, PackageInfoDependencies, PackageInfoDependency, PackageInfoDescription, PackageInfoHeader, PackageInfoName, PackageInfoVersion, } from "$lib/components/ai/package-info";</script>
<div class="flex w-full max-w-md flex-col gap-2.5"> {#each changes as c (c.name)} <PackageInfo changeType={c.type} currentVersion={c.from} name={c.name} newVersion={c.to}> <PackageInfoHeader> <PackageInfoName /> <PackageInfoChangeType /> <PackageInfoVersion /> </PackageInfoHeader> <PackageInfoDescription>{c.note}</PackageInfoDescription> </PackageInfo> {/each} <PackageInfo changeType="minor" currentVersion="1.2.0" name="@edmi-ui/tokens" newVersion="1.3.0"> <PackageInfoHeader> <PackageInfoName /> <PackageInfoChangeType /> <PackageInfoVersion /> </PackageInfoHeader> <PackageInfoContent> <PackageInfoDependencies> <PackageInfoDependency name="tailwindcss" version="^4.1.0" /> <PackageInfoDependency name="shiki" version="^4.5.0" /> </PackageInfoDependencies> </PackageInfoContent> </PackageInfo></div>Component source
Section titled “Component source”"use client";
import { cn } from "cn";import type { HTMLAttributes } from "react";import { createContext, useContext, useMemo } from "react";import { CubeIcon } from "@phosphor-icons/react";import { Badge } from "@/registry/edmi/ui/badge";
type ChangeType = "major" | "minor" | "patch" | "added" | "removed";
interface PackageInfoContextType { name: string; currentVersion?: string; newVersion?: string; changeType?: ChangeType;}
const PackageInfoContext = createContext<PackageInfoContextType>({ name: "",});
export type PackageInfoHeaderProps = HTMLAttributes<HTMLDivElement>;
export const PackageInfoHeader = ({ className, children, ...props}: PackageInfoHeaderProps) => ( <div data-slot="ai-package-info-header" className={cn("flex items-center gap-2", className)} {...props} > {children} </div>);
export type PackageInfoNameProps = HTMLAttributes<HTMLDivElement>;
export const PackageInfoName = ({ className, children, ...props}: PackageInfoNameProps) => { const { name } = useContext(PackageInfoContext);
return ( <div className={cn("flex items-center gap-2", className)} {...props}> <CubeIcon className="size-3.5 text-muted-foreground" /> <span className="font-mono text-[13.5px] font-semibold"> {children ?? name} </span> </div> );};
// major = destructive, minor = warning, patch = success, added = info (soft fill, tinted border).const changeTypeVariants = { added: "info", major: "destructive", minor: "warning", patch: "success", removed: "secondary",} as const;
export type PackageInfoChangeTypeProps = HTMLAttributes<HTMLSpanElement>;
export const PackageInfoChangeType = ({ className, children, ...props}: PackageInfoChangeTypeProps) => { const { changeType } = useContext(PackageInfoContext);
if (!changeType) { return null; }
return ( <Badge className={cn("h-5", className)} variant={changeTypeVariants[changeType]} {...props} > {children ?? changeType} </Badge> );};
export type PackageInfoVersionProps = HTMLAttributes<HTMLDivElement>;
/** `18.3.1 → 19.0.0`; with only a new version (added) it reads `→ 6.0.30`. Pushed right inside the header. */export const PackageInfoVersion = ({ className, children, ...props}: PackageInfoVersionProps) => { const { currentVersion, newVersion } = useContext(PackageInfoContext);
if (!(currentVersion || newVersion)) { return null; }
return ( <div className={cn( "ml-auto font-mono text-[12.5px] text-foreground", className, )} {...props} > {children ?? [currentVersion, newVersion && "→", newVersion] .filter(Boolean) .join(" ")} </div> );};
export type PackageInfoProps = HTMLAttributes<HTMLDivElement> & { name: string; currentVersion?: string; newVersion?: string; changeType?: ChangeType;};
export const PackageInfo = ({ name, currentVersion, newVersion, changeType, className, children, ...props}: PackageInfoProps) => { const contextValue = useMemo( () => ({ changeType, currentVersion, name, newVersion }), [changeType, currentVersion, name, newVersion], );
return ( <PackageInfoContext.Provider value={contextValue}> <div data-slot="ai-package-info" className={cn( "rounded-xl border border-border bg-card px-4 py-3.5 text-card-foreground", className, )} {...props} > {children ?? ( <PackageInfoHeader> <PackageInfoName /> {changeType && <PackageInfoChangeType />} <PackageInfoVersion /> </PackageInfoHeader> )} </div> </PackageInfoContext.Provider> );};
export type PackageInfoDescriptionProps = HTMLAttributes<HTMLParagraphElement>;
export const PackageInfoDescription = ({ className, children, ...props}: PackageInfoDescriptionProps) => ( <p className={cn("mt-1.5 text-xs text-muted-foreground", className)} {...props} > {children} </p>);
export type PackageInfoContentProps = HTMLAttributes<HTMLDivElement>;
export const PackageInfoContent = ({ className, children, ...props}: PackageInfoContentProps) => ( <div className={cn("mt-3 border-t border-border-2 pt-3", className)} {...props} > {children} </div>);
export type PackageInfoDependenciesProps = HTMLAttributes<HTMLDivElement>;
export const PackageInfoDependencies = ({ className, children, ...props}: PackageInfoDependenciesProps) => ( <div className={cn("flex flex-col gap-2", className)} {...props}> <span className="font-mono text-[11px] font-medium tracking-[0.8px] text-muted-foreground uppercase"> Dependencies </span> <div className="flex flex-col gap-1">{children}</div> </div>);
export type PackageInfoDependencyProps = HTMLAttributes<HTMLDivElement> & { name: string; version?: string;};
export const PackageInfoDependency = ({ name, version, className, children, ...props}: PackageInfoDependencyProps) => ( <div className={cn("flex items-center justify-between text-sm", className)} {...props} > {children ?? ( <> <span className="font-mono text-[12.5px] text-muted-foreground"> {name} </span> {version && <span className="font-mono text-xs">{version}</span>} </> )} </div>);<script setup lang="ts">import type { HTMLAttributes } from "vue"import type { PackageChangeType } from "./context"import { computed, provide, useSlots } from "vue"import { cn } from "@/registry/edmi/lib/utils"import { PackageInfoKey } from "./context"import PackageInfoChangeType from "./PackageInfoChangeType.vue"import PackageInfoHeader from "./PackageInfoHeader.vue"import PackageInfoName from "./PackageInfoName.vue"import PackageInfoVersion from "./PackageInfoVersion.vue"
const props = defineProps<{ name: string currentVersion?: string newVersion?: string changeType?: PackageChangeType class?: HTMLAttributes["class"]}>()
provide(PackageInfoKey, { name: computed(() => props.name), currentVersion: computed(() => props.currentVersion), newVersion: computed(() => props.newVersion), changeType: computed(() => props.changeType),})
const slots = useSlots()</script>
<template> <div data-slot="ai-package-info" :class="cn('rounded-xl border border-border bg-card px-4 py-3.5 text-card-foreground', props.class)" > <slot v-if="slots.default" /> <PackageInfoHeader v-else> <PackageInfoName /> <PackageInfoChangeType v-if="props.changeType" /> <PackageInfoVersion /> </PackageInfoHeader> </div></template><script setup lang="ts">import type { HTMLAttributes } from "vue"import { computed } from "vue"import { cn } from "@/registry/edmi/lib/utils"import { Badge } from "@/registry/edmi/ui/badge"import { usePackageInfoContext } from "./context"
const props = defineProps<{ class?: HTMLAttributes["class"] }>()
const { changeType } = usePackageInfoContext()
// major = destructive, minor = warning, patch = success, added = info (soft fill, tinted border).const variants = { added: "info", major: "destructive", minor: "warning", patch: "success", removed: "secondary",} as const
const variant = computed(() => (changeType.value ? variants[changeType.value] : undefined))</script>
<template> <Badge v-if="changeType" :variant="variant" :class="cn('h-5', props.class)"> <slot>{{ changeType }}</slot> </Badge></template><script setup lang="ts">import type { HTMLAttributes } from "vue"import { cn } from "@/registry/edmi/lib/utils"
const props = defineProps<{ class?: HTMLAttributes["class"] }>()</script>
<template> <div :class="cn('mt-3 border-t border-border-2 pt-3', props.class)"> <slot /> </div></template><script setup lang="ts">import type { HTMLAttributes } from "vue"import { cn } from "@/registry/edmi/lib/utils"
const props = defineProps<{ class?: HTMLAttributes["class"] }>()</script>
<template> <div :class="cn('flex flex-col gap-2', props.class)"> <span class="font-mono text-[11px] font-medium tracking-[0.8px] text-muted-foreground uppercase">Dependencies</span> <div class="flex flex-col gap-1"> <slot /> </div> </div></template><script setup lang="ts">import type { HTMLAttributes } from "vue"import { cn } from "@/registry/edmi/lib/utils"
const props = defineProps<{ name: string version?: string class?: HTMLAttributes["class"]}>()</script>
<template> <div :class="cn('flex items-center justify-between text-sm', props.class)"> <slot> <span class="font-mono text-[12.5px] text-muted-foreground">{{ props.name }}</span> <span v-if="props.version" class="font-mono text-xs">{{ props.version }}</span> </slot> </div></template><script setup lang="ts">import type { HTMLAttributes } from "vue"import { cn } from "@/registry/edmi/lib/utils"
const props = defineProps<{ class?: HTMLAttributes["class"] }>()</script>
<template> <p :class="cn('mt-1.5 text-xs text-muted-foreground', props.class)"> <slot /> </p></template><script setup lang="ts">import type { HTMLAttributes } from "vue"import { cn } from "@/registry/edmi/lib/utils"
const props = defineProps<{ class?: HTMLAttributes["class"] }>()</script>
<template> <div data-slot="ai-package-info-header" :class="cn('flex items-center gap-2', props.class)"> <slot /> </div></template><script setup lang="ts">import type { HTMLAttributes } from "vue"import { ContainerIcon } from "@lucide/vue"import { cn } from "@/registry/edmi/lib/utils"import { usePackageInfoContext } from "./context"
const props = defineProps<{ class?: HTMLAttributes["class"] }>()
const { name } = usePackageInfoContext()</script>
<template> <div :class="cn('flex items-center gap-2', props.class)"> <ContainerIcon class="size-3.5 text-muted-foreground" /> <span class="font-mono text-[13.5px] font-semibold"> <slot>{{ name }}</slot> </span> </div></template><script setup lang="ts">import type { HTMLAttributes } from "vue"import { computed } from "vue"import { cn } from "@/registry/edmi/lib/utils"import { usePackageInfoContext } from "./context"
const props = defineProps<{ class?: HTMLAttributes["class"] }>()
const { currentVersion, newVersion } = usePackageInfoContext()
// `18.3.1 → 19.0.0`; with only a new version (added) it reads `→ 6.0.30`. Pushed right inside the header.const text = computed(() => [currentVersion.value, newVersion.value && "→", newVersion.value].filter(Boolean).join(" "),)</script>
<template> <div v-if="currentVersion || newVersion" :class="cn('ml-auto font-mono text-[12.5px] text-foreground', props.class)" > <slot>{{ text }}</slot> </div></template>import type { ComputedRef, InjectionKey } from "vue";import { inject } from "vue";
export type PackageChangeType = | "major" | "minor" | "patch" | "added" | "removed";
export interface PackageInfoContext { name: ComputedRef<string>; currentVersion: ComputedRef<string | undefined>; newVersion: ComputedRef<string | undefined>; changeType: ComputedRef<PackageChangeType | undefined>;}
export const PackageInfoKey: InjectionKey<PackageInfoContext> = Symbol("PackageInfo");
export function usePackageInfoContext() { const ctx = inject(PackageInfoKey); if (!ctx) throw new Error("PackageInfo parts must be used within <PackageInfo />"); return ctx;}export * from "./context";export { default as PackageInfo } from "./PackageInfo.vue";export { default as PackageInfoChangeType } from "./PackageInfoChangeType.vue";export { default as PackageInfoContent } from "./PackageInfoContent.vue";export { default as PackageInfoDependencies } from "./PackageInfoDependencies.vue";export { default as PackageInfoDependency } from "./PackageInfoDependency.vue";export { default as PackageInfoDescription } from "./PackageInfoDescription.vue";export { default as PackageInfoHeader } from "./PackageInfoHeader.vue";export { default as PackageInfoName } from "./PackageInfoName.vue";export { default as PackageInfoVersion } from "./PackageInfoVersion.vue";<script lang="ts"> import { Badge } from "$lib/registry/ui/badge/index.js"; import { cn } from "$lib/utils.js"; import type { ComponentProps } from "svelte"; import { usePackageInfoContext } from "./use-package-info.svelte.js";
let { class: className, children, ...restProps }: ComponentProps<typeof Badge> = $props();
const info = usePackageInfoContext();
// major = destructive, minor = warning, patch = success, added = info (soft fill, tinted border). const variants = { added: "info", major: "destructive", minor: "warning", patch: "success", removed: "secondary", } as const;</script>
{#if info.changeType} <Badge variant={variants[info.changeType]} class={cn("h-5", className)} {...restProps}> {#if children}{@render children()}{:else}{info.changeType}{/if} </Badge>{/if}<script lang="ts"> import { cn } from "$lib/utils.js"; import type { Snippet } from "svelte"; import type { HTMLAttributes } from "svelte/elements";
let { class: className, children, ...restProps }: HTMLAttributes<HTMLDivElement> & { children?: Snippet } = $props();</script>
<div class={cn("mt-3 border-t border-border-2 pt-3", className)} {...restProps}> {@render children?.()}</div><script lang="ts"> import { cn } from "$lib/utils.js"; import type { Snippet } from "svelte"; import type { HTMLAttributes } from "svelte/elements";
let { class: className, children, ...restProps }: HTMLAttributes<HTMLDivElement> & { children?: Snippet } = $props();</script>
<div class={cn("flex flex-col gap-2", className)} {...restProps}> <span class="font-mono text-[11px] font-medium tracking-[0.8px] text-muted-foreground uppercase" >Dependencies</span > <div class="flex flex-col gap-1"> {@render children?.()} </div></div><script lang="ts"> import { cn } from "$lib/utils.js"; import type { Snippet } from "svelte"; import type { HTMLAttributes } from "svelte/elements";
let { name, version, class: className, children, ...restProps }: HTMLAttributes<HTMLDivElement> & { name: string; version?: string; children?: Snippet } = $props();</script>
<div class={cn("flex items-center justify-between text-sm", className)} {...restProps}> {#if children} {@render children()} {:else} <span class="font-mono text-[12.5px] text-muted-foreground">{name}</span> {#if version}<span class="font-mono text-xs">{version}</span>{/if} {/if}</div><script lang="ts"> import { cn } from "$lib/utils.js"; import type { Snippet } from "svelte"; import type { HTMLAttributes } from "svelte/elements";
let { class: className, children, ...restProps }: HTMLAttributes<HTMLParagraphElement> & { children?: Snippet } = $props();</script>
<p class={cn("mt-1.5 text-xs text-muted-foreground", className)} {...restProps}> {@render children?.()}</p><script lang="ts"> import { cn } from "$lib/utils.js"; import type { Snippet } from "svelte"; import type { HTMLAttributes } from "svelte/elements";
let { class: className, children, ...restProps }: HTMLAttributes<HTMLDivElement> & { children?: Snippet } = $props();</script>
<div data-slot="ai-package-info-header" class={cn("flex items-center gap-2", className)} {...restProps}> {@render children?.()}</div><script lang="ts"> import CubeIcon from "phosphor-svelte/lib/Cube"; import { cn } from "$lib/utils.js"; import type { Snippet } from "svelte"; import type { HTMLAttributes } from "svelte/elements"; import { usePackageInfoContext } from "./use-package-info.svelte.js";
let { class: className, children, ...restProps }: HTMLAttributes<HTMLDivElement> & { children?: Snippet } = $props();
const info = usePackageInfoContext();</script>
<div class={cn("flex items-center gap-2", className)} {...restProps}> <CubeIcon class="size-3.5 text-muted-foreground" /> <span class="font-mono text-[13.5px] font-semibold"> {#if children}{@render children()}{:else}{info.name}{/if} </span></div><script lang="ts"> import { cn } from "$lib/utils.js"; import type { Snippet } from "svelte"; import type { HTMLAttributes } from "svelte/elements"; import { usePackageInfoContext } from "./use-package-info.svelte.js";
let { class: className, children, ...restProps }: HTMLAttributes<HTMLDivElement> & { children?: Snippet } = $props();
const info = usePackageInfoContext();
// `18.3.1 → 19.0.0`; with only a new version (added) it reads `→ 6.0.30`. Pushed right inside the header. const text = $derived( [info.currentVersion, info.newVersion && "→", info.newVersion].filter(Boolean).join(" ") );</script>
{#if info.currentVersion || info.newVersion} <div class={cn("ml-auto font-mono text-[12.5px] text-foreground", className)} {...restProps}> {#if children}{@render children()}{:else}{text}{/if} </div>{/if}<script lang="ts"> import { cn } from "$lib/utils.js"; import type { Snippet } from "svelte"; import type { HTMLAttributes } from "svelte/elements"; import PackageInfoChangeType from "./package-info-change-type.svelte"; import PackageInfoHeader from "./package-info-header.svelte"; import PackageInfoName from "./package-info-name.svelte"; import PackageInfoVersion from "./package-info-version.svelte"; import { type PackageChangeType, setPackageInfoContext } from "./use-package-info.svelte.js";
let { name, currentVersion, newVersion, changeType, class: className, children, ...restProps }: HTMLAttributes<HTMLDivElement> & { name: string; currentVersion?: string; newVersion?: string; changeType?: PackageChangeType; children?: Snippet; } = $props();
setPackageInfoContext({ get name() { return name; }, get currentVersion() { return currentVersion; }, get newVersion() { return newVersion; }, get changeType() { return changeType; }, });</script>
<div data-slot="ai-package-info" class={cn("rounded-xl border border-border bg-card px-4 py-3.5 text-card-foreground", className)} {...restProps}> {#if children} {@render children()} {:else} <PackageInfoHeader> <PackageInfoName /> {#if changeType}<PackageInfoChangeType />{/if} <PackageInfoVersion /> </PackageInfoHeader> {/if}</div>import { getContext, setContext } from "svelte";
export type PackageChangeType = | "major" | "minor" | "patch" | "added" | "removed";
/** Getter object keeps the context reactive. */export interface PackageInfoContextValue { readonly name: string; readonly currentVersion: string | undefined; readonly newVersion: string | undefined; readonly changeType: PackageChangeType | undefined;}
const KEY = Symbol("ai-package-info");
export function setPackageInfoContext(value: PackageInfoContextValue) { return setContext(KEY, value);}
export function usePackageInfoContext(): PackageInfoContextValue { const ctx = getContext<PackageInfoContextValue | undefined>(KEY); if (!ctx) { throw new Error("PackageInfo parts must be used within <PackageInfo>"); } return ctx;}import Root from "./package-info.svelte";import ChangeType from "./package-info-change-type.svelte";import Content from "./package-info-content.svelte";import Dependencies from "./package-info-dependencies.svelte";import Dependency from "./package-info-dependency.svelte";import Description from "./package-info-description.svelte";import Header from "./package-info-header.svelte";import Name from "./package-info-name.svelte";import Version from "./package-info-version.svelte";
export { type PackageChangeType, usePackageInfoContext,} from "./use-package-info.svelte.js";
export { ChangeType as PackageInfoChangeType, Content as PackageInfoContent, Dependencies as PackageInfoDependencies, Dependency as PackageInfoDependency, Description as PackageInfoDescription, Header as PackageInfoHeader, Name as PackageInfoName, Root as PackageInfo, Version as PackageInfoVersion,};| Part | Prop | Type | Default |
|---|---|---|---|
| PackageInfo | name, currentVersion, newVersion |
string |
|
| PackageInfo | changeType |
major | minor | patch | added | removed |
|
| PackageInfoDependency | name, version |
string |
✦ Edmi additions
Section titled “✦ Edmi additions”- Change types map to badge variants: major
destructive, minorwarning, patchsuccess, addedinfo, removedsecondary. - With only
newVersion(added) the version reads→ 6.0.30.