@siyahi/ui 0.1.9-next.2 → 0.1.9-next.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -176
- package/THIRD_PARTY_NOTICES.md +11 -11
- package/agents/examples/accordion.tsx +39 -0
- package/agents/examples/alert.tsx +25 -0
- package/agents/examples/app-sidebar.tsx +38 -0
- package/agents/examples/avatar.tsx +14 -0
- package/agents/examples/badge.tsx +18 -0
- package/agents/examples/bar-list-labels.tsx +22 -0
- package/agents/examples/bar-list-sides.tsx +30 -0
- package/agents/examples/bar-list.tsx +24 -0
- package/agents/examples/breadcrumb.tsx +28 -0
- package/agents/examples/button.tsx +21 -0
- package/agents/examples/calendar.tsx +15 -0
- package/agents/examples/card.tsx +34 -0
- package/agents/examples/chart-area.tsx +38 -0
- package/agents/examples/chart-bar-flows.tsx +31 -0
- package/agents/examples/chart-bar-hourly.tsx +28 -0
- package/agents/examples/chart-bar-losses.tsx +29 -0
- package/agents/examples/chart-bar-sectors.tsx +70 -0
- package/agents/examples/chart-bar-years.tsx +40 -0
- package/agents/examples/chart-bar.tsx +56 -0
- package/agents/examples/chart-category-ticks.tsx +50 -0
- package/agents/examples/chart-line-events.tsx +47 -0
- package/agents/examples/chart-line-timeline.tsx +41 -0
- package/agents/examples/chart-line.tsx +57 -0
- package/agents/examples/code-block.tsx +38 -0
- package/agents/examples/collapsible.tsx +16 -0
- package/agents/examples/command.tsx +27 -0
- package/agents/examples/context-menu.tsx +15 -0
- package/agents/examples/copy-button.tsx +8 -0
- package/agents/examples/data-bar.tsx +121 -0
- package/agents/examples/data-table-filters.tsx +103 -0
- package/agents/examples/data-table.tsx +98 -0
- package/agents/examples/delta.tsx +13 -0
- package/agents/examples/dialog.tsx +28 -0
- package/agents/examples/distribution-bar-budget.tsx +30 -0
- package/agents/examples/distribution-bar-tug.tsx +72 -0
- package/agents/examples/dropdown-menu.tsx +31 -0
- package/agents/examples/formatters.tsx +42 -0
- package/agents/examples/heatmap-calendar.tsx +50 -0
- package/agents/examples/heatmap-status.tsx +51 -0
- package/agents/examples/heatmap-weekday.tsx +53 -0
- package/agents/examples/input.tsx +17 -0
- package/agents/examples/local-time.tsx +14 -0
- package/agents/examples/metric-strip.tsx +40 -0
- package/agents/examples/page-section.tsx +52 -0
- package/agents/examples/popover.tsx +23 -0
- package/agents/examples/price-chart.tsx +32 -0
- package/agents/examples/progress-tone.tsx +28 -0
- package/agents/examples/progress.tsx +10 -0
- package/agents/examples/scroll-area.tsx +20 -0
- package/agents/examples/section-cards-select.tsx +27 -0
- package/agents/examples/section-cards-trend.tsx +30 -0
- package/agents/examples/section-cards.tsx +48 -0
- package/agents/examples/select.tsx +27 -0
- package/agents/examples/separator.tsx +13 -0
- package/agents/examples/sheet.tsx +15 -0
- package/agents/examples/skeleton.tsx +11 -0
- package/agents/examples/slider.tsx +5 -0
- package/agents/examples/surfaces.tsx +115 -0
- package/agents/examples/table.tsx +50 -0
- package/agents/examples/tabs.tsx +16 -0
- package/agents/examples/toggle-group.tsx +12 -0
- package/agents/examples/toggle.tsx +11 -0
- package/agents/examples/tooltip.tsx +13 -0
- package/agents/examples/treemap.tsx +87 -0
- package/agents/manifest.json +931 -0
- package/agents/report-rules.json +7 -0
- package/dist/components/registry/charts/bar-chart-card.js +33 -26
- package/dist/components/registry/dashboard-01/section-cards.d.ts +2 -0
- package/dist/components/registry/dashboard-01/section-cards.js +42 -35
- package/dist/components/registry/dashboardcn/bar-list.js +9 -8
- package/dist/components/registry/dashboardcn/distribution-bar.js +1 -1
- package/dist/components/registry/dashboardcn/kpi-row-card.d.ts +29 -0
- package/dist/components/registry/dashboardcn/kpi-row-card.js +81 -0
- package/dist/components/registry/dashboardcn/sparkline.d.ts +18 -0
- package/dist/components/registry/dashboardcn/sparkline.js +95 -0
- package/dist/components/registry/heatmap/calendar-heatmap.js +8 -1
- package/dist/components/registry/heatmap/status-heatmap.js +8 -1
- package/dist/components/registry/heatmap/weekday-heatmap.d.ts +6 -2
- package/dist/components/registry/heatmap/weekday-heatmap.js +56 -37
- package/dist/components/registry/niko-table/core/data-table-context.d.ts +2 -0
- package/dist/components/registry/niko-table/core/data-table-context.js +21 -0
- package/dist/components/registry/niko-table/core/data-table-grouped-row.js +3 -1
- package/dist/components/registry/niko-table/core/data-table-structure.js +15 -12
- package/dist/components/registry/niko-table/core/data-table.d.ts +2 -2
- package/dist/components/registry/niko-table/core/data-table.js +5 -1
- package/dist/components/registry/niko-table/filters/table-faceted-filter.js +4 -4
- package/dist/components/registry/niko-table/filters/table-search-filter.js +1 -1
- package/dist/components/registry/niko-table/lib/flex-columns.d.ts +1 -1
- package/dist/components/registry/niko-table/lib/flex-columns.js +3 -3
- package/dist/components/registry/niko-table/lib/styles.d.ts +1 -1
- package/dist/components/registry/niko-table/lib/styles.js +2 -2
- package/dist/components/registry/niko-table/ui/table.js +2 -2
- package/dist/components/registry/sidebar-07/app-sidebar.d.ts +1 -1
- package/dist/components/registry/sidebar-07/app-sidebar.js +3 -1
- package/dist/components/registry/sidebar-07/nav-main.d.ts +1 -1
- package/dist/components/registry/sidebar-07/nav-main.js +7 -1
- package/dist/components/siyahi/data-bar.d.ts +19 -0
- package/dist/components/siyahi/data-bar.js +29 -0
- package/dist/components/siyahi/page-section.d.ts +4 -1
- package/dist/components/siyahi/page-section.js +6 -3
- package/dist/components/siyahi/panel-grid.d.ts +22 -0
- package/dist/components/siyahi/panel-grid.js +34 -0
- package/dist/components/siyahi/siyahi-provider.d.ts +13 -2
- package/dist/components/siyahi/siyahi-provider.js +17 -4
- package/dist/components/siyahi/treemap.js +46 -4
- package/dist/components/ui/accordion.js +5 -5
- package/dist/components/ui/alert.js +2 -2
- package/dist/components/ui/badge.js +1 -1
- package/dist/components/ui/breadcrumb.js +2 -2
- package/dist/components/ui/button.js +10 -10
- package/dist/components/ui/calendar.js +1 -1
- package/dist/components/ui/card.js +4 -4
- package/dist/components/ui/chart.js +1 -1
- package/dist/components/ui/code-block.js +13 -12
- package/dist/components/ui/command.js +7 -6
- package/dist/components/ui/context-menu.js +7 -7
- package/dist/components/ui/dialog.js +5 -5
- package/dist/components/ui/dropdown-menu.js +8 -8
- package/dist/components/ui/input-group.js +11 -11
- package/dist/components/ui/input.js +1 -1
- package/dist/components/ui/popover.js +3 -3
- package/dist/components/ui/progress.js +1 -1
- package/dist/components/ui/select.js +6 -6
- package/dist/components/ui/sheet.js +5 -5
- package/dist/components/ui/sidebar.js +17 -18
- package/dist/components/ui/skeleton.js +1 -1
- package/dist/components/ui/slider.js +2 -2
- package/dist/components/ui/table.js +2 -2
- package/dist/components/ui/tabs.js +2 -2
- package/dist/components/ui/textarea.js +1 -1
- package/dist/components/ui/toggle-group.js +2 -2
- package/dist/components/ui/toggle.js +4 -4
- package/dist/components/ui/tooltip.js +2 -2
- package/dist/index.d.ts +7 -4
- package/dist/index.js +7 -4
- package/dist/lib/chart-frame.d.ts +13 -5
- package/dist/lib/chart-frame.js +207 -127
- package/dist/lib/chart-series.d.ts +7 -4
- package/dist/lib/format.js +32 -13
- package/dist/lib/heatmap-navigation.d.ts +8 -0
- package/dist/lib/heatmap-navigation.js +49 -0
- package/package.json +3 -1
- package/registry.lock.json +16 -0
- package/report.css +11 -11
- package/styles/siyahi.css +77 -11
- package/dist/lib/recharts.d.ts +0 -2
- package/dist/lib/recharts.js +0 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
//#region src/components/siyahi/data-bar.d.ts
|
|
3
|
+
export interface DataBarProps {
|
|
4
|
+
value: number;
|
|
5
|
+
/** The value a full bar stands for, usually the column's largest: Math.max(...rows.map((row) => row.value)). */
|
|
6
|
+
max: number;
|
|
7
|
+
/** "sign" draws a gain in --positive and a loss in --negative; by default every bar is --chart-1. */
|
|
8
|
+
tone?: "chart" | "sign";
|
|
9
|
+
/** The figure, as the page formats it. */
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A table cell's figure behind a short bar whose length is the figure's share of max, so a column reads as a chart.
|
|
15
|
+
* The bar has a fixed width, so every row draws to the same scale, and sits on the figure's line, so the row
|
|
16
|
+
* keeps its height.
|
|
17
|
+
*/
|
|
18
|
+
export declare function DataBar({ value, max, tone, children, className }: DataBarProps): import("react").JSX.Element;
|
|
19
|
+
//#endregion
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { cn } from "cn";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
//#region src/components/siyahi/data-bar.tsx
|
|
4
|
+
/**
|
|
5
|
+
* A table cell's figure behind a short bar whose length is the figure's share of max, so a column reads as a chart.
|
|
6
|
+
* The bar has a fixed width, so every row draws to the same scale, and sits on the figure's line, so the row
|
|
7
|
+
* keeps its height.
|
|
8
|
+
*/
|
|
9
|
+
function DataBar({ value, max, tone = "chart", children, className }) {
|
|
10
|
+
const share = max > 0 ? Math.min(1, Math.abs(value) / max) : 0;
|
|
11
|
+
const fill = tone === "chart" ? "bg-chart-1" : value < 0 ? "bg-negative" : "bg-positive";
|
|
12
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
13
|
+
"data-slot": "data-bar",
|
|
14
|
+
className: cn("flex items-center gap-2", className),
|
|
15
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
16
|
+
"aria-hidden": "true",
|
|
17
|
+
className: "h-1.5 w-16 shrink-0 overflow-hidden rounded-full bg-muted",
|
|
18
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
19
|
+
className: cn("h-full rounded-full", fill),
|
|
20
|
+
style: { width: `${share * 100}%` }
|
|
21
|
+
})
|
|
22
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
23
|
+
className: "tabular-nums",
|
|
24
|
+
children
|
|
25
|
+
})]
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { DataBar };
|
|
@@ -12,7 +12,10 @@ export interface PageSectionProps {
|
|
|
12
12
|
action?: ReactNode;
|
|
13
13
|
children?: ReactNode;
|
|
14
14
|
}
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* One part of a long page: a rule above, then the heading and lead on the canvas, then its content. Spaced for
|
|
17
|
+
* density, 24px under the rule and 16px to the content, so sections stacked 24px apart sit 24px either side of it.
|
|
18
|
+
*/
|
|
16
19
|
export declare function PageSection({ id, eyebrow, title, lead, action, children }: PageSectionProps): import("react").JSX.Element;
|
|
17
20
|
/** A heading inside a PageSection, one level under its title. */
|
|
18
21
|
export declare function PageSubheading({ children }: {
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
//#region src/components/siyahi/page-section.tsx
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* One part of a long page: a rule above, then the heading and lead on the canvas, then its content. Spaced for
|
|
5
|
+
* density, 24px under the rule and 16px to the content, so sections stacked 24px apart sit 24px either side of it.
|
|
6
|
+
*/
|
|
4
7
|
function PageSection({ id, eyebrow, title, lead, action, children }) {
|
|
5
8
|
return /* @__PURE__ */ jsxs("section", {
|
|
6
9
|
id,
|
|
7
10
|
"data-slot": "page-section",
|
|
8
|
-
className: "flex scroll-mt-6 flex-col gap-
|
|
11
|
+
className: "flex scroll-mt-6 flex-col gap-4 border-t pt-6",
|
|
9
12
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
10
13
|
className: "flex flex-wrap items-end justify-between gap-4",
|
|
11
14
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
@@ -16,7 +19,7 @@ function PageSection({ id, eyebrow, title, lead, action, children }) {
|
|
|
16
19
|
children: eyebrow
|
|
17
20
|
}),
|
|
18
21
|
/* @__PURE__ */ jsx("h2", {
|
|
19
|
-
className: "text-
|
|
22
|
+
className: "text-xl font-semibold tracking-tight",
|
|
20
23
|
children: title
|
|
21
24
|
}),
|
|
22
25
|
lead && /* @__PURE__ */ jsx("div", {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
//#region src/components/siyahi/panel-grid.d.ts
|
|
3
|
+
declare const COLUMNS: {
|
|
4
|
+
readonly 1: "";
|
|
5
|
+
readonly 2: "@2xl/panels:grid-cols-2";
|
|
6
|
+
readonly 3: "@2xl/panels:grid-cols-2 @5xl/panels:grid-cols-3";
|
|
7
|
+
readonly 4: "@2xl/panels:grid-cols-2 @5xl/panels:grid-cols-4";
|
|
8
|
+
};
|
|
9
|
+
export interface PanelGridProps {
|
|
10
|
+
/** Blocks across on a wide page; two on a medium one, and one on a phone. */
|
|
11
|
+
columns?: keyof typeof COLUMNS;
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Data blocks side by side: chart cards, tables, a MetricStrip. On a ruled surface a hairline parts them across and
|
|
17
|
+
* down, with a rule above and below the grid; open leaves whitespace between them, and card a gap between boxes.
|
|
18
|
+
* Each block's left and top edges carry its rules, and the grid clips the ones on its own edges.
|
|
19
|
+
*/
|
|
20
|
+
export declare function PanelGrid({ columns, children, className }: PanelGridProps): import("react").JSX.Element;
|
|
21
|
+
//#endregion
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useSurface } from "./siyahi-provider.js";
|
|
2
|
+
import { cn } from "cn";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { Children } from "react";
|
|
5
|
+
//#region src/components/siyahi/panel-grid.tsx
|
|
6
|
+
const COLUMNS = {
|
|
7
|
+
1: "",
|
|
8
|
+
2: "@2xl/panels:grid-cols-2",
|
|
9
|
+
3: "@2xl/panels:grid-cols-2 @5xl/panels:grid-cols-3",
|
|
10
|
+
4: "@2xl/panels:grid-cols-2 @5xl/panels:grid-cols-4"
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Data blocks side by side: chart cards, tables, a MetricStrip. On a ruled surface a hairline parts them across and
|
|
14
|
+
* down, with a rule above and below the grid; open leaves whitespace between them, and card a gap between boxes.
|
|
15
|
+
* Each block's left and top edges carry its rules, and the grid clips the ones on its own edges.
|
|
16
|
+
*/
|
|
17
|
+
function PanelGrid({ columns = 2, children, className }) {
|
|
18
|
+
const surface = useSurface();
|
|
19
|
+
const ruled = surface === "ruled";
|
|
20
|
+
return /* @__PURE__ */ jsx("div", {
|
|
21
|
+
"data-slot": "panel-grid",
|
|
22
|
+
className: cn("@container/panels", ruled && "overflow-clip border-y", className),
|
|
23
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
24
|
+
className: cn("grid grid-cols-1", COLUMNS[columns], ruled ? "-mt-px -ml-px" : surface === "open" ? "gap-x-8 gap-y-6" : "gap-4"),
|
|
25
|
+
children: Children.map(children, (child) => /* @__PURE__ */ jsx("div", {
|
|
26
|
+
"data-slot": "panel",
|
|
27
|
+
className: cn("min-w-0", ruled && "border-t border-l"),
|
|
28
|
+
children: child
|
|
29
|
+
}))
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { PanelGrid };
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
import { SiyahiLocale } from "../../lib/locale.js";
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
3
|
//#region src/components/siyahi/siyahi-provider.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* How a data block sits on the page. "ruled": no box, hairlines between blocks in a PanelGrid. "open": no box and no
|
|
6
|
+
* lines, the block's content level with the page's text. "card": shadcn's own card, a filled box with a 1px ring.
|
|
7
|
+
*/
|
|
8
|
+
export type Surface = "ruled" | "open" | "card";
|
|
4
9
|
export interface SiyahiProviderProps {
|
|
5
10
|
/** Any setting left out keeps its default: en-IN, INR, Asia/Kolkata. */
|
|
6
11
|
locale?: Partial<SiyahiLocale>;
|
|
12
|
+
/**
|
|
13
|
+
* Set it on a nested provider for one part of a page. Left out, a provider keeps the surface around it, so a
|
|
14
|
+
* provider that only changes the locale changes nothing else; the outermost default is "ruled".
|
|
15
|
+
*/
|
|
16
|
+
surface?: Surface;
|
|
7
17
|
children: ReactNode;
|
|
8
18
|
}
|
|
9
|
-
/** Wrap the app once. Carries the locale and the tooltip provider shadcn asks for. */
|
|
10
|
-
export declare function SiyahiProvider({ locale, children }: SiyahiProviderProps): import("react").JSX.Element;
|
|
19
|
+
/** Wrap the app once. Carries the locale, the surface and the tooltip provider shadcn asks for. */
|
|
20
|
+
export declare function SiyahiProvider({ locale, surface, children }: SiyahiProviderProps): import("react").JSX.Element;
|
|
11
21
|
export declare function useLocale(): SiyahiLocale;
|
|
22
|
+
export declare function useSurface(): Surface;
|
|
12
23
|
//#endregion
|
|
@@ -4,8 +4,9 @@ import { jsx } from "react/jsx-runtime";
|
|
|
4
4
|
import { createContext, use, useMemo } from "react";
|
|
5
5
|
//#region src/components/siyahi/siyahi-provider.tsx
|
|
6
6
|
const LocaleContext = createContext(defaultLocale);
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const SurfaceContext = createContext("ruled");
|
|
8
|
+
/** Wrap the app once. Carries the locale, the surface and the tooltip provider shadcn asks for. */
|
|
9
|
+
function SiyahiProvider({ locale, surface, children }) {
|
|
9
10
|
const { numberLocale, currency, timeZone } = {
|
|
10
11
|
...defaultLocale,
|
|
11
12
|
...locale
|
|
@@ -19,13 +20,25 @@ function SiyahiProvider({ locale, children }) {
|
|
|
19
20
|
currency,
|
|
20
21
|
timeZone
|
|
21
22
|
]);
|
|
23
|
+
const around = use(SurfaceContext);
|
|
22
24
|
return /* @__PURE__ */ jsx(LocaleContext, {
|
|
23
25
|
value,
|
|
24
|
-
children: /* @__PURE__ */ jsx(
|
|
26
|
+
children: /* @__PURE__ */ jsx(SurfaceContext, {
|
|
27
|
+
value: surface ?? around,
|
|
28
|
+
children: /* @__PURE__ */ jsx(TooltipProvider, { children: surface ? /* @__PURE__ */ jsx("div", {
|
|
29
|
+
"data-slot": "siyahi-provider",
|
|
30
|
+
"data-surface": surface,
|
|
31
|
+
className: "contents",
|
|
32
|
+
children
|
|
33
|
+
}) : children })
|
|
34
|
+
})
|
|
25
35
|
});
|
|
26
36
|
}
|
|
27
37
|
function useLocale() {
|
|
28
38
|
return use(LocaleContext);
|
|
29
39
|
}
|
|
40
|
+
function useSurface() {
|
|
41
|
+
return use(SurfaceContext);
|
|
42
|
+
}
|
|
30
43
|
//#endregion
|
|
31
|
-
export { SiyahiProvider, useLocale };
|
|
44
|
+
export { SiyahiProvider, useLocale, useSurface };
|
|
@@ -2,12 +2,13 @@ import { useFormat } from "../../lib/format.js";
|
|
|
2
2
|
import { heat, heatFill, heatRange, layout } from "../../lib/treemap.js";
|
|
3
3
|
import { cn } from "cn";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import { useEffect, useEffectEvent, useLayoutEffect, useRef, useState } from "react";
|
|
5
|
+
import { useEffect, useEffectEvent, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
6
6
|
//#region src/components/siyahi/treemap.tsx
|
|
7
7
|
/** Holdings heat map: area by weight, colour by signed change, optionally grouped; hand-drawn SVG. */
|
|
8
8
|
function Treemap({ items, height, range, onHover, selected, onSelect }) {
|
|
9
9
|
const ref = useRef(null);
|
|
10
10
|
const [width, setWidth] = useState(0);
|
|
11
|
+
const [focusedKey, setFocusedKey] = useState(null);
|
|
11
12
|
const selectedKey = selected ? selected.key ?? selected.name : null;
|
|
12
13
|
const { pct } = useFormat();
|
|
13
14
|
useLayoutEffect(() => {
|
|
@@ -25,7 +26,12 @@ function Treemap({ items, height, range, onHover, selected, onSelect }) {
|
|
|
25
26
|
document.addEventListener("pointerdown", onPointerDown);
|
|
26
27
|
return () => document.removeEventListener("pointerdown", onPointerDown);
|
|
27
28
|
}, [selectedKey]);
|
|
28
|
-
const { groups, tiles } = layout(items, width, height)
|
|
29
|
+
const { groups, tiles } = useMemo(() => layout(items, width, height), [
|
|
30
|
+
items,
|
|
31
|
+
width,
|
|
32
|
+
height
|
|
33
|
+
]);
|
|
34
|
+
const focusKey = tiles.some(({ item }) => (item.key ?? item.name) === focusedKey) ? focusedKey : tiles[0]?.item.key ?? tiles[0]?.item.name;
|
|
29
35
|
const change = (value) => value === null ? "—" : `${value > 0 ? "▲ " : value < 0 ? "▼ " : ""}${pct(Math.abs(value))}`;
|
|
30
36
|
return /* @__PURE__ */ jsx("div", {
|
|
31
37
|
ref,
|
|
@@ -34,7 +40,7 @@ function Treemap({ items, height, range, onHover, selected, onSelect }) {
|
|
|
34
40
|
children: /* @__PURE__ */ jsxs("svg", {
|
|
35
41
|
width,
|
|
36
42
|
height,
|
|
37
|
-
role: "img",
|
|
43
|
+
role: onSelect ? "group" : "img",
|
|
38
44
|
"aria-label": "Treemap of holdings by weight and change",
|
|
39
45
|
className: "text-xs",
|
|
40
46
|
onPointerLeave: () => onHover?.(null),
|
|
@@ -53,12 +59,48 @@ function Treemap({ items, height, range, onHover, selected, onSelect }) {
|
|
|
53
59
|
className: "fill-muted-foreground font-medium",
|
|
54
60
|
children: group
|
|
55
61
|
})]
|
|
56
|
-
}, group)), tiles.map(({ item, ...box }) => {
|
|
62
|
+
}, group)), tiles.map(({ item, ...box }, index) => {
|
|
57
63
|
const key = item.key ?? item.name;
|
|
58
64
|
return /* @__PURE__ */ jsxs("svg", {
|
|
59
65
|
...box,
|
|
60
66
|
"data-slot": "treemap-tile",
|
|
61
67
|
"data-selected": key === selectedKey || void 0,
|
|
68
|
+
role: onSelect ? "button" : void 0,
|
|
69
|
+
tabIndex: onSelect ? key === focusKey ? 0 : -1 : void 0,
|
|
70
|
+
"aria-label": `${item.name}${item.group ? `, ${item.group}` : ""}, ${change(item.change)}`,
|
|
71
|
+
"aria-pressed": onSelect ? key === selectedKey : void 0,
|
|
72
|
+
onFocus: () => setFocusedKey(key),
|
|
73
|
+
onKeyDown: (event) => {
|
|
74
|
+
if (!onSelect) return;
|
|
75
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
76
|
+
event.preventDefault();
|
|
77
|
+
onSelect(key === selectedKey ? null : item);
|
|
78
|
+
} else if (event.key === "Escape") onSelect(null);
|
|
79
|
+
else {
|
|
80
|
+
let next;
|
|
81
|
+
switch (event.key) {
|
|
82
|
+
case "Home":
|
|
83
|
+
next = 0;
|
|
84
|
+
break;
|
|
85
|
+
case "End":
|
|
86
|
+
next = tiles.length - 1;
|
|
87
|
+
break;
|
|
88
|
+
case "ArrowRight":
|
|
89
|
+
case "ArrowDown":
|
|
90
|
+
next = (index + 1) % tiles.length;
|
|
91
|
+
break;
|
|
92
|
+
case "ArrowLeft":
|
|
93
|
+
case "ArrowUp":
|
|
94
|
+
next = (index + tiles.length - 1) % tiles.length;
|
|
95
|
+
break;
|
|
96
|
+
default: return;
|
|
97
|
+
}
|
|
98
|
+
event.preventDefault();
|
|
99
|
+
const target = tiles[next]?.item;
|
|
100
|
+
if (target) setFocusedKey(target.key ?? target.name);
|
|
101
|
+
ref.current?.querySelectorAll("[data-slot=\"treemap-tile\"]")[next]?.focus();
|
|
102
|
+
}
|
|
103
|
+
},
|
|
62
104
|
onPointerEnter: () => onHover?.(item),
|
|
63
105
|
onClick: () => onSelect?.(key === selectedKey ? null : item),
|
|
64
106
|
children: [
|
|
@@ -6,14 +6,14 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
function Accordion({ className, ...props }) {
|
|
7
7
|
return /* @__PURE__ */ jsx(Accordion$1.Root, {
|
|
8
8
|
"data-slot": "accordion",
|
|
9
|
-
className: cn("flex w-full flex-col
|
|
9
|
+
className: cn("flex w-full flex-col", className),
|
|
10
10
|
...props
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
function AccordionItem({ className, ...props }) {
|
|
14
14
|
return /* @__PURE__ */ jsx(Accordion$1.Item, {
|
|
15
15
|
"data-slot": "accordion-item",
|
|
16
|
-
className: cn("not-last:border-b
|
|
16
|
+
className: cn("not-last:border-b", className),
|
|
17
17
|
...props
|
|
18
18
|
});
|
|
19
19
|
}
|
|
@@ -22,7 +22,7 @@ function AccordionTrigger({ className, children, ...props }) {
|
|
|
22
22
|
className: "flex",
|
|
23
23
|
children: /* @__PURE__ */ jsxs(Accordion$1.Trigger, {
|
|
24
24
|
"data-slot": "accordion-trigger",
|
|
25
|
-
className: cn("group/accordion-trigger relative flex flex-1 items-start justify-between
|
|
25
|
+
className: cn("group/accordion-trigger relative flex flex-1 items-start justify-between rounded-lg border border-transparent py-2.5 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:after:border-ring aria-disabled:pointer-events-none aria-disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground", className),
|
|
26
26
|
...props,
|
|
27
27
|
children: [
|
|
28
28
|
children,
|
|
@@ -41,10 +41,10 @@ function AccordionTrigger({ className, children, ...props }) {
|
|
|
41
41
|
function AccordionContent({ className, children, ...props }) {
|
|
42
42
|
return /* @__PURE__ */ jsx(Accordion$1.Panel, {
|
|
43
43
|
"data-slot": "accordion-content",
|
|
44
|
-
className: "overflow-hidden
|
|
44
|
+
className: "overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up",
|
|
45
45
|
...props,
|
|
46
46
|
children: /* @__PURE__ */ jsx("div", {
|
|
47
|
-
className: cn("h-(--accordion-panel-height) pt-0 pb-
|
|
47
|
+
className: cn("h-(--accordion-panel-height) pt-0 pb-2.5 data-ending-style:h-0 data-starting-style:h-0 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4", className),
|
|
48
48
|
children
|
|
49
49
|
})
|
|
50
50
|
});
|
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import "react";
|
|
4
4
|
import { cva } from "class-variance-authority";
|
|
5
5
|
//#region src/components/ui/alert.tsx
|
|
6
|
-
const alertVariants = cva("group/alert relative grid w-full gap-0.5 rounded-
|
|
6
|
+
const alertVariants = cva("group/alert relative grid w-full gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4", {
|
|
7
7
|
variants: { variant: {
|
|
8
8
|
default: "bg-card text-card-foreground",
|
|
9
9
|
destructive: "bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current"
|
|
@@ -35,7 +35,7 @@ function AlertDescription({ className, ...props }) {
|
|
|
35
35
|
function AlertAction({ className, ...props }) {
|
|
36
36
|
return /* @__PURE__ */ jsx("div", {
|
|
37
37
|
"data-slot": "alert-action",
|
|
38
|
-
className: cn("absolute top-2
|
|
38
|
+
className: cn("absolute top-2 right-2", className),
|
|
39
39
|
...props
|
|
40
40
|
});
|
|
41
41
|
}
|
|
@@ -3,7 +3,7 @@ import { cva } from "class-variance-authority";
|
|
|
3
3
|
import { mergeProps } from "@base-ui/react/merge-props";
|
|
4
4
|
import { useRender } from "@base-ui/react/use-render";
|
|
5
5
|
//#region src/components/ui/badge.tsx
|
|
6
|
-
const badgeVariants = cva("group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-
|
|
6
|
+
const badgeVariants = cva("group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!", {
|
|
7
7
|
variants: { variant: {
|
|
8
8
|
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
|
|
9
9
|
secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
|
|
@@ -16,14 +16,14 @@ function Breadcrumb({ className, ...props }) {
|
|
|
16
16
|
function BreadcrumbList({ className, ...props }) {
|
|
17
17
|
return /* @__PURE__ */ jsx("ol", {
|
|
18
18
|
"data-slot": "breadcrumb-list",
|
|
19
|
-
className: cn("flex flex-wrap items-center gap-1.5 text-sm wrap-break-word text-muted-foreground
|
|
19
|
+
className: cn("flex flex-wrap items-center gap-1.5 text-sm wrap-break-word text-muted-foreground", className),
|
|
20
20
|
...props
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
function BreadcrumbItem({ className, ...props }) {
|
|
24
24
|
return /* @__PURE__ */ jsx("li", {
|
|
25
25
|
"data-slot": "breadcrumb-item",
|
|
26
|
-
className: cn("inline-flex items-center gap-1
|
|
26
|
+
className: cn("inline-flex items-center gap-1", className),
|
|
27
27
|
...props
|
|
28
28
|
});
|
|
29
29
|
}
|
|
@@ -3,25 +3,25 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
4
|
import { Button as Button$1 } from "@base-ui/react/button";
|
|
5
5
|
//#region src/components/ui/button.tsx
|
|
6
|
-
const buttonVariants = cva("group/button inline-flex shrink-0 items-center justify-center rounded-
|
|
6
|
+
const buttonVariants = cva("group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
7
7
|
variants: {
|
|
8
8
|
variant: {
|
|
9
9
|
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
10
|
-
outline: "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:bg-
|
|
10
|
+
outline: "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
|
|
11
11
|
secondary: "bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
12
12
|
ghost: "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
|
|
13
13
|
destructive: "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
|
|
14
14
|
link: "text-primary underline-offset-4 hover:underline"
|
|
15
15
|
},
|
|
16
16
|
size: {
|
|
17
|
-
default: "h-
|
|
18
|
-
xs: "h-6 gap-1 px-2
|
|
19
|
-
sm: "h-
|
|
20
|
-
lg: "h-
|
|
21
|
-
icon: "size-
|
|
22
|
-
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
23
|
-
"icon-sm": "size-
|
|
24
|
-
"icon-lg": "size-
|
|
17
|
+
default: "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
18
|
+
xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
19
|
+
sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
|
20
|
+
lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
21
|
+
icon: "size-8",
|
|
22
|
+
"icon-xs": "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
|
|
23
|
+
"icon-sm": "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
|
|
24
|
+
"icon-lg": "size-9"
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
defaultVariants: {
|
|
@@ -10,7 +10,7 @@ function Calendar({ className, classNames, showOutsideDays = true, captionLayout
|
|
|
10
10
|
const defaultClassNames = getDefaultClassNames();
|
|
11
11
|
return /* @__PURE__ */ jsx(DayPicker, {
|
|
12
12
|
showOutsideDays,
|
|
13
|
-
className: cn("group/calendar bg-background p-
|
|
13
|
+
className: cn("group/calendar bg-background p-2 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(7)] in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent", String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`, String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`, className),
|
|
14
14
|
captionLayout,
|
|
15
15
|
locale,
|
|
16
16
|
formatters: {
|
|
@@ -6,21 +6,21 @@ function Card({ className, size = "default", ...props }) {
|
|
|
6
6
|
return /* @__PURE__ */ jsx("div", {
|
|
7
7
|
"data-slot": "card",
|
|
8
8
|
"data-size": size,
|
|
9
|
-
className: cn("group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-
|
|
9
|
+
className: cn("group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl", className),
|
|
10
10
|
...props
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
function CardHeader({ className, ...props }) {
|
|
14
14
|
return /* @__PURE__ */ jsx("div", {
|
|
15
15
|
"data-slot": "card-header",
|
|
16
|
-
className: cn("group/card-header @container/card-header grid auto-rows-min items-start gap-1
|
|
16
|
+
className: cn("group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)", className),
|
|
17
17
|
...props
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
function CardTitle({ className, ...props }) {
|
|
21
21
|
return /* @__PURE__ */ jsx("div", {
|
|
22
22
|
"data-slot": "card-title",
|
|
23
|
-
className: cn("font-heading text-base font-medium", className),
|
|
23
|
+
className: cn("font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm", className),
|
|
24
24
|
...props
|
|
25
25
|
});
|
|
26
26
|
}
|
|
@@ -48,7 +48,7 @@ function CardContent({ className, ...props }) {
|
|
|
48
48
|
function CardFooter({ className, ...props }) {
|
|
49
49
|
return /* @__PURE__ */ jsx("div", {
|
|
50
50
|
"data-slot": "card-footer",
|
|
51
|
-
className: cn("flex items-center rounded-b-
|
|
51
|
+
className: cn("flex items-center rounded-b-xl border-t bg-muted/50 p-(--card-spacing)", className),
|
|
52
52
|
...props
|
|
53
53
|
});
|
|
54
54
|
}
|
|
@@ -79,7 +79,7 @@ function ChartTooltipContent({ active, payload, className, indicator = "dot", hi
|
|
|
79
79
|
if (!active || !payload?.length) return null;
|
|
80
80
|
const nestLabel = payload.length === 1 && indicator !== "dot";
|
|
81
81
|
return /* @__PURE__ */ jsxs("div", {
|
|
82
|
-
className: cn("grid min-w-32 items-start gap-1.5 rounded-
|
|
82
|
+
className: cn("grid min-w-32 items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl", className),
|
|
83
83
|
children: [!nestLabel ? tooltipLabel : null, /* @__PURE__ */ jsx("div", {
|
|
84
84
|
className: "grid gap-1.5",
|
|
85
85
|
children: payload.filter((item) => item.type !== "none").map((item, index) => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { Button } from "./button.js";
|
|
2
3
|
import { cn } from "cn";
|
|
3
4
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
@@ -5,10 +6,10 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
5
6
|
import * as React$1 from "react";
|
|
6
7
|
import { cva } from "class-variance-authority";
|
|
7
8
|
//#region src/components/ui/code-block.tsx
|
|
8
|
-
const codeBlockVariants = cva("group/code-block relative flex w-full min-w-0 flex-col overflow-hidden rounded-
|
|
9
|
+
const codeBlockVariants = cva("group/code-block relative flex w-full min-w-0 flex-col overflow-hidden rounded-lg text-sm has-[>[data-slot=code-block-content]:focus-visible]:ring-3 has-[>[data-slot=code-block-content]:focus-visible]:ring-ring/50 data-[size=sm]:text-xs", {
|
|
9
10
|
variants: { variant: {
|
|
10
|
-
default: "
|
|
11
|
-
destructive: "
|
|
11
|
+
default: "border border-input text-foreground has-[>[data-slot=code-block-content]:focus-visible]:border-ring dark:bg-input/30",
|
|
12
|
+
destructive: "border border-destructive/30 text-destructive dark:border-destructive/40"
|
|
12
13
|
} },
|
|
13
14
|
defaultVariants: { variant: "default" }
|
|
14
15
|
});
|
|
@@ -24,21 +25,21 @@ function CodeBlock({ className, variant = "default", size = "default", ...props
|
|
|
24
25
|
function CodeBlockHeader({ className, ...props }) {
|
|
25
26
|
return /* @__PURE__ */ jsx("div", {
|
|
26
27
|
"data-slot": "code-block-header",
|
|
27
|
-
className: cn("flex min-w-0 shrink-0 items-center gap-2 px-
|
|
28
|
+
className: cn("flex min-w-0 shrink-0 items-center gap-2 px-3 pt-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pt-2.5 group-data-[variant=destructive]/code-block:text-destructive *:has-[>[data-slot=code-block-title]]:min-w-0", className),
|
|
28
29
|
...props
|
|
29
30
|
});
|
|
30
31
|
}
|
|
31
32
|
function CodeBlockTitle({ className, ...props }) {
|
|
32
33
|
return /* @__PURE__ */ jsx("div", {
|
|
33
34
|
"data-slot": "code-block-title",
|
|
34
|
-
className: cn("min-w-0 truncate font-sans text-sm font-medium text-foreground group-data-[size=sm]/code-block:text-xs group-data-[variant=destructive]/code-block:text-destructive [&_svg]:pointer-events-none [&_svg]:inline-block [&_svg]:align-middle [&_svg:not([class*='size-'])]:size-
|
|
35
|
+
className: cn("min-w-0 truncate font-sans text-sm font-medium text-foreground group-data-[size=sm]/code-block:text-xs group-data-[variant=destructive]/code-block:text-destructive [&_svg]:pointer-events-none [&_svg]:inline-block [&_svg]:align-middle [&_svg:not([class*='size-'])]:size-3.5 *:[svg]:me-1.5", className),
|
|
35
36
|
...props
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
39
|
function CodeBlockActions({ className, ...props }) {
|
|
39
40
|
return /* @__PURE__ */ jsx("div", {
|
|
40
41
|
"data-slot": "code-block-actions",
|
|
41
|
-
className: cn("-my-1 ms-auto -me-1.5 flex shrink-0 items-center gap-1
|
|
42
|
+
className: cn("-my-1 ms-auto -me-1.5 flex shrink-0 items-center gap-1 [[data-slot=code-block]>&]:absolute [[data-slot=code-block]>&]:end-2 [[data-slot=code-block]>&]:top-2 [[data-slot=code-block]>&]:z-10 [[data-slot=code-block]>&]:m-0 [[data-slot=code-block]>&]:opacity-0 [[data-slot=code-block]>&]:transition-opacity [[data-slot=code-block]>&]:group-focus-within/code-block:opacity-100 [[data-slot=code-block]>&]:group-hover/code-block:opacity-100 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:end-1.5 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:top-1.5 [[data-slot=code-block]>&]:pointer-coarse:opacity-100 [[data-slot=code-block]>&]:*:[button]:bg-background [[data-slot=code-block]>&]:*:[button]:ring-1 [[data-slot=code-block]>&]:*:[button]:ring-foreground/10", className),
|
|
42
43
|
...props
|
|
43
44
|
});
|
|
44
45
|
}
|
|
@@ -55,7 +56,7 @@ function CodeBlockCopyButton({ value, variant = "ghost", size = "icon-xs", class
|
|
|
55
56
|
variant,
|
|
56
57
|
size,
|
|
57
58
|
"aria-label": copied ? "Copied" : "Copy",
|
|
58
|
-
className: cn(
|
|
59
|
+
className: cn(className),
|
|
59
60
|
onClick: (event) => {
|
|
60
61
|
onClick?.(event);
|
|
61
62
|
navigator.clipboard.writeText(value).then(() => setCopied(true)).catch(() => {});
|
|
@@ -79,7 +80,7 @@ function CodeBlockContent({ className, children, style, wrap = false, lineNumber
|
|
|
79
80
|
counterReset: `line ${startLine - 1}`,
|
|
80
81
|
...style
|
|
81
82
|
},
|
|
82
|
-
className: cn("min-h-0 min-w-0 scroll-fade-x scrollbar-thin overflow-auto px-
|
|
83
|
+
className: cn("min-h-0 min-w-0 scroll-fade-x scrollbar-thin overflow-auto px-3 py-3 text-start font-mono leading-relaxed outline-none group-has-data-[slot=code-block-footer]/code-block:pb-2 group-has-data-[slot=code-block-header]/code-block:pt-2 group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:py-2.5 group-data-[size=sm]/code-block:group-has-data-[slot=code-block-header]/code-block:pt-1.5 data-wrap:scroll-fade-y data-wrap:wrap-break-word data-wrap:whitespace-pre-wrap", className),
|
|
83
84
|
...props,
|
|
84
85
|
children: /* @__PURE__ */ jsx("code", {
|
|
85
86
|
"data-slot": "code-block-code",
|
|
@@ -88,12 +89,12 @@ function CodeBlockContent({ className, children, style, wrap = false, lineNumber
|
|
|
88
89
|
})
|
|
89
90
|
});
|
|
90
91
|
}
|
|
91
|
-
const codeBlockLineVariants = cva("relative -mx-
|
|
92
|
+
const codeBlockLineVariants = cva("relative -mx-3 block min-h-lh px-3 group-data-[size=sm]/code-block:-mx-2.5 group-data-[size=sm]/code-block:px-2.5 before:min-w-6 before:text-end before:text-muted-foreground after:absolute after:start-1 after:top-0 after:text-muted-foreground after:select-none in-data-numbered:col-span-2 in-data-numbered:grid in-data-numbered:grid-cols-subgrid in-data-numbered:gap-x-3 in-data-numbered:[counter-increment:line] in-data-numbered:before:content-[counter(line)] in-data-numbered:before:select-none in-data-numbered:supports-[content:counter(line)_/_'']:before:content-[counter(line)_/_'']", {
|
|
92
93
|
variants: { variant: {
|
|
93
94
|
default: "",
|
|
94
|
-
added: "bg-
|
|
95
|
+
added: "bg-muted after:content-['+']",
|
|
95
96
|
removed: "bg-destructive/10 after:text-destructive after:content-['−']",
|
|
96
|
-
highlighted: "bg-
|
|
97
|
+
highlighted: "bg-muted"
|
|
97
98
|
} },
|
|
98
99
|
defaultVariants: { variant: "default" }
|
|
99
100
|
});
|
|
@@ -114,7 +115,7 @@ function CodeBlockLine({ className, variant = "default", children, ...props }) {
|
|
|
114
115
|
function CodeBlockFooter({ className, ...props }) {
|
|
115
116
|
return /* @__PURE__ */ jsx("div", {
|
|
116
117
|
"data-slot": "code-block-footer",
|
|
117
|
-
className: cn("flex min-w-0 shrink-0 items-center gap-2 px-
|
|
118
|
+
className: cn("flex min-w-0 shrink-0 items-center gap-2 px-3 pb-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pb-2.5", className),
|
|
118
119
|
...props
|
|
119
120
|
});
|
|
120
121
|
}
|