Skip to content

Commit 5bbb94e

Browse files
authored
feat: add ShimmerText component (#3938)
* feat: add ShimmerText component with simplified API - Create ShimmerText component that wraps any text with shimmer effect - Component inherits text size from parent (no size prop needed) - Rename all CSS from glimmer to shimmer - Add simple Storybook stories demonstrating usage * feat(ui): add custom color support to ShimmerText component Add foregroundColor and highlightColor props to allow custom shimmer colors, with fallback to VSCode theme colors. Updated Storybook stories to demonstrate usage via props and CSS variables.
1 parent 00cd5a6 commit 5bbb94e

File tree

3 files changed

+163
-0
lines changed

3 files changed

+163
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// kilocode_change - new file
2+
import React from "react"
3+
import type { Meta, StoryObj } from "@storybook/react-vite"
4+
import { ShimmerText } from "../../../webview-ui/src/components/ui/shimmer-text"
5+
6+
const meta = {
7+
title: "Components/ShimmerText",
8+
component: ShimmerText,
9+
tags: ["autodocs"],
10+
argTypes: {
11+
children: {
12+
control: "text",
13+
description: "The text content to display with shimmer effect",
14+
},
15+
asChild: {
16+
control: "boolean",
17+
description: "Render as child element instead of wrapper span",
18+
},
19+
foregroundColor: {
20+
control: "color",
21+
description: "Custom foreground/base color for the shimmer",
22+
},
23+
highlightColor: {
24+
control: "color",
25+
description: "Custom highlight color for the shimmer effect",
26+
},
27+
},
28+
args: {
29+
children: "API Request...",
30+
},
31+
decorators: [
32+
(Story) => (
33+
<div className="w-full max-w-4xl mx-auto bg-[var(--vscode-editor-background)] p-8">
34+
<Story />
35+
</div>
36+
),
37+
],
38+
} satisfies Meta<typeof ShimmerText>
39+
40+
export default meta
41+
type Story = StoryObj<typeof meta>
42+
43+
export const Default: Story = {
44+
args: {
45+
children: "API Request...",
46+
},
47+
}
48+
49+
export const Examples: Story = {
50+
render: () => (
51+
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
52+
<div style={{ fontSize: "12px" }}>
53+
<ShimmerText>Small text with shimmer</ShimmerText>
54+
</div>
55+
<div style={{ fontSize: "16px" }}>
56+
<ShimmerText>Normal text with shimmer</ShimmerText>
57+
</div>
58+
<div style={{ fontSize: "24px" }}>
59+
<ShimmerText>Large text with shimmer</ShimmerText>
60+
</div>
61+
<ShimmerText>
62+
<span className="codicon codicon-loading" style={{ marginRight: "8px" }} />
63+
Loading with icon
64+
</ShimmerText>
65+
<ShimmerText>
66+
<span className="codicon codicon-sparkle" style={{ fontSize: "64px" }} />
67+
</ShimmerText>
68+
69+
<div style={{ marginTop: "8px" }}>
70+
<strong style={{ color: "var(--vscode-foreground)" }}>Custom colors via props:</strong>
71+
</div>
72+
<ShimmerText foregroundColor="#3b82f6" style={{ fontSize: "18px" }}>
73+
Blue (foreground only, highlight auto-generated)
74+
</ShimmerText>
75+
<ShimmerText foregroundColor="#6366f1" highlightColor="#c4b5fd" style={{ fontSize: "18px" }}>
76+
Purple with custom highlight
77+
</ShimmerText>
78+
79+
<div style={{ marginTop: "8px" }}>
80+
<strong style={{ color: "var(--vscode-foreground)" }}>CSS variables from parent:</strong>
81+
</div>
82+
<div
83+
style={
84+
{
85+
"--shimmer-foreground": "#059669",
86+
"--shimmer-highlight-color": "#a7f3d0",
87+
padding: "12px",
88+
border: "1px solid var(--vscode-panel-border)",
89+
borderRadius: "4px",
90+
} as React.CSSProperties
91+
}>
92+
<ShimmerText style={{ fontSize: "18px" }}>Inherits green from parent container</ShimmerText>
93+
</div>
94+
</div>
95+
),
96+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import * as React from "react"
2+
import { Slot } from "@radix-ui/react-slot"
3+
import { cn } from "@/lib/utils"
4+
5+
export interface ShimmerTextProps extends React.HTMLAttributes<HTMLSpanElement> {
6+
children: React.ReactNode
7+
asChild?: boolean
8+
/** Custom foreground/base color (e.g., "#ff0000" or "rgb(255, 0, 0)") */
9+
foregroundColor?: string
10+
/** Custom highlight color for the shimmer effect */
11+
highlightColor?: string
12+
}
13+
14+
const ShimmerText = React.forwardRef<HTMLSpanElement, ShimmerTextProps>(
15+
({ className, children, asChild = false, foregroundColor, highlightColor, style, ...props }, ref) => {
16+
const Comp = asChild ? Slot : "span"
17+
18+
const customStyle = {
19+
...style,
20+
...(foregroundColor && { "--shimmer-foreground": foregroundColor }),
21+
...(highlightColor && { "--shimmer-highlight-color": highlightColor }),
22+
} as React.CSSProperties
23+
24+
return (
25+
<Comp ref={ref} {...props} style={customStyle} className={cn("shimmer-text", className)}>
26+
{children}
27+
</Comp>
28+
)
29+
},
30+
)
31+
ShimmerText.displayName = "ShimmerText"
32+
33+
export { ShimmerText }

webview-ui/src/kilocode.css

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,37 @@
6060
.animate-message-highlight {
6161
animation: message-highlight 1s ease-out forwards;
6262
}
63+
64+
/* Shimmer text animation - horizontal shimmer effect */
65+
@keyframes shimmer {
66+
0% {
67+
background-position: 200% center;
68+
}
69+
100% {
70+
background-position: -200% center;
71+
}
72+
}
73+
74+
.shimmer-text {
75+
/* Allow custom colors via CSS variables, with fallback to VSCode theme colors */
76+
--shimmer-base: var(--shimmer-foreground, color-mix(in srgb, var(--vscode-descriptionForeground) 80%, black));
77+
--shimmer-highlight: var(--shimmer-highlight-color, color-mix(in srgb, var(--shimmer-base) 70%, white));
78+
79+
color: var(--shimmer-base);
80+
background: linear-gradient(
81+
90deg,
82+
var(--shimmer-base) 0%,
83+
var(--shimmer-base) 35%,
84+
var(--shimmer-highlight) 45%,
85+
var(--shimmer-highlight) 50%,
86+
var(--shimmer-highlight) 55%,
87+
var(--shimmer-base) 65%,
88+
var(--shimmer-base) 100%
89+
);
90+
background-size: 200% 100%;
91+
-webkit-background-clip: text;
92+
background-clip: text;
93+
-webkit-text-fill-color: transparent;
94+
display: inline-block;
95+
animation: shimmer 2.5s linear infinite;
96+
}

0 commit comments

Comments
 (0)