@arolariu/components 0.4.0 → 0.4.1
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/changelog.md +4 -0
- package/dist/components/ui/chart.d.ts +19 -41
- package/dist/components/ui/chart.d.ts.map +1 -1
- package/dist/components/ui/chart.js +34 -35
- package/dist/components/ui/chart.js.map +1 -1
- package/dist/components/ui/collapsible.d.ts +1 -2
- package/dist/components/ui/collapsible.d.ts.map +1 -1
- package/dist/components/ui/collapsible.js +30 -2
- package/dist/components/ui/collapsible.js.map +1 -1
- package/dist/components/ui/input-otp.d.ts +2 -2
- package/dist/components/ui/sheet.d.ts +1 -1
- package/dist/index.css +32 -26
- package/dist/index.css.map +1 -1
- package/package.json +1 -1
- package/src/components/ui/chart.tsx +162 -161
- package/src/components/ui/collapsible.tsx +1 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arolariu/components",
|
|
3
3
|
"displayName": "@arolariu/components",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.1",
|
|
5
5
|
"description": "🎨 70+ beautiful, accessible React components built on Radix UI. TypeScript-first, tree-shakeable, SSR-ready. Perfect for modern web apps, design systems & rapid prototyping. Zero config, maximum flexibility! ⚡",
|
|
6
6
|
"homepage": "https://arolariu.ro",
|
|
7
7
|
"repository": {
|
|
@@ -2,24 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
/* eslint-disable */
|
|
4
4
|
|
|
5
|
+
import {cn} from "@/lib/utilities";
|
|
5
6
|
import * as React from "react";
|
|
6
7
|
import * as RechartsPrimitive from "recharts";
|
|
7
|
-
|
|
8
|
-
import {cn} from "@/lib/utilities";
|
|
8
|
+
import type {NameType, ValueType} from "recharts/types/component/DefaultTooltipContent";
|
|
9
9
|
|
|
10
10
|
// Format: { THEME_NAME: CSS_SELECTOR }
|
|
11
11
|
const THEMES = {light: "", dark: ".dark"} as const;
|
|
12
12
|
|
|
13
|
-
export type ChartConfig =
|
|
14
|
-
|
|
13
|
+
export type ChartConfig = Record<
|
|
14
|
+
string,
|
|
15
|
+
{
|
|
15
16
|
label?: React.ReactNode;
|
|
16
17
|
icon?: React.ComponentType;
|
|
17
|
-
} & ({color?: string; theme?: never} | {color?: never; theme: Record<keyof typeof THEMES, string>})
|
|
18
|
-
|
|
18
|
+
} & ({color?: string; theme?: never} | {color?: never; theme: Record<keyof typeof THEMES, string>})
|
|
19
|
+
>;
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
interface ChartContextProps {
|
|
21
22
|
config: ChartConfig;
|
|
22
|
-
}
|
|
23
|
+
}
|
|
23
24
|
|
|
24
25
|
const ChartContext = React.createContext<ChartContextProps | null>(null);
|
|
25
26
|
|
|
@@ -33,23 +34,35 @@ function useChart() {
|
|
|
33
34
|
return context;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
>
|
|
37
|
+
interface ChartContainerProps
|
|
38
|
+
extends
|
|
39
|
+
Omit<React.ComponentProps<"div">, "children">,
|
|
40
|
+
Pick<
|
|
41
|
+
React.ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>,
|
|
42
|
+
"initialDimension" | "aspect" | "debounce" | "minHeight" | "minWidth" | "maxHeight" | "height" | "width" | "onResize" | "children"
|
|
43
|
+
> {
|
|
44
|
+
config: ChartConfig;
|
|
45
|
+
innerResponsiveContainerStyle?: React.ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>["style"];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function ChartContainer({
|
|
49
|
+
id,
|
|
50
|
+
config,
|
|
51
|
+
initialDimension = {width: 320, height: 200},
|
|
52
|
+
className,
|
|
53
|
+
children,
|
|
54
|
+
...props
|
|
55
|
+
}: Readonly<ChartContainerProps>) {
|
|
43
56
|
const uniqueId = React.useId();
|
|
44
|
-
const chartId = `chart-${id
|
|
57
|
+
const chartId = `chart-${id ?? uniqueId.replace(/:/g, "")}`;
|
|
45
58
|
|
|
46
59
|
return (
|
|
47
60
|
<ChartContext.Provider value={{config}}>
|
|
48
61
|
<div
|
|
62
|
+
data-slot='chart'
|
|
49
63
|
data-chart={chartId}
|
|
50
|
-
ref={ref}
|
|
51
64
|
className={cn(
|
|
52
|
-
"[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.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 [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-
|
|
65
|
+
"[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.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 [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden",
|
|
53
66
|
className,
|
|
54
67
|
)}
|
|
55
68
|
{...props}>
|
|
@@ -57,15 +70,14 @@ const ChartContainer = React.forwardRef<
|
|
|
57
70
|
id={chartId}
|
|
58
71
|
config={config}
|
|
59
72
|
/>
|
|
60
|
-
<RechartsPrimitive.ResponsiveContainer>{children}</RechartsPrimitive.ResponsiveContainer>
|
|
73
|
+
<RechartsPrimitive.ResponsiveContainer initialDimension={initialDimension}>{children}</RechartsPrimitive.ResponsiveContainer>
|
|
61
74
|
</div>
|
|
62
75
|
</ChartContext.Provider>
|
|
63
76
|
);
|
|
64
|
-
}
|
|
65
|
-
ChartContainer.displayName = "Chart";
|
|
77
|
+
}
|
|
66
78
|
|
|
67
79
|
const ChartStyle = ({id, config}: {id: string; config: ChartConfig}) => {
|
|
68
|
-
const colorConfig = Object.entries(config).filter(([, config]) => config.theme
|
|
80
|
+
const colorConfig = Object.entries(config).filter(([, config]) => config.theme ?? config.color);
|
|
69
81
|
|
|
70
82
|
if (!colorConfig.length) {
|
|
71
83
|
return null;
|
|
@@ -80,14 +92,14 @@ const ChartStyle = ({id, config}: {id: string; config: ChartConfig}) => {
|
|
|
80
92
|
${prefix} [data-chart=${id}] {
|
|
81
93
|
${colorConfig
|
|
82
94
|
.map(([key, itemConfig]) => {
|
|
83
|
-
const color = itemConfig.theme?.[theme as keyof typeof itemConfig.theme]
|
|
95
|
+
const color = itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ?? itemConfig.color;
|
|
84
96
|
return color ? ` --color-${key}: ${color};` : null;
|
|
85
97
|
})
|
|
86
|
-
.join("")}
|
|
98
|
+
.join("\n")}
|
|
87
99
|
}
|
|
88
100
|
`,
|
|
89
101
|
)
|
|
90
|
-
.join(""),
|
|
102
|
+
.join("\n"),
|
|
91
103
|
}}
|
|
92
104
|
/>
|
|
93
105
|
);
|
|
@@ -95,144 +107,136 @@ ${colorConfig
|
|
|
95
107
|
|
|
96
108
|
const ChartTooltip = RechartsPrimitive.Tooltip;
|
|
97
109
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
110
|
+
function ChartTooltipContent({
|
|
111
|
+
active,
|
|
112
|
+
payload,
|
|
113
|
+
className,
|
|
114
|
+
indicator = "dot",
|
|
115
|
+
hideLabel = false,
|
|
116
|
+
hideIndicator = false,
|
|
117
|
+
label,
|
|
118
|
+
labelFormatter,
|
|
119
|
+
labelClassName,
|
|
120
|
+
formatter,
|
|
121
|
+
color,
|
|
122
|
+
nameKey,
|
|
123
|
+
labelKey,
|
|
124
|
+
}: React.ComponentProps<typeof RechartsPrimitive.Tooltip>
|
|
125
|
+
& React.ComponentProps<"div"> & {
|
|
126
|
+
hideLabel?: boolean;
|
|
127
|
+
hideIndicator?: boolean;
|
|
128
|
+
indicator?: "line" | "dot" | "dashed";
|
|
129
|
+
nameKey?: string;
|
|
130
|
+
labelKey?: string;
|
|
131
|
+
} & Omit<RechartsPrimitive.DefaultTooltipContentProps<ValueType, NameType>, "accessibilityLayer">) {
|
|
132
|
+
const {config} = useChart();
|
|
133
|
+
|
|
134
|
+
const tooltipLabel = React.useMemo(() => {
|
|
135
|
+
if (hideLabel || !payload?.length) {
|
|
136
|
+
return null;
|
|
107
137
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
{
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
labelClassName,
|
|
120
|
-
formatter,
|
|
121
|
-
color,
|
|
122
|
-
nameKey,
|
|
123
|
-
labelKey,
|
|
124
|
-
},
|
|
125
|
-
ref,
|
|
126
|
-
) => {
|
|
127
|
-
const {config} = useChart();
|
|
128
|
-
|
|
129
|
-
const tooltipLabel = React.useMemo(() => {
|
|
130
|
-
if (hideLabel || !payload?.length) {
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const [item] = payload;
|
|
135
|
-
const key = `${labelKey || item?.dataKey || item?.name || "value"}`;
|
|
136
|
-
const itemConfig = getPayloadConfigFromPayload(config, item, key);
|
|
137
|
-
const value = !labelKey && typeof label === "string" ? config[label as keyof typeof config]?.label || label : itemConfig?.label;
|
|
138
|
-
|
|
139
|
-
if (labelFormatter) {
|
|
140
|
-
return <div className={cn("font-medium", labelClassName)}>{labelFormatter(value, payload)}</div>;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (!value) {
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return <div className={cn("font-medium", labelClassName)}>{value}</div>;
|
|
148
|
-
}, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);
|
|
149
|
-
|
|
150
|
-
if (!active || !payload?.length) {
|
|
138
|
+
|
|
139
|
+
const [item] = payload;
|
|
140
|
+
const key = `${labelKey ?? item?.dataKey ?? item?.name ?? "value"}`;
|
|
141
|
+
const itemConfig = getPayloadConfigFromPayload(config, item, key);
|
|
142
|
+
const value = !labelKey && typeof label === "string" ? (config[label]?.label ?? label) : itemConfig?.label;
|
|
143
|
+
|
|
144
|
+
if (labelFormatter) {
|
|
145
|
+
return <div className={cn("font-medium", labelClassName)}>{labelFormatter(value, payload)}</div>;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (!value) {
|
|
151
149
|
return null;
|
|
152
150
|
}
|
|
153
151
|
|
|
154
|
-
|
|
152
|
+
return <div className={cn("font-medium", labelClassName)}>{value}</div>;
|
|
153
|
+
}, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);
|
|
155
154
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
)}
|
|
155
|
+
if (!active || !payload?.length) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const nestLabel = payload.length === 1 && indicator !== "dot";
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<div
|
|
163
|
+
className={cn(
|
|
164
|
+
"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-xl",
|
|
165
|
+
className,
|
|
166
|
+
)}>
|
|
167
|
+
{!nestLabel ? tooltipLabel : null}
|
|
168
|
+
<div className='grid gap-1.5'>
|
|
169
|
+
{payload
|
|
170
|
+
.filter((item) => item.type !== "none")
|
|
171
|
+
.map((item, index) => {
|
|
172
|
+
const key = `${nameKey ?? item.name ?? item.dataKey ?? "value"}`;
|
|
173
|
+
const itemConfig = getPayloadConfigFromPayload(config, item, key);
|
|
174
|
+
const indicatorColor = color ?? item.payload?.fill ?? item.color;
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
<div
|
|
178
|
+
key={index}
|
|
179
|
+
className={cn(
|
|
180
|
+
"[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5",
|
|
181
|
+
indicator === "dot" && "items-center",
|
|
182
|
+
)}>
|
|
183
|
+
{formatter && item?.value !== undefined && item.name ? (
|
|
184
|
+
formatter(item.value, item.name, item, index, item.payload)
|
|
185
|
+
) : (
|
|
186
|
+
<>
|
|
187
|
+
{itemConfig?.icon ? (
|
|
188
|
+
<itemConfig.icon />
|
|
189
|
+
) : (
|
|
190
|
+
!hideIndicator && (
|
|
191
|
+
<div
|
|
192
|
+
className={cn("shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)", {
|
|
193
|
+
"h-2.5 w-2.5": indicator === "dot",
|
|
194
|
+
"w-1": indicator === "line",
|
|
195
|
+
"w-0 border-[1.5px] border-dashed bg-transparent": indicator === "dashed",
|
|
196
|
+
"my-0.5": nestLabel && indicator === "dashed",
|
|
197
|
+
})}
|
|
198
|
+
style={
|
|
199
|
+
{
|
|
200
|
+
"--color-bg": indicatorColor,
|
|
201
|
+
"--color-border": indicatorColor,
|
|
202
|
+
} as React.CSSProperties
|
|
203
|
+
}
|
|
204
|
+
/>
|
|
205
|
+
)
|
|
206
|
+
)}
|
|
207
|
+
<div className={cn("flex flex-1 justify-between leading-none", nestLabel ? "items-end" : "items-center")}>
|
|
208
|
+
<div className='grid gap-1.5'>
|
|
209
|
+
{nestLabel ? tooltipLabel : null}
|
|
210
|
+
<span className='text-muted-foreground'>{itemConfig?.label ?? item.name}</span>
|
|
213
211
|
</div>
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
212
|
+
{item.value != null && (
|
|
213
|
+
<span className='text-foreground font-mono font-medium tabular-nums'>
|
|
214
|
+
{typeof item.value === "number" ? item.value.toLocaleString() : String(item.value)}
|
|
215
|
+
</span>
|
|
216
|
+
)}
|
|
217
|
+
</div>
|
|
218
|
+
</>
|
|
219
|
+
)}
|
|
220
|
+
</div>
|
|
221
|
+
);
|
|
222
|
+
})}
|
|
220
223
|
</div>
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
ChartTooltipContent.displayName = "ChartTooltip";
|
|
224
|
+
</div>
|
|
225
|
+
);
|
|
226
|
+
}
|
|
225
227
|
|
|
226
228
|
const ChartLegend = RechartsPrimitive.Legend;
|
|
227
229
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
230
|
+
function ChartLegendContent({
|
|
231
|
+
className,
|
|
232
|
+
hideIcon = false,
|
|
233
|
+
nameKey,
|
|
234
|
+
payload,
|
|
235
|
+
verticalAlign,
|
|
236
|
+
}: React.ComponentProps<"div"> & {
|
|
237
|
+
hideIcon?: boolean;
|
|
238
|
+
nameKey?: string;
|
|
239
|
+
} & RechartsPrimitive.DefaultLegendContentProps) {
|
|
236
240
|
const {config} = useChart();
|
|
237
241
|
|
|
238
242
|
if (!payload?.length) {
|
|
@@ -240,19 +244,17 @@ const ChartLegendContent = React.forwardRef<
|
|
|
240
244
|
}
|
|
241
245
|
|
|
242
246
|
return (
|
|
243
|
-
<div
|
|
244
|
-
ref={ref}
|
|
245
|
-
className={cn("flex items-center justify-center gap-4", verticalAlign === "top" ? "pb-3" : "pt-3", className)}>
|
|
247
|
+
<div className={cn("flex items-center justify-center gap-4", verticalAlign === "top" ? "pb-3" : "pt-3", className)}>
|
|
246
248
|
{payload
|
|
247
249
|
.filter((item) => item.type !== "none")
|
|
248
250
|
.map((item) => {
|
|
249
|
-
const key = `${nameKey
|
|
251
|
+
const key = `${nameKey ?? item.dataKey ?? "value"}`;
|
|
250
252
|
const itemConfig = getPayloadConfigFromPayload(config, item, key);
|
|
251
253
|
|
|
252
254
|
return (
|
|
253
255
|
<div
|
|
254
256
|
key={item.value}
|
|
255
|
-
className={cn("flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3
|
|
257
|
+
className={cn("[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3")}>
|
|
256
258
|
{itemConfig?.icon && !hideIcon ? (
|
|
257
259
|
<itemConfig.icon />
|
|
258
260
|
) : (
|
|
@@ -269,8 +271,7 @@ const ChartLegendContent = React.forwardRef<
|
|
|
269
271
|
})}
|
|
270
272
|
</div>
|
|
271
273
|
);
|
|
272
|
-
}
|
|
273
|
-
ChartLegendContent.displayName = "ChartLegend";
|
|
274
|
+
}
|
|
274
275
|
|
|
275
276
|
// Helper to extract item config from a payload.
|
|
276
277
|
function getPayloadConfigFromPayload(config: ChartConfig, payload: unknown, key: string) {
|
|
@@ -289,7 +290,7 @@ function getPayloadConfigFromPayload(config: ChartConfig, payload: unknown, key:
|
|
|
289
290
|
configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string;
|
|
290
291
|
}
|
|
291
292
|
|
|
292
|
-
return configLabelKey in config ? config[configLabelKey] : config[key
|
|
293
|
+
return configLabelKey in config ? config[configLabelKey] : config[key];
|
|
293
294
|
}
|
|
294
295
|
|
|
295
296
|
export {ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent};
|
|
@@ -4,8 +4,6 @@ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
|
4
4
|
|
|
5
5
|
const Collapsible = CollapsiblePrimitive.Root;
|
|
6
6
|
|
|
7
|
-
const CollapsibleTrigger = CollapsiblePrimitive
|
|
8
|
-
|
|
9
|
-
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
|
|
7
|
+
const {CollapsibleTrigger, CollapsibleContent} = CollapsiblePrimitive;
|
|
10
8
|
|
|
11
9
|
export {Collapsible, CollapsibleContent, CollapsibleTrigger};
|