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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions public/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,8 @@ bunx carllosnc/dashkit add navigation-menu

The Navigation Menu uses a value-based system to track the active item. Ensure the `value` on `NavigationMenuTrigger` matches the `value` on `NavigationMenuContent`.



```tsx
<NavigationMenu>
<NavigationMenuList>
Expand All @@ -819,19 +821,24 @@ The Navigation Menu uses a value-based system to track the active item. Ensure t

### NavigationMenu


| Property | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `delay` | `number` | `200` | Delay in milliseconds before closing the menu after the mouse leaves. |
| `className` | `string` | - | Additional CSS classes for the root container. |


### NavigationMenuTrigger


| Property | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `value` | `string` | - | A unique value to associate the trigger with its corresponding content. |


### NavigationMenuContent


| Property | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `value` | `string` | - | The unique value matching the NavigationMenuTrigger. |
Expand Down Expand Up @@ -6107,10 +6114,12 @@ bunx carllosnc/dashkit add statscard

The `StatsCard` is perfect for dashboards and summary sections.







```tsx
import { StatsCard } from 'dashkit';

Expand Down Expand Up @@ -6144,6 +6153,7 @@ export default () => (

Add visual context using icons from `react-icons`.


}
status="info"
description="Completion across all active sprints"
Expand All @@ -6155,6 +6165,7 @@ Add visual context using icons from `react-icons`.
description="Unassigned support requests"
/>


```tsx
import { StatsCard } from 'dashkit';
import { HiOutlineChartBarSquare, HiOutlineTicket } from 'react-icons/hi2';
Expand Down Expand Up @@ -6182,10 +6193,12 @@ export default () => (

Visualize data trends directly within the card using the `chart` prop.







```tsx
import { StatsCard } from 'dashkit';

Expand All @@ -6207,9 +6220,11 @@ export default () => (

Combine sparklines and descriptive footers for maximum context.






```tsx
import { StatsCard } from 'dashkit';

Expand Down Expand Up @@ -6244,6 +6259,7 @@ export default () => (

### StatsCard Props


| Property | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `title` | `string` | - | The label for the metric. |
Expand Down Expand Up @@ -6380,8 +6396,10 @@ bunx carllosnc/dashkit add systemlogs

The `SystemLogs` component takes an array of `logs` and renders them in a dark, monospace container that mimics a terminal environment.





```tsx
import { SystemLogs } from '@/dashkit/SystemLogs/SystemLogs'

Expand Down Expand Up @@ -6414,8 +6432,10 @@ The component supports five distinct log levels, each with its own visual style:
- `error`: Error messages (indicated by `[ERR]`)
- `stable`: Stability or state updates (indicated by `[STB]`)





## Customization

### Auto-scrolling
Expand All @@ -6431,6 +6451,7 @@ By default, the component automatically scrolls to the bottom when new logs are

## Props


| Property | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `logs` | `LogEntry[]` | - | An array of log entries to display. Each entry has a type, message, and optional timestamp. |
Expand Down Expand Up @@ -6908,6 +6929,25 @@ Transform any pie chart into a donut chart by setting the `innerRadius` property
/>
```

### Textured Slices

Apply SVG patterns across the entire chart with the `texture` prop (`'striped' | 'dots' | 'grid' | 'gradient'`) or mix different textures per slice inside `data`.





```tsx
<PieChart
innerRadius={0.55}
data={[
{ label: 'Completed', value: 55, color: 'var(--color-emerald-500)', texture: 'gradient' },
{ label: 'In Progress', value: 30, color: 'var(--color-blue-500)', texture: 'striped' },
{ label: 'Planned', value: 15, color: 'var(--color-amber-500)', texture: 'dots' },
]}
/>
```

## API Reference

### PieChart
Expand All @@ -6921,6 +6961,7 @@ Transform any pie chart into a donut chart by setting the `innerRadius` property
| `showLabels` | `boolean` | `true` | Display the legend below the chart. |
| `showTooltip` | `boolean` | `true` | Enable interactive segment tooltips. |
| `animate` | `boolean` | `true` | Enable entrance animations. |
| `texture` | `'none' \| 'striped' \| 'dots' \| 'grid' \| 'gradient'` | `'none'` | SVG pattern texture applied over the slices (can also be overridden per item in data). |
| `className` | `string` | - | Additional CSS for the container. |


Expand Down
2 changes: 1 addition & 1 deletion public/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,7 @@
"usePieChart"
],
"propsDefinitions": [
"export interface PieChartProps {\r\n data: PieChartDataItem[];\r\n className?: string;\r\n innerRadius?: number;\r\n showLabels?: boolean;\r\n showTooltip?: boolean;\r\n animate?: boolean;\r\n}",
"export interface PieChartProps {\r\n data: PieChartDataItem[];\r\n className?: string;\r\n innerRadius?: number;\r\n showLabels?: boolean;\r\n showTooltip?: boolean;\r\n animate?: boolean;\r\n texture?: PieChartTexture;\r\n}",
"export interface UsePieChartProps {\r\n data: PieChartDataItem[];\r\n innerRadius: number;\r\n showTooltip: boolean;\r\n}"
]
},
Expand Down
12 changes: 6 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import { Footer } from './partials/Footer'
import { HomeExamples } from './partials/HomeExamples'
import { Divider } from './dashkit/Divider/Divider'

const TITLE = "Dashkit | Build Modern Interfaces Faster";
const DESCRIPTION = "Copy-paste 55+ customizable React 19 & Tailwind CSS v4 components straight into your project. Total code ownership, dynamic semantic tokens, and native context for AI coding agents.";
const TAGLINE = "Build Modern Interfaces Faster";
const OG_DESCRIPTION = "Copy-paste 55+ customizable React 19 & Tailwind CSS v4 components straight into your project with total code ownership and native AI context.";
const TITLE = "Dashkit | Ship modern interfaces in minutes";
const DESCRIPTION = "Ready-to-use components you can copy straight into your project. Fully customizable, accessible by default, and yours to own.";
const TAGLINE = "Ship modern interfaces in minutes";
const OG_DESCRIPTION = "Ready-to-use components you can copy straight into your project. Fully customizable, accessible by default, and yours to own.";

function App() {
return (
Expand Down Expand Up @@ -44,11 +44,11 @@ function App() {
/>
</div>

<h1 className="text-4xl md:text-5xl font-bold tracking-tight text-foreground max-w-4xl leading-tight mb-6">
<h1 className="text-4xl md:text-5xl font-bold tracking-tight text-foreground leading-tight mb-5">
{TAGLINE}
</h1>

<p className="text-base md:text-xl text-muted-foreground max-w-2xl leading-relaxed mb-10">
<p className="text-base md:text-lg text-muted-foreground max-w-2xl leading-relaxed text-balance mb-10">
{DESCRIPTION}
</p>

Expand Down
22 changes: 21 additions & 1 deletion src/dashkit/ImageExpander/ImageExpander.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render, screen, fireEvent } from '@testing-library/react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { ImageExpander } from './ImageExpander';

describe('ImageExpander', () => {
Expand Down Expand Up @@ -51,6 +51,26 @@ describe('ImageExpander', () => {
fireEvent.keyDown(window, { key: 'Escape' });
// State change is internal, in a real env it would close.
});

it('closes when clicking the expanded image', async () => {
render(
<ImageExpander
caption="Click Image Test"
full={<img src="full.jpg" alt="Expanded" />}
>
<img src="test.jpg" alt="Thumbnail" />
</ImageExpander>
);

fireEvent.click(screen.getByAltText('Thumbnail'));
const expandedImg = screen.getByAltText('Expanded');
expect(expandedImg).toBeInTheDocument();

fireEvent.click(expandedImg);
await waitFor(() => {
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
});
});
});


34 changes: 15 additions & 19 deletions src/dashkit/ImageExpander/ImageExpander.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,39 +70,35 @@ export function ImageExpander({ children, full, caption, className }: ImageExpan
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.95 }}
transition={{ type: 'spring', damping: 25, stiffness: 300 }}
className="relative z-[105] w-full h-full flex flex-col items-center justify-center overflow-auto no-scrollbar scroll-smooth selection:bg-ds-500/30"
onClick={(e: React.MouseEvent) => e.stopPropagation()}
className="relative z-[105] w-full h-full flex flex-col items-center justify-center p-4 md:p-8 overflow-auto no-scrollbar scroll-smooth selection:bg-ds-500/30 pointer-events-none"
>
<div className="relative shrink-0 flex items-center justify-center min-w-full min-h-full">
<div className="cursor-default">
<div
className="relative shrink-0 flex flex-col items-center justify-center gap-4 pointer-events-auto"
onClick={(e: React.MouseEvent) => e.stopPropagation()}
>
<div
className="cursor-zoom-out"
onClick={() => setIsOpen(false)}
>
{displayFull}
</div>
</div>

{caption && (
<>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-x-0 bottom-0 h-48 bg-gradient-to-t from-ds-950/80 via-ds-950/40 to-transparent pointer-events-none z-[115]"
/>

{caption && (
<motion.div
initial={{ opacity: 0, y: 20 }}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 20 }}
exit={{ opacity: 0, y: 10 }}
transition={{
type: 'spring',
damping: 30,
stiffness: 350
}}
className="fixed bottom-12 left-1/2 -translate-x-1/2 text-white/90 text-sm font-semibold z-[120] flex items-center gap-2.5 tracking-tight"
className="text-white/90 text-sm font-semibold flex items-center gap-2.5 tracking-tight text-center"
>
{caption}
</motion.div>
</>
)}
)}
</div>
</motion.div>
</motion.div>
)}
Expand Down
15 changes: 15 additions & 0 deletions src/dashkit/PieChart/PieChart.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,19 @@ describe('PieChart', () => {
const paths = container.querySelectorAll('path');
expect(paths).toHaveLength(3);
});

it('renders texture overlay paths when global or per-slice texture is set', () => {
const { container } = render(
<PieChart
data={[
{ label: 'A', value: 50, color: 'red', texture: 'striped' },
{ label: 'B', value: 50, color: 'blue' },
]}
/>
);
const paths = container.querySelectorAll('path');
// 2 base slice paths + 1 texture overlay path for slice A
expect(paths).toHaveLength(3);
expect(paths[1].getAttribute('fill')).toMatch(/^url\(#pie-texture-striped-/);
});
});
Loading
Loading