@neoptocom/neopto-ui 0.8.0 → 0.9.0
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/index.cjs +70 -4
- package/dist/index.d.cts +20 -2
- package/dist/index.d.ts +20 -2
- package/dist/index.js +71 -6
- package/package.json +1 -1
- package/src/components/BackgroundBlur.tsx +73 -0
- package/src/components/Chip.tsx +24 -2
- package/src/index.ts +2 -0
package/dist/index.cjs
CHANGED
|
@@ -100,6 +100,53 @@ function AppBackground({
|
|
|
100
100
|
)
|
|
101
101
|
] });
|
|
102
102
|
}
|
|
103
|
+
function BackgroundBlur({
|
|
104
|
+
open,
|
|
105
|
+
children,
|
|
106
|
+
onClose,
|
|
107
|
+
zIndex = 40,
|
|
108
|
+
className = ""
|
|
109
|
+
}) {
|
|
110
|
+
const [shouldRender, setShouldRender] = React2.useState(false);
|
|
111
|
+
const [isVisible, setIsVisible] = React2.useState(false);
|
|
112
|
+
React2.useEffect(() => {
|
|
113
|
+
if (open) {
|
|
114
|
+
setShouldRender(true);
|
|
115
|
+
requestAnimationFrame(() => {
|
|
116
|
+
setIsVisible(true);
|
|
117
|
+
});
|
|
118
|
+
} else {
|
|
119
|
+
setIsVisible(false);
|
|
120
|
+
const timer = setTimeout(() => {
|
|
121
|
+
setShouldRender(false);
|
|
122
|
+
}, 500);
|
|
123
|
+
return () => clearTimeout(timer);
|
|
124
|
+
}
|
|
125
|
+
}, [open]);
|
|
126
|
+
if (!shouldRender) return null;
|
|
127
|
+
const handleBackdropClick = (e) => {
|
|
128
|
+
if (e.target === e.currentTarget && onClose) {
|
|
129
|
+
onClose();
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
133
|
+
"div",
|
|
134
|
+
{
|
|
135
|
+
className: `fixed inset-0 flex items-center justify-center transition-opacity duration-500 ${className}`,
|
|
136
|
+
style: {
|
|
137
|
+
backgroundColor: "rgba(0, 0, 0, 0.10)",
|
|
138
|
+
backdropFilter: "blur(10px)",
|
|
139
|
+
WebkitBackdropFilter: "blur(10px)",
|
|
140
|
+
// Safari support
|
|
141
|
+
zIndex,
|
|
142
|
+
opacity: isVisible ? 1 : 0
|
|
143
|
+
},
|
|
144
|
+
onClick: handleBackdropClick,
|
|
145
|
+
role: "presentation",
|
|
146
|
+
children
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
}
|
|
103
150
|
var Input = React2__namespace.forwardRef(
|
|
104
151
|
({ className, disabled, ...props }, ref) => {
|
|
105
152
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -891,6 +938,9 @@ function Chip({
|
|
|
891
938
|
icon,
|
|
892
939
|
className = "",
|
|
893
940
|
label,
|
|
941
|
+
backgroundColor,
|
|
942
|
+
textColor,
|
|
943
|
+
style,
|
|
894
944
|
...props
|
|
895
945
|
}) {
|
|
896
946
|
const base = "inline-flex w-fit items-center justify-center gap-1 whitespace-nowrap overflow-hidden rounded-full h-6 px-2 text-xs font-semibold";
|
|
@@ -901,10 +951,25 @@ function Chip({
|
|
|
901
951
|
light: "bg-[var(--muted)] text-[var(--fg)]",
|
|
902
952
|
dark: "bg-[var(--surface)] text-[var(--fg)]"
|
|
903
953
|
};
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
954
|
+
const hasCustomColors = backgroundColor || textColor;
|
|
955
|
+
const colorClasses = hasCustomColors ? "" : variantCls[variant];
|
|
956
|
+
const mergedStyle = {
|
|
957
|
+
...style,
|
|
958
|
+
...backgroundColor && { backgroundColor },
|
|
959
|
+
...textColor && { color: textColor }
|
|
960
|
+
};
|
|
961
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
962
|
+
"div",
|
|
963
|
+
{
|
|
964
|
+
className: [base, colorClasses, className].join(" "),
|
|
965
|
+
style: mergedStyle,
|
|
966
|
+
...props,
|
|
967
|
+
children: [
|
|
968
|
+
icon ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, size: "sm", className: "mr-0.5" }) : null,
|
|
969
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: label })
|
|
970
|
+
]
|
|
971
|
+
}
|
|
972
|
+
);
|
|
908
973
|
}
|
|
909
974
|
function Counter({
|
|
910
975
|
value = 0,
|
|
@@ -1144,6 +1209,7 @@ exports.AppBackground = AppBackground;
|
|
|
1144
1209
|
exports.Autocomplete = Autocomplete;
|
|
1145
1210
|
exports.Avatar = Avatar;
|
|
1146
1211
|
exports.AvatarGroup = AvatarGroup;
|
|
1212
|
+
exports.BackgroundBlur = BackgroundBlur;
|
|
1147
1213
|
exports.Button = Button;
|
|
1148
1214
|
exports.ChatButton = ChatButton_default;
|
|
1149
1215
|
exports.Chip = Chip;
|
package/dist/index.d.cts
CHANGED
|
@@ -26,6 +26,20 @@ type AppBackgroundProps = {
|
|
|
26
26
|
};
|
|
27
27
|
declare function AppBackground({ children, lightImage, darkImage, className, }: AppBackgroundProps): react_jsx_runtime.JSX.Element;
|
|
28
28
|
|
|
29
|
+
type BackgroundBlurProps = {
|
|
30
|
+
/** Whether the blur overlay is visible */
|
|
31
|
+
open: boolean;
|
|
32
|
+
/** Content to render on top of the blur (e.g., modal, drawer) */
|
|
33
|
+
children?: React.ReactNode;
|
|
34
|
+
/** Callback when the backdrop is clicked */
|
|
35
|
+
onClose?: () => void;
|
|
36
|
+
/** z-index for the overlay (default: 40) */
|
|
37
|
+
zIndex?: number;
|
|
38
|
+
/** Additional CSS classes */
|
|
39
|
+
className?: string;
|
|
40
|
+
};
|
|
41
|
+
declare function BackgroundBlur({ open, children, onClose, zIndex, className, }: BackgroundBlurProps): react_jsx_runtime.JSX.Element | null;
|
|
42
|
+
|
|
29
43
|
type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>;
|
|
30
44
|
declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
|
|
31
45
|
|
|
@@ -214,8 +228,12 @@ type ChipProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
|
214
228
|
variant?: "warning" | "success" | "error" | "light" | "dark";
|
|
215
229
|
icon?: string;
|
|
216
230
|
label?: string;
|
|
231
|
+
/** Custom background color (overrides variant) */
|
|
232
|
+
backgroundColor?: string;
|
|
233
|
+
/** Custom text color (overrides variant) */
|
|
234
|
+
textColor?: string;
|
|
217
235
|
};
|
|
218
|
-
declare function Chip({ variant, icon, className, label, ...props }: ChipProps): react_jsx_runtime.JSX.Element;
|
|
236
|
+
declare function Chip({ variant, icon, className, label, backgroundColor, textColor, style, ...props }: ChipProps): react_jsx_runtime.JSX.Element;
|
|
219
237
|
|
|
220
238
|
type CounterProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> & {
|
|
221
239
|
value?: number;
|
|
@@ -255,4 +273,4 @@ interface AnimatedBgRectangleProps {
|
|
|
255
273
|
}
|
|
256
274
|
declare const AnimatedBgRectangle: ({ colors, delay }: AnimatedBgRectangleProps) => react_jsx_runtime.JSX.Element;
|
|
257
275
|
|
|
258
|
-
export { AnimatedBgCircle, AnimatedBgRectangle, AppBackground, type AppBackgroundProps, Autocomplete, type AutocompleteOption, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, ChatButton, type ChatButtonProps, Chip, type ChipProps, Counter, type CounterProps, Icon, IconButton, type IconButtonProps, type IconProps, Input, type InputProps, Modal, type ModalProps, Search, type SearchOption, type SearchProps, Skeleton, type SkeletonProps, Typo, type TypoProps, type TypoVariant, type TypoWeight, index as assets };
|
|
276
|
+
export { AnimatedBgCircle, AnimatedBgRectangle, AppBackground, type AppBackgroundProps, Autocomplete, type AutocompleteOption, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, BackgroundBlur, type BackgroundBlurProps, Button, type ButtonProps, ChatButton, type ChatButtonProps, Chip, type ChipProps, Counter, type CounterProps, Icon, IconButton, type IconButtonProps, type IconProps, Input, type InputProps, Modal, type ModalProps, Search, type SearchOption, type SearchProps, Skeleton, type SkeletonProps, Typo, type TypoProps, type TypoVariant, type TypoWeight, index as assets };
|
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,20 @@ type AppBackgroundProps = {
|
|
|
26
26
|
};
|
|
27
27
|
declare function AppBackground({ children, lightImage, darkImage, className, }: AppBackgroundProps): react_jsx_runtime.JSX.Element;
|
|
28
28
|
|
|
29
|
+
type BackgroundBlurProps = {
|
|
30
|
+
/** Whether the blur overlay is visible */
|
|
31
|
+
open: boolean;
|
|
32
|
+
/** Content to render on top of the blur (e.g., modal, drawer) */
|
|
33
|
+
children?: React.ReactNode;
|
|
34
|
+
/** Callback when the backdrop is clicked */
|
|
35
|
+
onClose?: () => void;
|
|
36
|
+
/** z-index for the overlay (default: 40) */
|
|
37
|
+
zIndex?: number;
|
|
38
|
+
/** Additional CSS classes */
|
|
39
|
+
className?: string;
|
|
40
|
+
};
|
|
41
|
+
declare function BackgroundBlur({ open, children, onClose, zIndex, className, }: BackgroundBlurProps): react_jsx_runtime.JSX.Element | null;
|
|
42
|
+
|
|
29
43
|
type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>;
|
|
30
44
|
declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
|
|
31
45
|
|
|
@@ -214,8 +228,12 @@ type ChipProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
|
214
228
|
variant?: "warning" | "success" | "error" | "light" | "dark";
|
|
215
229
|
icon?: string;
|
|
216
230
|
label?: string;
|
|
231
|
+
/** Custom background color (overrides variant) */
|
|
232
|
+
backgroundColor?: string;
|
|
233
|
+
/** Custom text color (overrides variant) */
|
|
234
|
+
textColor?: string;
|
|
217
235
|
};
|
|
218
|
-
declare function Chip({ variant, icon, className, label, ...props }: ChipProps): react_jsx_runtime.JSX.Element;
|
|
236
|
+
declare function Chip({ variant, icon, className, label, backgroundColor, textColor, style, ...props }: ChipProps): react_jsx_runtime.JSX.Element;
|
|
219
237
|
|
|
220
238
|
type CounterProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> & {
|
|
221
239
|
value?: number;
|
|
@@ -255,4 +273,4 @@ interface AnimatedBgRectangleProps {
|
|
|
255
273
|
}
|
|
256
274
|
declare const AnimatedBgRectangle: ({ colors, delay }: AnimatedBgRectangleProps) => react_jsx_runtime.JSX.Element;
|
|
257
275
|
|
|
258
|
-
export { AnimatedBgCircle, AnimatedBgRectangle, AppBackground, type AppBackgroundProps, Autocomplete, type AutocompleteOption, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, ChatButton, type ChatButtonProps, Chip, type ChipProps, Counter, type CounterProps, Icon, IconButton, type IconButtonProps, type IconProps, Input, type InputProps, Modal, type ModalProps, Search, type SearchOption, type SearchProps, Skeleton, type SkeletonProps, Typo, type TypoProps, type TypoVariant, type TypoWeight, index as assets };
|
|
276
|
+
export { AnimatedBgCircle, AnimatedBgRectangle, AppBackground, type AppBackgroundProps, Autocomplete, type AutocompleteOption, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, BackgroundBlur, type BackgroundBlurProps, Button, type ButtonProps, ChatButton, type ChatButtonProps, Chip, type ChipProps, Counter, type CounterProps, Icon, IconButton, type IconButtonProps, type IconProps, Input, type InputProps, Modal, type ModalProps, Search, type SearchOption, type SearchProps, Skeleton, type SkeletonProps, Typo, type TypoProps, type TypoVariant, type TypoWeight, index as assets };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import * as React2 from 'react';
|
|
3
|
-
import { useState, useMemo, useId, useRef, useCallback
|
|
3
|
+
import { useState, useEffect, useMemo, useId, useRef, useCallback } from 'react';
|
|
4
4
|
import { createPortal } from 'react-dom';
|
|
5
5
|
|
|
6
6
|
var __defProp = Object.defineProperty;
|
|
@@ -79,6 +79,53 @@ function AppBackground({
|
|
|
79
79
|
)
|
|
80
80
|
] });
|
|
81
81
|
}
|
|
82
|
+
function BackgroundBlur({
|
|
83
|
+
open,
|
|
84
|
+
children,
|
|
85
|
+
onClose,
|
|
86
|
+
zIndex = 40,
|
|
87
|
+
className = ""
|
|
88
|
+
}) {
|
|
89
|
+
const [shouldRender, setShouldRender] = useState(false);
|
|
90
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (open) {
|
|
93
|
+
setShouldRender(true);
|
|
94
|
+
requestAnimationFrame(() => {
|
|
95
|
+
setIsVisible(true);
|
|
96
|
+
});
|
|
97
|
+
} else {
|
|
98
|
+
setIsVisible(false);
|
|
99
|
+
const timer = setTimeout(() => {
|
|
100
|
+
setShouldRender(false);
|
|
101
|
+
}, 500);
|
|
102
|
+
return () => clearTimeout(timer);
|
|
103
|
+
}
|
|
104
|
+
}, [open]);
|
|
105
|
+
if (!shouldRender) return null;
|
|
106
|
+
const handleBackdropClick = (e) => {
|
|
107
|
+
if (e.target === e.currentTarget && onClose) {
|
|
108
|
+
onClose();
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
return /* @__PURE__ */ jsx(
|
|
112
|
+
"div",
|
|
113
|
+
{
|
|
114
|
+
className: `fixed inset-0 flex items-center justify-center transition-opacity duration-500 ${className}`,
|
|
115
|
+
style: {
|
|
116
|
+
backgroundColor: "rgba(0, 0, 0, 0.10)",
|
|
117
|
+
backdropFilter: "blur(10px)",
|
|
118
|
+
WebkitBackdropFilter: "blur(10px)",
|
|
119
|
+
// Safari support
|
|
120
|
+
zIndex,
|
|
121
|
+
opacity: isVisible ? 1 : 0
|
|
122
|
+
},
|
|
123
|
+
onClick: handleBackdropClick,
|
|
124
|
+
role: "presentation",
|
|
125
|
+
children
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
}
|
|
82
129
|
var Input = React2.forwardRef(
|
|
83
130
|
({ className, disabled, ...props }, ref) => {
|
|
84
131
|
return /* @__PURE__ */ jsx(
|
|
@@ -870,6 +917,9 @@ function Chip({
|
|
|
870
917
|
icon,
|
|
871
918
|
className = "",
|
|
872
919
|
label,
|
|
920
|
+
backgroundColor,
|
|
921
|
+
textColor,
|
|
922
|
+
style,
|
|
873
923
|
...props
|
|
874
924
|
}) {
|
|
875
925
|
const base = "inline-flex w-fit items-center justify-center gap-1 whitespace-nowrap overflow-hidden rounded-full h-6 px-2 text-xs font-semibold";
|
|
@@ -880,10 +930,25 @@ function Chip({
|
|
|
880
930
|
light: "bg-[var(--muted)] text-[var(--fg)]",
|
|
881
931
|
dark: "bg-[var(--surface)] text-[var(--fg)]"
|
|
882
932
|
};
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
933
|
+
const hasCustomColors = backgroundColor || textColor;
|
|
934
|
+
const colorClasses = hasCustomColors ? "" : variantCls[variant];
|
|
935
|
+
const mergedStyle = {
|
|
936
|
+
...style,
|
|
937
|
+
...backgroundColor && { backgroundColor },
|
|
938
|
+
...textColor && { color: textColor }
|
|
939
|
+
};
|
|
940
|
+
return /* @__PURE__ */ jsxs(
|
|
941
|
+
"div",
|
|
942
|
+
{
|
|
943
|
+
className: [base, colorClasses, className].join(" "),
|
|
944
|
+
style: mergedStyle,
|
|
945
|
+
...props,
|
|
946
|
+
children: [
|
|
947
|
+
icon ? /* @__PURE__ */ jsx(Icon, { name: icon, size: "sm", className: "mr-0.5" }) : null,
|
|
948
|
+
/* @__PURE__ */ jsx("span", { children: label })
|
|
949
|
+
]
|
|
950
|
+
}
|
|
951
|
+
);
|
|
887
952
|
}
|
|
888
953
|
function Counter({
|
|
889
954
|
value = 0,
|
|
@@ -1117,4 +1182,4 @@ var ChatButton = ({
|
|
|
1117
1182
|
};
|
|
1118
1183
|
var ChatButton_default = ChatButton;
|
|
1119
1184
|
|
|
1120
|
-
export { AnimatedBgCircle_default as AnimatedBgCircle, AnimatedBgRectangle_default as AnimatedBgRectangle, AppBackground, Autocomplete, Avatar, AvatarGroup, Button, ChatButton_default as ChatButton, Chip, Counter, Icon, IconButton, Input, Modal, Search, Skeleton, Typo, assets_exports as assets };
|
|
1185
|
+
export { AnimatedBgCircle_default as AnimatedBgCircle, AnimatedBgRectangle_default as AnimatedBgRectangle, AppBackground, Autocomplete, Avatar, AvatarGroup, BackgroundBlur, Button, ChatButton_default as ChatButton, Chip, Counter, Icon, IconButton, Input, Modal, Search, Skeleton, Typo, assets_exports as assets };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neoptocom/neopto-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A modern React component library built with Tailwind CSS v4 and TypeScript. Features dark mode, design tokens, and comprehensive Storybook documentation. Requires Tailwind v4+.",
|
|
6
6
|
"keywords": [
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
|
|
4
|
+
export type BackgroundBlurProps = {
|
|
5
|
+
/** Whether the blur overlay is visible */
|
|
6
|
+
open: boolean;
|
|
7
|
+
/** Content to render on top of the blur (e.g., modal, drawer) */
|
|
8
|
+
children?: React.ReactNode;
|
|
9
|
+
/** Callback when the backdrop is clicked */
|
|
10
|
+
onClose?: () => void;
|
|
11
|
+
/** z-index for the overlay (default: 40) */
|
|
12
|
+
zIndex?: number;
|
|
13
|
+
/** Additional CSS classes */
|
|
14
|
+
className?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export function BackgroundBlur({
|
|
18
|
+
open,
|
|
19
|
+
children,
|
|
20
|
+
onClose,
|
|
21
|
+
zIndex = 40,
|
|
22
|
+
className = "",
|
|
23
|
+
}: BackgroundBlurProps) {
|
|
24
|
+
const [shouldRender, setShouldRender] = useState(false);
|
|
25
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (open) {
|
|
29
|
+
// Mount the component
|
|
30
|
+
setShouldRender(true);
|
|
31
|
+
// Trigger fade-in on next frame
|
|
32
|
+
requestAnimationFrame(() => {
|
|
33
|
+
setIsVisible(true);
|
|
34
|
+
});
|
|
35
|
+
} else {
|
|
36
|
+
// Trigger fade-out
|
|
37
|
+
setIsVisible(false);
|
|
38
|
+
// Unmount after transition completes
|
|
39
|
+
const timer = setTimeout(() => {
|
|
40
|
+
setShouldRender(false);
|
|
41
|
+
}, 500); // Match transition duration
|
|
42
|
+
return () => clearTimeout(timer);
|
|
43
|
+
}
|
|
44
|
+
}, [open]);
|
|
45
|
+
|
|
46
|
+
// Don't render if not mounted
|
|
47
|
+
if (!shouldRender) return null;
|
|
48
|
+
|
|
49
|
+
const handleBackdropClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
50
|
+
// Only trigger onClose if clicking the backdrop itself, not children
|
|
51
|
+
if (e.target === e.currentTarget && onClose) {
|
|
52
|
+
onClose();
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div
|
|
58
|
+
className={`fixed inset-0 flex items-center justify-center transition-opacity duration-500 ${className}`}
|
|
59
|
+
style={{
|
|
60
|
+
backgroundColor: "rgba(0, 0, 0, 0.10)",
|
|
61
|
+
backdropFilter: "blur(10px)",
|
|
62
|
+
WebkitBackdropFilter: "blur(10px)", // Safari support
|
|
63
|
+
zIndex,
|
|
64
|
+
opacity: isVisible ? 1 : 0,
|
|
65
|
+
}}
|
|
66
|
+
onClick={handleBackdropClick}
|
|
67
|
+
role="presentation"
|
|
68
|
+
>
|
|
69
|
+
{children}
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
package/src/components/Chip.tsx
CHANGED
|
@@ -5,6 +5,10 @@ export type ChipProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
|
5
5
|
variant?: "warning" | "success" | "error" | "light" | "dark";
|
|
6
6
|
icon?: string;
|
|
7
7
|
label?: string;
|
|
8
|
+
/** Custom background color (overrides variant) */
|
|
9
|
+
backgroundColor?: string;
|
|
10
|
+
/** Custom text color (overrides variant) */
|
|
11
|
+
textColor?: string;
|
|
8
12
|
};
|
|
9
13
|
|
|
10
14
|
export default function Chip({
|
|
@@ -12,13 +16,16 @@ export default function Chip({
|
|
|
12
16
|
icon,
|
|
13
17
|
className = "",
|
|
14
18
|
label,
|
|
19
|
+
backgroundColor,
|
|
20
|
+
textColor,
|
|
21
|
+
style,
|
|
15
22
|
...props
|
|
16
23
|
}: ChipProps) {
|
|
17
24
|
const base =
|
|
18
25
|
"inline-flex w-fit items-center justify-center gap-1 whitespace-nowrap overflow-hidden rounded-full h-6 px-2 " +
|
|
19
26
|
"text-xs font-semibold";
|
|
20
27
|
|
|
21
|
-
// Token-based backgrounds + readable text
|
|
28
|
+
// Token-based backgrounds + readable text (only used if no custom colors)
|
|
22
29
|
const variantCls: Record<NonNullable<ChipProps["variant"]>, string> = {
|
|
23
30
|
warning: "bg-[var(--warning)] text-white",
|
|
24
31
|
success: "bg-[var(--success)] text-white",
|
|
@@ -27,8 +34,23 @@ export default function Chip({
|
|
|
27
34
|
dark: "bg-[var(--surface)] text-[var(--fg)]"
|
|
28
35
|
};
|
|
29
36
|
|
|
37
|
+
// Use custom colors if provided, otherwise use variant styles
|
|
38
|
+
const hasCustomColors = backgroundColor || textColor;
|
|
39
|
+
const colorClasses = hasCustomColors ? "" : variantCls[variant];
|
|
40
|
+
|
|
41
|
+
// Merge custom colors into style prop
|
|
42
|
+
const mergedStyle: React.CSSProperties = {
|
|
43
|
+
...style,
|
|
44
|
+
...(backgroundColor && { backgroundColor }),
|
|
45
|
+
...(textColor && { color: textColor }),
|
|
46
|
+
};
|
|
47
|
+
|
|
30
48
|
return (
|
|
31
|
-
<div
|
|
49
|
+
<div
|
|
50
|
+
className={[base, colorClasses, className].join(" ")}
|
|
51
|
+
style={mergedStyle}
|
|
52
|
+
{...props}
|
|
53
|
+
>
|
|
32
54
|
{icon ? <Icon name={icon} size="sm" className="mr-0.5" /> : null}
|
|
33
55
|
<span>{label}</span>
|
|
34
56
|
</div>
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * as assets from "./assets";
|
|
|
3
3
|
|
|
4
4
|
// Components
|
|
5
5
|
export { AppBackground } from "./components/AppBackground";
|
|
6
|
+
export { BackgroundBlur } from "./components/BackgroundBlur";
|
|
6
7
|
export * from "./components/Input";
|
|
7
8
|
export * from "./components/Modal";
|
|
8
9
|
export { default as Typo } from "./components/Typo";
|
|
@@ -20,6 +21,7 @@ export * from "./components/Chat";
|
|
|
20
21
|
|
|
21
22
|
// Types
|
|
22
23
|
export type { AppBackgroundProps } from "./components/AppBackground";
|
|
24
|
+
export type { BackgroundBlurProps } from "./components/BackgroundBlur";
|
|
23
25
|
export type { InputProps } from "./components/Input";
|
|
24
26
|
export type { ModalProps } from "./components/Modal";
|
|
25
27
|
export type { TypoProps, TypoVariant, TypoWeight } from "./components/Typo";
|