@customafk/lunas-ui 0.2.61 → 0.2.63
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/dist/{cms-layout-BeU_CkJl.mjs → cms-layout-CuF5ahpj.mjs} +2 -2
- package/dist/{cms-layout-BeU_CkJl.mjs.map → cms-layout-CuF5ahpj.mjs.map} +1 -1
- package/dist/{cms-layout-hLiQbkXR.cjs → cms-layout-SubgSF72.cjs} +2 -2
- package/dist/{cms-layout-hLiQbkXR.cjs.map → cms-layout-SubgSF72.cjs.map} +1 -1
- package/dist/features/charts/index.cjs +2 -0
- package/dist/features/charts/index.cjs.map +1 -0
- package/dist/features/charts/index.d.cts +349 -0
- package/dist/features/charts/index.d.mts +349 -0
- package/dist/features/charts/index.mjs +2 -0
- package/dist/features/charts/index.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +4 -2
- package/dist/index.d.mts +4 -2
- package/dist/index.mjs +1 -1
- package/dist/layouts/cms-layout/index.cjs +1 -1
- package/dist/layouts/cms-layout/index.mjs +1 -1
- package/dist/{resizable-CFCYn9e_.d.cts → resizable-BLfxHCf4.d.cts} +2 -2
- package/dist/{resizable-CFCYn9e_.d.mts → resizable-BLfxHCf4.d.mts} +2 -2
- package/dist/ui/chart.cjs +4 -0
- package/dist/ui/chart.cjs.map +1 -0
- package/dist/ui/chart.d.cts +80 -0
- package/dist/ui/chart.d.mts +80 -0
- package/dist/ui/chart.mjs +4 -0
- package/dist/ui/chart.mjs.map +1 -0
- package/dist/ui/resizable.d.cts +1 -1
- package/dist/ui/resizable.d.mts +1 -1
- package/package.json +11 -1
- package/styles/theme.css +8 -5
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { LegendPayload, ResponsiveContainer, Tooltip, TooltipContentProps } from "recharts";
|
|
2
|
+
|
|
3
|
+
//#region packages/components/ui/chart.d.ts
|
|
4
|
+
declare const THEMES: {
|
|
5
|
+
readonly light: "";
|
|
6
|
+
readonly dark: ".dark";
|
|
7
|
+
};
|
|
8
|
+
type ChartConfig = { [k in string]: {
|
|
9
|
+
label?: React.ReactNode;
|
|
10
|
+
icon?: React.ComponentType;
|
|
11
|
+
} & ({
|
|
12
|
+
color?: string;
|
|
13
|
+
theme?: never;
|
|
14
|
+
} | {
|
|
15
|
+
color?: never;
|
|
16
|
+
theme: Record<keyof typeof THEMES, string>;
|
|
17
|
+
}) };
|
|
18
|
+
type ChartContextProps = {
|
|
19
|
+
config: ChartConfig;
|
|
20
|
+
};
|
|
21
|
+
declare const useChart: () => ChartContextProps;
|
|
22
|
+
type ChartContainerProps = React.ComponentProps<'div'> & {
|
|
23
|
+
config: ChartConfig;
|
|
24
|
+
children: React.ComponentProps<typeof ResponsiveContainer>['children'];
|
|
25
|
+
};
|
|
26
|
+
declare const ChartContainer: ({
|
|
27
|
+
id,
|
|
28
|
+
className,
|
|
29
|
+
children,
|
|
30
|
+
config,
|
|
31
|
+
...props
|
|
32
|
+
}: ChartContainerProps) => import("react").JSX.Element;
|
|
33
|
+
declare const ChartStyle: ({
|
|
34
|
+
id,
|
|
35
|
+
config
|
|
36
|
+
}: {
|
|
37
|
+
id: string;
|
|
38
|
+
config: ChartConfig;
|
|
39
|
+
}) => import("react").JSX.Element | null;
|
|
40
|
+
declare const ChartTooltip: typeof Tooltip;
|
|
41
|
+
type ChartTooltipContentProps = React.ComponentProps<'div'> & Partial<Pick<TooltipContentProps<number | string, string>, 'active' | 'payload' | 'label' | 'labelFormatter' | 'formatter'>> & {
|
|
42
|
+
hideLabel?: boolean;
|
|
43
|
+
hideIndicator?: boolean;
|
|
44
|
+
indicator?: 'line' | 'dot' | 'dashed';
|
|
45
|
+
nameKey?: string;
|
|
46
|
+
labelKey?: string;
|
|
47
|
+
labelClassName?: string;
|
|
48
|
+
};
|
|
49
|
+
declare const ChartTooltipContent: ({
|
|
50
|
+
active,
|
|
51
|
+
payload,
|
|
52
|
+
className,
|
|
53
|
+
indicator,
|
|
54
|
+
hideLabel,
|
|
55
|
+
hideIndicator,
|
|
56
|
+
label,
|
|
57
|
+
labelFormatter,
|
|
58
|
+
labelClassName,
|
|
59
|
+
formatter,
|
|
60
|
+
color,
|
|
61
|
+
nameKey,
|
|
62
|
+
labelKey
|
|
63
|
+
}: ChartTooltipContentProps) => import("react").JSX.Element | null;
|
|
64
|
+
declare const ChartLegend: import("react").MemoExoticComponent<(outsideProps: import("recharts").LegendProps) => React.ReactPortal | null>;
|
|
65
|
+
type ChartLegendContentProps = React.ComponentProps<'div'> & {
|
|
66
|
+
payload?: readonly LegendPayload[];
|
|
67
|
+
verticalAlign?: 'top' | 'bottom' | 'middle';
|
|
68
|
+
hideIcon?: boolean;
|
|
69
|
+
nameKey?: string;
|
|
70
|
+
};
|
|
71
|
+
declare const ChartLegendContent: ({
|
|
72
|
+
className,
|
|
73
|
+
hideIcon,
|
|
74
|
+
payload,
|
|
75
|
+
verticalAlign,
|
|
76
|
+
nameKey
|
|
77
|
+
}: ChartLegendContentProps) => import("react").JSX.Element | null;
|
|
78
|
+
//#endregion
|
|
79
|
+
export { ChartConfig, ChartContainer, ChartContainerProps, ChartLegend, ChartLegendContent, ChartLegendContentProps, ChartStyle, ChartTooltip, ChartTooltipContent, ChartTooltipContentProps, useChart };
|
|
80
|
+
//# sourceMappingURL=chart.d.cts.map
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { LegendPayload, ResponsiveContainer, Tooltip, TooltipContentProps } from "recharts";
|
|
2
|
+
|
|
3
|
+
//#region packages/components/ui/chart.d.ts
|
|
4
|
+
declare const THEMES: {
|
|
5
|
+
readonly light: "";
|
|
6
|
+
readonly dark: ".dark";
|
|
7
|
+
};
|
|
8
|
+
type ChartConfig = { [k in string]: {
|
|
9
|
+
label?: React.ReactNode;
|
|
10
|
+
icon?: React.ComponentType;
|
|
11
|
+
} & ({
|
|
12
|
+
color?: string;
|
|
13
|
+
theme?: never;
|
|
14
|
+
} | {
|
|
15
|
+
color?: never;
|
|
16
|
+
theme: Record<keyof typeof THEMES, string>;
|
|
17
|
+
}) };
|
|
18
|
+
type ChartContextProps = {
|
|
19
|
+
config: ChartConfig;
|
|
20
|
+
};
|
|
21
|
+
declare const useChart: () => ChartContextProps;
|
|
22
|
+
type ChartContainerProps = React.ComponentProps<'div'> & {
|
|
23
|
+
config: ChartConfig;
|
|
24
|
+
children: React.ComponentProps<typeof ResponsiveContainer>['children'];
|
|
25
|
+
};
|
|
26
|
+
declare const ChartContainer: ({
|
|
27
|
+
id,
|
|
28
|
+
className,
|
|
29
|
+
children,
|
|
30
|
+
config,
|
|
31
|
+
...props
|
|
32
|
+
}: ChartContainerProps) => import("react").JSX.Element;
|
|
33
|
+
declare const ChartStyle: ({
|
|
34
|
+
id,
|
|
35
|
+
config
|
|
36
|
+
}: {
|
|
37
|
+
id: string;
|
|
38
|
+
config: ChartConfig;
|
|
39
|
+
}) => import("react").JSX.Element | null;
|
|
40
|
+
declare const ChartTooltip: typeof Tooltip;
|
|
41
|
+
type ChartTooltipContentProps = React.ComponentProps<'div'> & Partial<Pick<TooltipContentProps<number | string, string>, 'active' | 'payload' | 'label' | 'labelFormatter' | 'formatter'>> & {
|
|
42
|
+
hideLabel?: boolean;
|
|
43
|
+
hideIndicator?: boolean;
|
|
44
|
+
indicator?: 'line' | 'dot' | 'dashed';
|
|
45
|
+
nameKey?: string;
|
|
46
|
+
labelKey?: string;
|
|
47
|
+
labelClassName?: string;
|
|
48
|
+
};
|
|
49
|
+
declare const ChartTooltipContent: ({
|
|
50
|
+
active,
|
|
51
|
+
payload,
|
|
52
|
+
className,
|
|
53
|
+
indicator,
|
|
54
|
+
hideLabel,
|
|
55
|
+
hideIndicator,
|
|
56
|
+
label,
|
|
57
|
+
labelFormatter,
|
|
58
|
+
labelClassName,
|
|
59
|
+
formatter,
|
|
60
|
+
color,
|
|
61
|
+
nameKey,
|
|
62
|
+
labelKey
|
|
63
|
+
}: ChartTooltipContentProps) => import("react").JSX.Element | null;
|
|
64
|
+
declare const ChartLegend: import("react").MemoExoticComponent<(outsideProps: import("recharts").LegendProps) => React.ReactPortal | null>;
|
|
65
|
+
type ChartLegendContentProps = React.ComponentProps<'div'> & {
|
|
66
|
+
payload?: readonly LegendPayload[];
|
|
67
|
+
verticalAlign?: 'top' | 'bottom' | 'middle';
|
|
68
|
+
hideIcon?: boolean;
|
|
69
|
+
nameKey?: string;
|
|
70
|
+
};
|
|
71
|
+
declare const ChartLegendContent: ({
|
|
72
|
+
className,
|
|
73
|
+
hideIcon,
|
|
74
|
+
payload,
|
|
75
|
+
verticalAlign,
|
|
76
|
+
nameKey
|
|
77
|
+
}: ChartLegendContentProps) => import("react").JSX.Element | null;
|
|
78
|
+
//#endregion
|
|
79
|
+
export { ChartConfig, ChartContainer, ChartContainerProps, ChartLegend, ChartLegendContent, ChartLegendContentProps, ChartStyle, ChartTooltip, ChartTooltipContent, ChartTooltipContentProps, useChart };
|
|
80
|
+
//# sourceMappingURL=chart.d.mts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use client";import{createContext as e,useContext as t,useId as n,useMemo as r}from"react";import{cn as i}from"@customafk/react-toolkit/utils";import{Fragment as a,jsx as o,jsxs as s}from"react/jsx-runtime";import{Legend as c,ResponsiveContainer as l,Tooltip as u}from"recharts";const d={light:``,dark:`.dark`},f=e(null),p=()=>{let e=t(f);if(!e)throw Error(`useChart must be used within a <ChartContainer />`);return e},m=({id:e,className:t,children:r,config:a,...c})=>{let u=n(),d=`chart-${e||u.replace(/:/g,``)}`;return o(f.Provider,{value:{config:a},children:s(`div`,{"data-slot":`chart`,"data-chart":d,className:i(`flex aspect-video justify-center text-xs`,`[&_.recharts-cartesian-axis-tick_text]:fill-muted`,`[&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50`,`[&_.recharts-curve.recharts-tooltip-cursor]:stroke-border`,`[&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border`,`[&_.recharts-radial-bar-background-sector]:fill-muted-muted`,`[&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted-muted`,`[&_.recharts-reference-line_[stroke='#ccc']]:stroke-border`,`[&_.recharts-dot[stroke='#fff']]:stroke-transparent`,`[&_.recharts-layer]:outline-hidden`,`[&_.recharts-sector]:outline-hidden`,`[&_.recharts-sector[stroke='#fff']]:stroke-transparent`,`[&_.recharts-surface]:outline-hidden`,t),...c,children:[o(_,{id:d,config:a}),o(l,{children:r})]})})},h=/^[a-zA-Z0-9#(),.%\s/_-]+$/,g=/^[a-zA-Z0-9_-]+$/,_=({id:e,config:t})=>{let n=Object.entries(t).filter(([e,t])=>(t.theme||t.color)&&g.test(e));return n.length?o(`style`,{dangerouslySetInnerHTML:{__html:Object.entries(d).map(([t,r])=>`${r} [data-chart=${e}] {\n${n.map(([e,n])=>{let r=n.theme?.[t]||n.color;return!r||!h.test(r)?null:` --color-${e}: ${r};`}).filter(Boolean).join(`
|
|
2
|
+
`)}\n}`).join(`
|
|
3
|
+
`)}}):null},v=u,y=({active:e,payload:t,className:n,indicator:c=`dot`,hideLabel:l=!1,hideIndicator:u=!1,label:d,labelFormatter:f,labelClassName:m,formatter:h,color:g,nameKey:_,labelKey:v})=>{let{config:y}=p(),b=r(()=>{if(l||!t?.length)return null;let[e]=t,n=S(y,e,`${v||e?.dataKey||e?.name||`value`}`),r=!v&&typeof d==`string`?y[d]?.label||d:n?.label;return f?o(`div`,{className:i(`font-medium`,m),children:f(r,t)}):r?o(`div`,{className:i(`font-medium`,m),children:r}):null},[d,f,t,l,m,y,v]);if(!e||!t?.length)return null;let x=t.length===1&&c!==`dot`;return s(`div`,{"data-slot":`chart-tooltip-content`,className:i(`border-border/50 bg-background grid min-w-[8rem] items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-dropdown`,n),children:[x?null:b,o(`div`,{className:`grid gap-1.5`,children:t.map((e,t)=>{let n=S(y,e,`${_||e.name||e.dataKey||`value`}`),r=g||e.payload?.fill||e.color;return o(`div`,{className:i(`flex w-full flex-wrap items-stretch gap-2`,`[&>svg]:text-muted [&>svg]:size-2.5`,c===`dot`&&`items-center`),children:h&&e?.value!==void 0&&e.name?h(e.value,String(e.name),e,t,e.payload):s(a,{children:[n?.icon?o(n.icon,{}):!u&&o(`div`,{className:i(`shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)`,{"size-2.5":c===`dot`,"w-1":c===`line`,"w-0 border-[1.5px] border-dashed bg-transparent":c===`dashed`,"my-0.5":x&&c===`dashed`}),style:{"--color-bg":r,"--color-border":r}}),s(`div`,{className:i(`flex flex-1 justify-between gap-2 leading-none`,x?`items-end`:`items-center`),children:[s(`div`,{className:`grid gap-1.5`,children:[x?b:null,o(`span`,{className:`text-muted`,children:n?.label||e.name})]}),e.value!==void 0&&o(`span`,{className:`text-text-positive-strong font-number font-medium tabular-nums`,children:typeof e.value==`number`?e.value.toLocaleString():e.value})]})]})},typeof e.dataKey==`function`?t:e.dataKey??t)})})]})},b=c,x=({className:e,hideIcon:t=!1,payload:n,verticalAlign:r=`bottom`,nameKey:a})=>{let{config:c}=p();return n?.length?o(`div`,{"data-slot":`chart-legend-content`,className:i(`flex items-center justify-center gap-4`,r===`top`?`pb-3`:`pt-3`,e),children:n.map(e=>{let n=S(c,e,`${a||e.dataKey||`value`}`);return s(`div`,{className:i(`flex items-center gap-1.5`,`[&>svg]:text-muted [&>svg]:size-3`),children:[n?.icon&&!t?o(n.icon,{}):o(`div`,{className:`size-2 shrink-0 rounded-[2px]`,style:{backgroundColor:e.color}}),o(`span`,{className:`text-muted-strong`,children:n?.label??e.value})]},`${e.value}`)})}):null},S=(e,t,n)=>{if(typeof t!=`object`||!t)return;let r=`payload`in t&&typeof t.payload==`object`&&t.payload!==null?t.payload:void 0,i=n,a=t;return n in a&&typeof a[n]==`string`?i=a[n]:r&&n in r&&typeof r[n]==`string`&&(i=r[n]),i in e?e[i]:e[n]};export{m as ChartContainer,b as ChartLegend,x as ChartLegendContent,_ as ChartStyle,v as ChartTooltip,y as ChartTooltipContent,p as useChart};
|
|
4
|
+
//# sourceMappingURL=chart.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart.mjs","names":[],"sources":["../../packages/components/ui/chart.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, useContext, useId, useMemo } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport type { LegendPayload, TooltipContentProps } from 'recharts';\nimport { Legend, ResponsiveContainer, Tooltip } from 'recharts';\n\nconst THEMES = { light: '', dark: '.dark' } as const;\n\nexport type ChartConfig = {\n [k in string]: {\n label?: React.ReactNode;\n icon?: React.ComponentType;\n } & ({ color?: string; theme?: never } | { color?: never; theme: Record<keyof typeof THEMES, string> });\n};\n\ntype ChartContextProps = {\n config: ChartConfig;\n};\n\nconst ChartContext = createContext<ChartContextProps | null>(null);\n\nexport const useChart = () => {\n const context = useContext(ChartContext);\n if (!context) {\n throw new Error('useChart must be used within a <ChartContainer />');\n }\n return context;\n};\n\nexport type ChartContainerProps = React.ComponentProps<'div'> & {\n config: ChartConfig;\n children: React.ComponentProps<typeof ResponsiveContainer>['children'];\n};\n\nexport const ChartContainer = ({ id, className, children, config, ...props }: ChartContainerProps) => {\n const uniqueId = useId();\n const chartId = `chart-${id || uniqueId.replace(/:/g, '')}`;\n\n return (\n <ChartContext.Provider value={{ config }}>\n <div\n data-slot=\"chart\"\n data-chart={chartId}\n className={cn(\n 'flex aspect-video justify-center text-xs',\n '[&_.recharts-cartesian-axis-tick_text]:fill-muted',\n \"[&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50\",\n '[&_.recharts-curve.recharts-tooltip-cursor]:stroke-border',\n \"[&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border\",\n '[&_.recharts-radial-bar-background-sector]:fill-muted-muted',\n '[&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted-muted',\n \"[&_.recharts-reference-line_[stroke='#ccc']]:stroke-border\",\n \"[&_.recharts-dot[stroke='#fff']]:stroke-transparent\",\n '[&_.recharts-layer]:outline-hidden',\n '[&_.recharts-sector]:outline-hidden',\n \"[&_.recharts-sector[stroke='#fff']]:stroke-transparent\",\n '[&_.recharts-surface]:outline-hidden',\n className\n )}\n {...props}\n >\n <ChartStyle id={chartId} config={config} />\n <ResponsiveContainer>{children}</ResponsiveContainer>\n </div>\n </ChartContext.Provider>\n );\n};\n\n/** Accepts CSS color notations (hex, rgb/hsl/oklch, var(...)) while rejecting CSS injection. */\nconst SAFE_CSS_COLOR_PATTERN = /^[a-zA-Z0-9#(),.%\\s/_-]+$/;\nconst SAFE_CSS_KEY_PATTERN = /^[a-zA-Z0-9_-]+$/;\n\nexport const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n const colorConfig = Object.entries(config).filter(([key, itemConfig]) => (itemConfig.theme || itemConfig.color) && SAFE_CSS_KEY_PATTERN.test(key));\n\n if (!colorConfig.length) return null;\n\n const css = Object.entries(THEMES)\n .map(([theme, prefix]) => {\n const rules = colorConfig\n .map(([key, itemConfig]) => {\n const color = itemConfig.theme?.[theme as keyof typeof THEMES] || itemConfig.color;\n if (!color || !SAFE_CSS_COLOR_PATTERN.test(color)) return null;\n return ` --color-${key}: ${color};`;\n })\n .filter(Boolean)\n .join('\\n');\n return `${prefix} [data-chart=${id}] {\\n${rules}\\n}`;\n })\n .join('\\n');\n\n // biome-ignore lint/security/noDangerouslySetInnerHtml: values are sanitized against SAFE_CSS_* patterns above\n return <style dangerouslySetInnerHTML={{ __html: css }} />;\n};\n\nexport const ChartTooltip = Tooltip;\n\ntype TooltipItemPayload = NonNullable<TooltipContentProps<number | string, string>['payload']>[number];\n\nexport type ChartTooltipContentProps = React.ComponentProps<'div'> &\n Partial<Pick<TooltipContentProps<number | string, string>, 'active' | 'payload' | 'label' | 'labelFormatter' | 'formatter'>> & {\n hideLabel?: boolean;\n hideIndicator?: boolean;\n indicator?: 'line' | 'dot' | 'dashed';\n nameKey?: string;\n labelKey?: string;\n labelClassName?: string;\n };\n\nexport const ChartTooltipContent = ({\n active,\n payload,\n className,\n indicator = 'dot',\n hideLabel = false,\n hideIndicator = false,\n label,\n labelFormatter,\n labelClassName,\n formatter,\n color,\n nameKey,\n labelKey,\n}: ChartTooltipContentProps) => {\n const { config } = useChart();\n\n const tooltipLabel = useMemo(() => {\n if (hideLabel || !payload?.length) return null;\n\n const [item] = payload;\n const key = `${labelKey || item?.dataKey || item?.name || 'value'}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const value = !labelKey && typeof label === 'string' ? config[label as keyof typeof config]?.label || label : itemConfig?.label;\n\n if (labelFormatter) {\n return <div className={cn('font-medium', labelClassName)}>{labelFormatter(value, payload)}</div>;\n }\n if (!value) return null;\n return <div className={cn('font-medium', labelClassName)}>{value}</div>;\n }, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);\n\n if (!active || !payload?.length) return null;\n\n const nestLabel = payload.length === 1 && indicator !== 'dot';\n\n return (\n <div\n data-slot=\"chart-tooltip-content\"\n className={cn('border-border/50 bg-background grid min-w-[8rem] items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-dropdown', className)}\n >\n {!nestLabel ? tooltipLabel : null}\n <div className=\"grid gap-1.5\">\n {payload.map((item, index) => {\n const key = `${nameKey || item.name || item.dataKey || 'value'}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const indicatorColor = color || item.payload?.fill || item.color;\n\n return (\n <div\n key={typeof item.dataKey === 'function' ? index : (item.dataKey ?? index)}\n className={cn('flex w-full flex-wrap items-stretch gap-2', '[&>svg]:text-muted [&>svg]:size-2.5', indicator === 'dot' && 'items-center')}\n >\n {formatter && item?.value !== undefined && item.name ? (\n formatter(item.value as number | string, String(item.name), item, index, item.payload)\n ) : (\n <>\n {itemConfig?.icon ? (\n <itemConfig.icon />\n ) : (\n !hideIndicator && (\n <div\n className={cn('shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)', {\n 'size-2.5': indicator === 'dot',\n 'w-1': indicator === 'line',\n 'w-0 border-[1.5px] border-dashed bg-transparent': indicator === 'dashed',\n 'my-0.5': nestLabel && indicator === 'dashed',\n })}\n style={\n {\n '--color-bg': indicatorColor,\n '--color-border': indicatorColor,\n } as React.CSSProperties\n }\n />\n )\n )}\n <div className={cn('flex flex-1 justify-between gap-2 leading-none', nestLabel ? 'items-end' : 'items-center')}>\n <div className=\"grid gap-1.5\">\n {nestLabel ? tooltipLabel : null}\n <span className=\"text-muted\">{itemConfig?.label || item.name}</span>\n </div>\n {item.value !== undefined && (\n <span className=\"text-text-positive-strong font-number font-medium tabular-nums\">\n {typeof item.value === 'number' ? item.value.toLocaleString() : item.value}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n};\n\nexport const ChartLegend = Legend;\n\nexport type ChartLegendContentProps = React.ComponentProps<'div'> & {\n payload?: readonly LegendPayload[];\n verticalAlign?: 'top' | 'bottom' | 'middle';\n hideIcon?: boolean;\n nameKey?: string;\n};\n\nexport const ChartLegendContent = ({ className, hideIcon = false, payload, verticalAlign = 'bottom', nameKey }: ChartLegendContentProps) => {\n const { config } = useChart();\n\n if (!payload?.length) return null;\n\n return (\n <div data-slot=\"chart-legend-content\" className={cn('flex items-center justify-center gap-4', verticalAlign === 'top' ? 'pb-3' : 'pt-3', className)}>\n {payload.map(item => {\n const key = `${nameKey || item.dataKey || 'value'}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n\n return (\n <div key={`${item.value}`} className={cn('flex items-center gap-1.5', '[&>svg]:text-muted [&>svg]:size-3')}>\n {itemConfig?.icon && !hideIcon ? <itemConfig.icon /> : <div className=\"size-2 shrink-0 rounded-[2px]\" style={{ backgroundColor: item.color }} />}\n <span className=\"text-muted-strong\">{itemConfig?.label ?? item.value}</span>\n </div>\n );\n })}\n </div>\n );\n};\n\nconst getPayloadConfigFromPayload = (config: ChartConfig, payload: TooltipItemPayload | LegendPayload | undefined, key: string) => {\n if (typeof payload !== 'object' || payload === null) return undefined;\n\n const payloadPayload =\n 'payload' in payload && typeof payload.payload === 'object' && payload.payload !== null ? (payload.payload as Record<string, unknown>) : undefined;\n\n let configLabelKey: string = key;\n\n const record = payload as unknown as Record<string, unknown>;\n if (key in record && typeof record[key] === 'string') {\n configLabelKey = record[key] as string;\n } else if (payloadPayload && key in payloadPayload && typeof payloadPayload[key] === 'string') {\n configLabelKey = payloadPayload[key] as string;\n }\n\n return configLabelKey in config ? config[configLabelKey] : config[key];\n};\n"],"mappings":"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"}
|
package/dist/ui/resizable.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as ResizablePanel, r as ResizablePanelGroup, t as ResizableHandle } from "../resizable-
|
|
1
|
+
import { n as ResizablePanel, r as ResizablePanelGroup, t as ResizableHandle } from "../resizable-BLfxHCf4.cjs";
|
|
2
2
|
export { ResizableHandle, ResizablePanel, ResizablePanelGroup };
|
package/dist/ui/resizable.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as ResizablePanel, r as ResizablePanelGroup, t as ResizableHandle } from "../resizable-
|
|
1
|
+
import { n as ResizablePanel, r as ResizablePanelGroup, t as ResizableHandle } from "../resizable-BLfxHCf4.mjs";
|
|
2
2
|
export { ResizableHandle, ResizablePanel, ResizablePanelGroup };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@customafk/lunas-ui",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.63",
|
|
4
4
|
"description": "UI library for Lunas Enterprise",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": {
|
|
@@ -104,6 +104,10 @@
|
|
|
104
104
|
"require": "./dist/dialogs/loading-dialog.cjs",
|
|
105
105
|
"import": "./dist/dialogs/loading-dialog.mjs"
|
|
106
106
|
},
|
|
107
|
+
"./features/charts": {
|
|
108
|
+
"require": "./dist/features/charts/index.cjs",
|
|
109
|
+
"import": "./dist/features/charts/index.mjs"
|
|
110
|
+
},
|
|
107
111
|
"./features/descriptions": {
|
|
108
112
|
"require": "./dist/features/descriptions/index.cjs",
|
|
109
113
|
"import": "./dist/features/descriptions/index.mjs"
|
|
@@ -248,6 +252,10 @@
|
|
|
248
252
|
"require": "./dist/ui/carousel.cjs",
|
|
249
253
|
"import": "./dist/ui/carousel.mjs"
|
|
250
254
|
},
|
|
255
|
+
"./ui/chart": {
|
|
256
|
+
"require": "./dist/ui/chart.cjs",
|
|
257
|
+
"import": "./dist/ui/chart.mjs"
|
|
258
|
+
},
|
|
251
259
|
"./ui/checkbox": {
|
|
252
260
|
"require": "./dist/ui/checkbox.cjs",
|
|
253
261
|
"import": "./dist/ui/checkbox.mjs"
|
|
@@ -475,6 +483,7 @@
|
|
|
475
483
|
"react-dropzone": "^14.3.0",
|
|
476
484
|
"react-hook-form": "^7.62.0",
|
|
477
485
|
"react-resizable-panels": "^3.0.0",
|
|
486
|
+
"recharts": "^3.9.1",
|
|
478
487
|
"sonner": "^2.0.5",
|
|
479
488
|
"tailwind-merge": "^3.3.0",
|
|
480
489
|
"tailwindcss": "^4.1.0",
|
|
@@ -504,6 +513,7 @@
|
|
|
504
513
|
"@vitest/coverage-v8": "^4.1.9",
|
|
505
514
|
"jsdom": "^26.1.0",
|
|
506
515
|
"playwright": "^1.61.0",
|
|
516
|
+
"recharts": "^3.9.1",
|
|
507
517
|
"tsdown": "^0.22.3",
|
|
508
518
|
"typescript": "^5.8.3",
|
|
509
519
|
"typescript-eslint": "^8.30.1",
|
package/styles/theme.css
CHANGED
|
@@ -106,11 +106,14 @@
|
|
|
106
106
|
--input: oklch(0.871 0.006 286.286); /* --color-zinc-300 */
|
|
107
107
|
--ring: oklch(0.81 0.1 294); /* --color-violet-300 */
|
|
108
108
|
|
|
109
|
-
--chart-1: oklch(0.
|
|
110
|
-
--chart-2: oklch(0.
|
|
111
|
-
--chart-3: oklch(0.
|
|
112
|
-
--chart-4: oklch(0.
|
|
113
|
-
--chart-5: oklch(0.
|
|
109
|
+
--chart-1: oklch(0.61 0.22 293); /* violet — matches --primary */
|
|
110
|
+
--chart-2: oklch(0.62 0.19 260); /* blue — matches --info */
|
|
111
|
+
--chart-3: oklch(0.72 0.19 150); /* green — matches --success */
|
|
112
|
+
--chart-4: oklch(0.78 0.16 75); /* amber */
|
|
113
|
+
--chart-5: oklch(0.64 0.21 25); /* red */
|
|
114
|
+
--chart-6: oklch(0.7 0.14 195); /* teal */
|
|
115
|
+
--chart-7: oklch(0.66 0.2 330); /* fuchsia */
|
|
116
|
+
--chart-8: oklch(0.55 0.04 285); /* muted slate-violet */
|
|
114
117
|
|
|
115
118
|
--sidebar: oklch(0.97 0 286); /* --color-zinc-100 */
|
|
116
119
|
--sidebar-foreground: oklch(0.28 0.04 260.03);
|