mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-07-01 16:44:24 +00:00
* feat(@shadcn/react): add message-scroller package Add the @shadcn/react headless primitives package with MessageScroller scroll anchoring, streaming follow, history prepend, and jump-to-message behavior. Includes geometry helpers, use-render utility, and unit, browser, and perf tests. * feat(registry): add chat components Add MessageScroller, Message, Bubble, Attachment, and Marker registry sources for base and radix, style variants, preview-03 chat blocks, and registry index wiring. * feat(v4): integrate chat components into docs site Wire chat components into the v4 app with docs routes, example preview pages, message part renderers, markdown support, registry build updates, and supporting lib utilities. * feat(examples): add chat component demos Add base and radix example demos for MessageScroller, Message, Bubble, Attachment, Marker, scroll-fade, and shimmer. * docs: add chat component documentation Add component and utility docs for the chat component set, update docs navigation, and add the June 2026 chat components changelog entry. * chore: regenerate registry JSON output Rebuild public registry artifacts for all style variants with the new chat components. * chore(release): add @shadcn/react publish and CI pipeline Add Changesets prerelease workflow, browser test job, RELEASING docs, and monorepo wiring for publishing @shadcn/react independently from the shadcn CLI. * docs: fix display of component preview on mobile * fix * fix * docs: add message scroller docs * style: format * fix
421 lines
12 KiB
CSS
421 lines
12 KiB
CSS
@import "tailwindcss";
|
|
@import "tw-animate-css";
|
|
@import "shadcn/tailwind.css";
|
|
@import "./legacy-themes.css";
|
|
|
|
@source "../node_modules/streamdown/dist/*.js";
|
|
|
|
@custom-variant style-vega (&:where(.style-vega *));
|
|
@custom-variant style-nova (&:where(.style-nova *));
|
|
@custom-variant style-lyra (&:where(.style-lyra *));
|
|
@custom-variant style-maia (&:where(.style-maia *));
|
|
@custom-variant style-mira (&:where(.style-mira *));
|
|
@custom-variant style-luma (&:where(.style-luma *));
|
|
@custom-variant style-sera (&:where(.style-sera *));
|
|
@custom-variant style-rhea (&:where(.style-rhea *));
|
|
|
|
@custom-variant dark (&:is(.dark *));
|
|
@custom-variant fixed (&:is(.layout-fixed *));
|
|
|
|
@theme inline {
|
|
--breakpoint-3xl: 1600px;
|
|
--breakpoint-4xl: 2000px;
|
|
--font-sans: var(--font-sans);
|
|
--font-heading: var(--font-heading);
|
|
--font-mono: var(--font-mono);
|
|
--radius-sm: calc(var(--radius) * 0.6);
|
|
--radius-md: calc(var(--radius) * 0.8);
|
|
--radius-lg: var(--radius);
|
|
--radius-xl: calc(var(--radius) * 1.4);
|
|
--radius-2xl: calc(var(--radius) * 1.8);
|
|
--radius-3xl: calc(var(--radius) * 2.2);
|
|
--radius-4xl: calc(var(--radius) * 2.6);
|
|
--color-background: var(--background);
|
|
--color-foreground: var(--foreground);
|
|
--color-card: var(--card);
|
|
--color-card-foreground: var(--card-foreground);
|
|
--color-popover: var(--popover);
|
|
--color-popover-foreground: var(--popover-foreground);
|
|
--color-primary: var(--primary);
|
|
--color-primary-foreground: var(--primary-foreground);
|
|
--color-secondary: var(--secondary);
|
|
--color-secondary-foreground: var(--secondary-foreground);
|
|
--color-muted: var(--muted);
|
|
--color-muted-foreground: var(--muted-foreground);
|
|
--color-accent: var(--accent);
|
|
--color-accent-foreground: var(--accent-foreground);
|
|
--color-destructive: var(--destructive);
|
|
--color-destructive-foreground: var(--destructive-foreground);
|
|
--color-border: var(--border);
|
|
--color-input: var(--input);
|
|
--color-ring: var(--ring);
|
|
--color-chart-1: var(--chart-1);
|
|
--color-chart-2: var(--chart-2);
|
|
--color-chart-3: var(--chart-3);
|
|
--color-chart-4: var(--chart-4);
|
|
--color-chart-5: var(--chart-5);
|
|
--color-sidebar: var(--sidebar);
|
|
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
--color-sidebar-primary: var(--sidebar-primary);
|
|
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
--color-sidebar-accent: var(--sidebar-accent);
|
|
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
--color-sidebar-border: var(--sidebar-border);
|
|
--color-sidebar-ring: var(--sidebar-ring);
|
|
--color-surface: var(--surface);
|
|
--color-surface-foreground: var(--surface-foreground);
|
|
--color-code: var(--code);
|
|
--color-code-foreground: var(--code-foreground);
|
|
--color-code-highlight: var(--code-highlight);
|
|
--color-code-number: var(--code-number);
|
|
--color-selection: var(--selection);
|
|
--color-selection-foreground: var(--selection-foreground);
|
|
}
|
|
|
|
:root {
|
|
--radius: 0.625rem;
|
|
--background: oklch(1 0 0);
|
|
--foreground: oklch(0% 0 0);
|
|
--card: oklch(1 0 0);
|
|
--card-foreground: oklch(0% 0 0);
|
|
--popover: oklch(1 0 0);
|
|
--popover-foreground: oklch(0% 0 0);
|
|
--primary: oklch(0% 0 0);
|
|
--primary-foreground: oklch(0.985 0 0);
|
|
--secondary: oklch(0.97 0 0);
|
|
--secondary-foreground: oklch(0.205 0 0);
|
|
--muted: oklch(0.97 0 0);
|
|
--muted-foreground: oklch(0.556 0 0);
|
|
--accent: oklch(0.97 0 0);
|
|
--accent-foreground: oklch(0.205 0 0);
|
|
--destructive: oklch(0.577 0.245 27.325);
|
|
--destructive-foreground: oklch(0.97 0.01 17);
|
|
--border: oklch(0.922 0 0);
|
|
--input: oklch(0.922 0 0);
|
|
--ring: oklch(0.708 0 0);
|
|
--chart-1: var(--color-blue-300);
|
|
--chart-2: var(--color-blue-500);
|
|
--chart-3: var(--color-blue-600);
|
|
--chart-4: var(--color-blue-700);
|
|
--chart-5: var(--color-blue-800);
|
|
--sidebar: oklch(0.985 0 0);
|
|
--sidebar-foreground: oklch(0% 0 0);
|
|
--sidebar-primary: oklch(0.205 0 0);
|
|
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
--sidebar-accent: oklch(0.97 0 0);
|
|
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
--sidebar-border: oklch(0.922 0 0);
|
|
--sidebar-ring: oklch(0.708 0 0);
|
|
--surface: oklch(0.98 0 0);
|
|
--surface-foreground: var(--foreground);
|
|
--code: var(--surface);
|
|
--code-foreground: var(--surface-foreground);
|
|
--code-highlight: oklch(0.96 0 0);
|
|
--code-number: oklch(0.56 0 0);
|
|
--selection: oklch(0% 0 0);
|
|
--selection-foreground: oklch(1 0 0);
|
|
}
|
|
|
|
.dark {
|
|
--background: oklch(0.145 0 0);
|
|
--foreground: oklch(0.985 0 0);
|
|
--card: oklch(0.205 0 0);
|
|
--card-foreground: oklch(0.985 0 0);
|
|
--popover: oklch(0.205 0 0);
|
|
--popover-foreground: oklch(0.985 0 0);
|
|
--primary: oklch(0.922 0 0);
|
|
--primary-foreground: oklch(0.205 0 0);
|
|
--secondary: oklch(0.269 0 0);
|
|
--secondary-foreground: oklch(0.985 0 0);
|
|
--muted: oklch(0.269 0 0);
|
|
--muted-foreground: oklch(0.708 0 0);
|
|
--accent: oklch(0.371 0 0);
|
|
--accent-foreground: oklch(0.985 0 0);
|
|
--destructive: oklch(0.704 0.191 22.216);
|
|
--destructive-foreground: oklch(0.58 0.22 27);
|
|
--border: oklch(1 0 0 / 10%);
|
|
--input: oklch(1 0 0 / 15%);
|
|
--ring: oklch(0.556 0 0);
|
|
--chart-1: var(--color-blue-300);
|
|
--chart-2: var(--color-blue-500);
|
|
--chart-3: var(--color-blue-600);
|
|
--chart-4: var(--color-blue-700);
|
|
--chart-5: var(--color-blue-800);
|
|
--sidebar: oklch(0.205 0 0);
|
|
--sidebar-foreground: oklch(0.985 0 0);
|
|
--sidebar-primary: oklch(0.488 0.243 264.376);
|
|
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
--sidebar-accent: oklch(0.269 0 0);
|
|
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
--sidebar-border: oklch(1 0 0 / 10%);
|
|
--sidebar-ring: oklch(0.439 0 0);
|
|
--surface: oklch(0.2 0 0);
|
|
--surface-foreground: oklch(0.708 0 0);
|
|
--code: var(--surface);
|
|
--code-foreground: var(--surface-foreground);
|
|
--code-highlight: oklch(0.27 0 0);
|
|
--code-number: oklch(0.72 0 0);
|
|
--selection: oklch(0.922 0 0);
|
|
--selection-foreground: oklch(0.205 0 0);
|
|
}
|
|
|
|
@layer base {
|
|
* {
|
|
@apply border-border outline-ring/50;
|
|
}
|
|
::selection {
|
|
@apply bg-selection text-selection-foreground;
|
|
}
|
|
html {
|
|
@apply overscroll-y-none;
|
|
}
|
|
body {
|
|
font-synthesis-weight: none;
|
|
text-rendering: optimizeLegibility;
|
|
}
|
|
.cn-font-heading {
|
|
@apply font-heading;
|
|
}
|
|
|
|
[data-slot="layout"] {
|
|
@apply overscroll-none;
|
|
}
|
|
|
|
@supports (font: -apple-system-body) and (-webkit-appearance: none) {
|
|
[data-wrapper] {
|
|
@apply min-[1800px]:border-t;
|
|
}
|
|
}
|
|
|
|
a:active,
|
|
button:active {
|
|
@apply opacity-60 md:opacity-100;
|
|
}
|
|
|
|
[data-lang="ar"] {
|
|
font-family: var(--font-ar);
|
|
}
|
|
|
|
[data-lang="he"] {
|
|
font-family: var(--font-he);
|
|
}
|
|
}
|
|
|
|
@utility border-grid {
|
|
@apply border-border/50 dark:border-border;
|
|
}
|
|
|
|
@utility section-soft {
|
|
@apply bg-linear-to-b from-background to-surface/40 dark:bg-background 3xl:fixed:bg-none;
|
|
}
|
|
|
|
@utility theme-container {
|
|
@apply font-sans;
|
|
}
|
|
|
|
@utility container-wrapper {
|
|
@apply mx-auto w-full px-2 3xl:fixed:max-w-[calc(var(--breakpoint-2xl)+2rem)];
|
|
}
|
|
|
|
@utility container {
|
|
@apply mx-auto max-w-[1400px] px-4 3xl:max-w-screen-2xl lg:px-8;
|
|
}
|
|
|
|
@utility no-scrollbar {
|
|
-ms-overflow-style: none;
|
|
scrollbar-width: none;
|
|
|
|
&::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
@utility border-ghost {
|
|
@apply relative after:absolute after:inset-0 after:border after:border-border after:mix-blend-darken dark:after:mix-blend-lighten;
|
|
}
|
|
|
|
@utility step {
|
|
counter-increment: step;
|
|
|
|
&:before {
|
|
@apply mr-2 inline-flex size-6 items-center justify-center rounded-full border-background bg-muted text-center -indent-px font-mono text-sm font-medium md:absolute md:mt-[-4px] md:ml-[-50px] md:size-9 md:border-4;
|
|
content: counter(step);
|
|
}
|
|
}
|
|
|
|
@utility extend-touch-target {
|
|
@media (pointer: coarse) {
|
|
@apply relative touch-manipulation after:absolute after:-inset-2;
|
|
}
|
|
}
|
|
|
|
@layer components {
|
|
.steps {
|
|
&:first-child {
|
|
@apply !mt-0;
|
|
}
|
|
|
|
&:first-child > h3:first-child {
|
|
@apply !mt-0;
|
|
}
|
|
|
|
> h3 {
|
|
@apply !mt-8;
|
|
}
|
|
|
|
> h3 + p {
|
|
@apply !mt-2;
|
|
}
|
|
}
|
|
|
|
[data-rehype-pretty-code-figure] {
|
|
background-color: var(--color-code);
|
|
color: var(--color-code-foreground);
|
|
border-radius: var(--radius-xl);
|
|
border-width: 0px;
|
|
border-color: var(--border);
|
|
margin-top: calc(var(--spacing) * 6);
|
|
overflow: hidden;
|
|
font-size: var(--text-sm);
|
|
outline: none;
|
|
position: relative;
|
|
@apply -mx-1 md:-mx-1;
|
|
|
|
&:has([data-rehype-pretty-code-title]) [data-slot="copy-button"] {
|
|
top: calc(var(--spacing) * 1.5) !important;
|
|
}
|
|
}
|
|
|
|
[data-rehype-pretty-code-figure] code,
|
|
[data-rehype-pretty-code-figure] code span {
|
|
font-variant-ligatures: none;
|
|
font-feature-settings:
|
|
"liga" 0,
|
|
"calt" 0;
|
|
}
|
|
|
|
[data-rehype-pretty-code-title] {
|
|
border-bottom: color-mix(in oklab, var(--border) 30%, transparent);
|
|
border-bottom-width: 1px;
|
|
border-bottom-style: solid;
|
|
padding-block: calc(var(--spacing) * 2.5);
|
|
padding-inline: calc(var(--spacing) * 4);
|
|
font-size: var(--text-sm);
|
|
font-family: var(--font-mono);
|
|
color: var(--color-code-foreground);
|
|
}
|
|
|
|
[data-line-numbers] {
|
|
display: grid;
|
|
min-width: 100%;
|
|
white-space: pre;
|
|
border: 0;
|
|
background: transparent;
|
|
padding: 0;
|
|
counter-reset: line;
|
|
box-decoration-break: clone;
|
|
}
|
|
|
|
[data-line-numbers] [data-line]::before {
|
|
font-size: var(--text-sm);
|
|
counter-increment: line;
|
|
content: counter(line);
|
|
display: inline-block;
|
|
width: calc(var(--spacing) * 16);
|
|
padding-right: calc(var(--spacing) * 6);
|
|
text-align: right;
|
|
color: var(--color-code-number);
|
|
background-color: var(--color-code);
|
|
position: sticky;
|
|
left: 0;
|
|
}
|
|
|
|
[data-line-numbers] [data-highlighted-line][data-line]::before {
|
|
background-color: var(--color-code-highlight);
|
|
}
|
|
|
|
[data-line] {
|
|
padding-top: calc(var(--spacing) * 0.5);
|
|
padding-bottom: calc(var(--spacing) * 0.5);
|
|
min-height: calc(var(--spacing) * 1);
|
|
width: 100%;
|
|
display: inline-block;
|
|
}
|
|
|
|
/*
|
|
* ```text composition trees use box-drawing characters; per-line padding makes
|
|
* vertical connectors look broken. rehype-pretty-code sets `data-language` on
|
|
* `pre`/`code` (not `language-*` classes). It also sets `code { display: grid }`,
|
|
* which can add visible row separation — reset to a normal pre stack for text.
|
|
*/
|
|
[data-rehype-pretty-code-figure] pre[data-language="text"] code,
|
|
[data-rehype-pretty-code-figure] pre[data-language="plaintext"] code,
|
|
[data-slot="docs"] pre[data-language="text"] code,
|
|
[data-slot="docs"] pre[data-language="plaintext"] code {
|
|
display: block !important;
|
|
white-space: pre;
|
|
line-height: 0.95;
|
|
font-family:
|
|
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
|
"Courier New", monospace;
|
|
font-variant-ligatures: none;
|
|
}
|
|
|
|
[data-rehype-pretty-code-figure] pre[data-language="text"] [data-line],
|
|
[data-rehype-pretty-code-figure] pre[data-language="plaintext"] [data-line],
|
|
[data-rehype-pretty-code-figure] code[data-language="text"] [data-line],
|
|
[data-rehype-pretty-code-figure] code[data-language="plaintext"] [data-line],
|
|
[data-slot="docs"] pre[data-language="text"] [data-line],
|
|
[data-slot="docs"] pre[data-language="plaintext"] [data-line] {
|
|
padding-top: 0;
|
|
padding-bottom: 0;
|
|
min-height: unset;
|
|
line-height: 0.95;
|
|
display: block;
|
|
}
|
|
|
|
[data-line] span {
|
|
color: var(--shiki-light);
|
|
|
|
@variant dark {
|
|
color: var(--shiki-dark) !important;
|
|
}
|
|
}
|
|
|
|
[data-highlighted-line],
|
|
[data-highlighted-chars] {
|
|
position: relative;
|
|
background-color: var(--color-code-highlight);
|
|
}
|
|
|
|
[data-highlighted-line] {
|
|
&:after {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 2px;
|
|
height: 100%;
|
|
content: "";
|
|
background-color: color-mix(
|
|
in oklab,
|
|
var(--muted-foreground) 50%,
|
|
transparent
|
|
);
|
|
}
|
|
}
|
|
|
|
[data-highlighted-chars] {
|
|
border-radius: var(--radius-sm);
|
|
padding-inline: 0.3rem;
|
|
padding-block: 0.1rem;
|
|
font-family: var(--font-mono);
|
|
font-size: 0.8rem;
|
|
}
|
|
}
|
|
|
|
@layer components {
|
|
.dialog-ring {
|
|
@apply rounded-xl border-none bg-clip-padding shadow-2xl ring-4 ring-neutral-200/80 dark:bg-neutral-900 dark:ring-neutral-800;
|
|
}
|
|
}
|