@neuctra/ui 0.2.9 → 0.2.10
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.js +109 -140
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +1563 -2402
- package/dist/index.es.js.map +1 -1
- package/dist/{components → types/components}/basic/Alert.d.ts +3 -2
- package/dist/{components → types/components}/basic/Avatar.d.ts +1 -0
- package/dist/{components → types/components}/basic/Badge.d.ts +1 -2
- package/dist/{components → types/components}/basic/Button.d.ts +2 -2
- package/dist/types/components/basic/Container.d.ts +15 -0
- package/dist/{components → types/components}/basic/Input.d.ts +1 -1
- package/dist/types/components/basic/Tabs.d.ts +76 -0
- package/dist/{components → types/components}/basic/Text.d.ts +25 -20
- package/dist/{index.d.ts → types/index.d.ts} +3 -7
- package/dist/ui.css +1 -1
- package/package.json +9 -2
- package/dist/components/basic/Container.d.ts +0 -21
- package/dist/components/basic/Tabs.d.ts +0 -47
- package/dist/src/components/basic/Accordation.js +0 -73
- package/dist/src/components/basic/Alert.js +0 -36
- package/dist/src/components/basic/AudioGallery.js +0 -425
- package/dist/src/components/basic/AudioPlayer.js +0 -130
- package/dist/src/components/basic/Avatar.js +0 -68
- package/dist/src/components/basic/Badge.js +0 -27
- package/dist/src/components/basic/Button.js +0 -24
- package/dist/src/components/basic/CheckboxGroup.js +0 -63
- package/dist/src/components/basic/Container.js +0 -56
- package/dist/src/components/basic/Drawer.js +0 -43
- package/dist/src/components/basic/DropDown.js +0 -98
- package/dist/src/components/basic/FlexView.js +0 -19
- package/dist/src/components/basic/GridView.js +0 -18
- package/dist/src/components/basic/Image.js +0 -55
- package/dist/src/components/basic/Input.js +0 -82
- package/dist/src/components/basic/List.js +0 -29
- package/dist/src/components/basic/Modal.js +0 -34
- package/dist/src/components/basic/RadioGroup.js +0 -54
- package/dist/src/components/basic/Stack.js +0 -22
- package/dist/src/components/basic/SwitchGroup.js +0 -76
- package/dist/src/components/basic/Table.js +0 -30
- package/dist/src/components/basic/Tabs.js +0 -140
- package/dist/src/components/basic/Text.js +0 -25
- package/dist/src/index.js +0 -44
- package/dist/types/src/components/basic/Accordation.d.ts +0 -40
- package/dist/types/src/components/basic/Alert.d.ts +0 -17
- package/dist/types/src/components/basic/AudioGallery.d.ts +0 -23
- package/dist/types/src/components/basic/AudioPlayer.d.ts +0 -16
- package/dist/types/src/components/basic/Avatar.d.ts +0 -23
- package/dist/types/src/components/basic/Badge.d.ts +0 -21
- package/dist/types/src/components/basic/Button.d.ts +0 -15
- package/dist/types/src/components/basic/CheckboxGroup.d.ts +0 -27
- package/dist/types/src/components/basic/Container.d.ts +0 -21
- package/dist/types/src/components/basic/Drawer.d.ts +0 -22
- package/dist/types/src/components/basic/DropDown.d.ts +0 -33
- package/dist/types/src/components/basic/FlexView.d.ts +0 -16
- package/dist/types/src/components/basic/GridView.d.ts +0 -14
- package/dist/types/src/components/basic/Image.d.ts +0 -37
- package/dist/types/src/components/basic/Input.d.ts +0 -33
- package/dist/types/src/components/basic/List.d.ts +0 -20
- package/dist/types/src/components/basic/Modal.d.ts +0 -17
- package/dist/types/src/components/basic/RadioGroup.d.ts +0 -26
- package/dist/types/src/components/basic/Stack.d.ts +0 -17
- package/dist/types/src/components/basic/SwitchGroup.d.ts +0 -26
- package/dist/types/src/components/basic/Table.d.ts +0 -28
- package/dist/types/src/components/basic/Tabs.d.ts +0 -47
- package/dist/types/src/components/basic/Text.d.ts +0 -1121
- package/dist/types/src/index.d.ts +0 -24
- package/dist/types/vite.config.d.ts +0 -2
- package/dist/vite.config.js +0 -34
- /package/dist/{components/basic/Accordation.d.ts → types/components/basic/Accordion.d.ts} +0 -0
- /package/dist/{components → types/components}/basic/AudioGallery.d.ts +0 -0
- /package/dist/{components → types/components}/basic/AudioPlayer.d.ts +0 -0
- /package/dist/{components → types/components}/basic/CheckboxGroup.d.ts +0 -0
- /package/dist/{components → types/components}/basic/Drawer.d.ts +0 -0
- /package/dist/{components → types/components}/basic/DropDown.d.ts +0 -0
- /package/dist/{components → types/components}/basic/FlexView.d.ts +0 -0
- /package/dist/{components → types/components}/basic/GridView.d.ts +0 -0
- /package/dist/{components → types/components}/basic/Image.d.ts +0 -0
- /package/dist/{components → types/components}/basic/List.d.ts +0 -0
- /package/dist/{components → types/components}/basic/Modal.d.ts +0 -0
- /package/dist/{components → types/components}/basic/RadioGroup.d.ts +0 -0
- /package/dist/{components → types/components}/basic/Stack.d.ts +0 -0
- /package/dist/{components → types/components}/basic/SwitchGroup.d.ts +0 -0
- /package/dist/{components → types/components}/basic/Table.d.ts +0 -0
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState, useEffect, useRef } from "react";
|
|
4
|
-
import clsx from "clsx";
|
|
5
|
-
export const RadioGroup = ({ name, options, selectedValue, onChange, disabled = false, readOnly = false, required = false, error, className, style, labelStyle, iconSize = 20, iconCheckedBgColor = "#2563eb", iconUncheckedBorderColor = "#9ca3af", textColor = "#374151", errorStyle, darkMode = false, }) => {
|
|
6
|
-
const containerRef = useRef(null);
|
|
7
|
-
const [focusedIndex, setFocusedIndex] = useState(null);
|
|
8
|
-
// Keyboard navigation
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
const container = containerRef.current;
|
|
11
|
-
if (!container)
|
|
12
|
-
return;
|
|
13
|
-
const handleKeyDown = (e) => {
|
|
14
|
-
if (disabled)
|
|
15
|
-
return;
|
|
16
|
-
const currentIndex = focusedIndex ?? options.findIndex((o) => o.value === selectedValue) ?? 0;
|
|
17
|
-
if (e.key === "ArrowDown" || e.key === "ArrowRight") {
|
|
18
|
-
e.preventDefault();
|
|
19
|
-
const nextIndex = (currentIndex + 1) % options.length;
|
|
20
|
-
onChange && onChange(options[nextIndex].value);
|
|
21
|
-
setFocusedIndex(nextIndex);
|
|
22
|
-
}
|
|
23
|
-
if (e.key === "ArrowUp" || e.key === "ArrowLeft") {
|
|
24
|
-
e.preventDefault();
|
|
25
|
-
const prevIndex = (currentIndex - 1 + options.length) % options.length;
|
|
26
|
-
onChange && onChange(options[prevIndex].value);
|
|
27
|
-
setFocusedIndex(prevIndex);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
container.addEventListener("keydown", handleKeyDown);
|
|
31
|
-
return () => container.removeEventListener("keydown", handleKeyDown);
|
|
32
|
-
}, [focusedIndex, options, selectedValue, onChange, disabled]);
|
|
33
|
-
return (_jsxs("div", { ref: containerRef, role: "radiogroup", "aria-disabled": disabled, "aria-invalid": !!error, className: clsx("flex flex-col gap-2", className), style: { ...style }, tabIndex: 0, children: [options.map((option, index) => {
|
|
34
|
-
const isChecked = selectedValue === option.value;
|
|
35
|
-
const isFocused = focusedIndex === index;
|
|
36
|
-
return (_jsxs("label", { className: clsx("flex items-center justify-between cursor-pointer select-none gap-2", disabled ? "opacity-50 cursor-not-allowed" : "opacity-100", isFocused ? "ring-2 ring-blue-400" : ""), style: { ...labelStyle }, children: [_jsx("span", { style: { color: textColor, fontSize: 14 }, children: option.label }), _jsx("input", { type: "radio", name: name, value: option.value, checked: isChecked, disabled: disabled || readOnly, required: required, onChange: () => onChange && onChange(option.value), style: { display: "none" } }), _jsx("span", { className: clsx("inline-flex items-center justify-center rounded-full transition-all"), style: {
|
|
37
|
-
width: iconSize,
|
|
38
|
-
height: iconSize,
|
|
39
|
-
border: `2px solid ${isChecked ? iconCheckedBgColor : iconUncheckedBorderColor}`,
|
|
40
|
-
backgroundColor: isChecked ? iconCheckedBgColor : "transparent",
|
|
41
|
-
transition: "all 0.2s ease",
|
|
42
|
-
}, children: isChecked && (_jsx("span", { style: {
|
|
43
|
-
width: iconSize / 2,
|
|
44
|
-
height: iconSize / 2,
|
|
45
|
-
borderRadius: "50%",
|
|
46
|
-
backgroundColor: darkMode ? "#fff" : "#fff",
|
|
47
|
-
} })) })] }, option.value));
|
|
48
|
-
}), error && (_jsx("p", { role: "alert", style: {
|
|
49
|
-
color: "#dc2626",
|
|
50
|
-
fontSize: 12,
|
|
51
|
-
marginTop: 4,
|
|
52
|
-
...errorStyle,
|
|
53
|
-
}, children: error }))] }));
|
|
54
|
-
};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import clsx from "clsx";
|
|
3
|
-
/**
|
|
4
|
-
* Convert responsive prop to Tailwind class string
|
|
5
|
-
*/
|
|
6
|
-
const toResponsiveClass = (prefix, value) => {
|
|
7
|
-
if (value == null)
|
|
8
|
-
return "";
|
|
9
|
-
if (typeof value !== "object")
|
|
10
|
-
return `${prefix}-${value}`;
|
|
11
|
-
return Object.entries(value)
|
|
12
|
-
.map(([bp, val]) => `${bp}:${prefix}-${val}`)
|
|
13
|
-
.join(" ");
|
|
14
|
-
};
|
|
15
|
-
export const Stack = ({ direction = { sm: "vertical", md: "horizontal" }, gap = 4, align = "center", justify = "start", wrap = "nowrap", className, children, }) => {
|
|
16
|
-
const classes = clsx("flex", toResponsiveClass("flex", direction), // flex-col or flex-row
|
|
17
|
-
toResponsiveClass("gap", gap), align !== "stretch" ? `items-${align}` : "items-stretch", justify !== "start" ? `justify-${justify}` : "justify-start", wrap !== "nowrap" ? `flex-${wrap}` : "flex-nowrap", className);
|
|
18
|
-
return _jsx("div", { className: classes, children: children });
|
|
19
|
-
};
|
|
20
|
-
/** Shortcuts for horizontal & vertical stacks */
|
|
21
|
-
export const HStack = (props) => (_jsx(Stack, { direction: "horizontal", ...props }));
|
|
22
|
-
export const VStack = (props) => (_jsx(Stack, { direction: "vertical", ...props }));
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState, useEffect, useRef } from "react";
|
|
4
|
-
import clsx from "clsx";
|
|
5
|
-
export const SwitchGroup = ({ name, options, selectedValues = [], onChange, disabled = false, readOnly = false, required = false, error, className, style, labelStyle, iconSize = 20, iconCheckedBgColor = "#2563eb", switchBgColor = "#d1d5db", textColor = "#374151", errorStyle, darkMode = false, }) => {
|
|
6
|
-
const containerRef = useRef(null);
|
|
7
|
-
const [focusedIndex, setFocusedIndex] = useState(null);
|
|
8
|
-
const handleChange = (value) => {
|
|
9
|
-
if (!onChange || disabled || readOnly)
|
|
10
|
-
return;
|
|
11
|
-
const updatedValues = selectedValues.includes(value)
|
|
12
|
-
? selectedValues.filter((v) => v !== value)
|
|
13
|
-
: [...selectedValues, value];
|
|
14
|
-
onChange(updatedValues);
|
|
15
|
-
};
|
|
16
|
-
// Keyboard navigation
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
const container = containerRef.current;
|
|
19
|
-
if (!container)
|
|
20
|
-
return;
|
|
21
|
-
const handleKeyDown = (e) => {
|
|
22
|
-
if (disabled)
|
|
23
|
-
return;
|
|
24
|
-
if (focusedIndex === null)
|
|
25
|
-
return;
|
|
26
|
-
const currentIndex = focusedIndex;
|
|
27
|
-
if (e.key === "ArrowRight" || e.key === "ArrowDown") {
|
|
28
|
-
e.preventDefault();
|
|
29
|
-
const nextIndex = (currentIndex + 1) % options.length;
|
|
30
|
-
setFocusedIndex(nextIndex);
|
|
31
|
-
}
|
|
32
|
-
if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
|
|
33
|
-
e.preventDefault();
|
|
34
|
-
const prevIndex = (currentIndex - 1 + options.length) % options.length;
|
|
35
|
-
setFocusedIndex(prevIndex);
|
|
36
|
-
}
|
|
37
|
-
if (e.key === " " || e.key === "Enter") {
|
|
38
|
-
e.preventDefault();
|
|
39
|
-
handleChange(options[currentIndex].value);
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
container.addEventListener("keydown", handleKeyDown);
|
|
43
|
-
return () => container.removeEventListener("keydown", handleKeyDown);
|
|
44
|
-
}, [focusedIndex, options, selectedValues, disabled]);
|
|
45
|
-
return (_jsxs("div", { ref: containerRef, role: "group", "aria-disabled": disabled, "aria-invalid": !!error, tabIndex: 0, className: clsx("flex flex-col gap-2", className), style: { ...style }, children: [options.map((option, index) => {
|
|
46
|
-
const isChecked = selectedValues.includes(option.value);
|
|
47
|
-
const isFocused = focusedIndex === index;
|
|
48
|
-
return (_jsxs("label", { className: clsx("flex items-center justify-between cursor-pointer select-none transition-opacity", disabled ? "opacity-50 cursor-not-allowed" : "opacity-100", isFocused ? "ring-2 ring-blue-400" : ""), style: { ...labelStyle }, onFocus: () => setFocusedIndex(index), children: [_jsx("span", { style: { color: textColor, fontSize: 14 }, children: option.label }), _jsx("input", { type: "checkbox", name: name, value: option.value, checked: isChecked, disabled: disabled || readOnly, required: required, onChange: () => handleChange(option.value), style: { display: "none" } }), _jsx("span", { className: clsx("relative inline-flex rounded-full transition-colors"), style: {
|
|
49
|
-
width: iconSize * 2,
|
|
50
|
-
height: iconSize * 1.1,
|
|
51
|
-
backgroundColor: isChecked
|
|
52
|
-
? iconCheckedBgColor
|
|
53
|
-
: switchBgColor,
|
|
54
|
-
transition: "background-color 0.25s ease",
|
|
55
|
-
borderRadius: 9999,
|
|
56
|
-
}, children: _jsx("span", { style: {
|
|
57
|
-
position: "absolute",
|
|
58
|
-
top: "50%",
|
|
59
|
-
left: isChecked
|
|
60
|
-
? `calc(100% - ${iconSize - 4}px - 2px)`
|
|
61
|
-
: "2px",
|
|
62
|
-
transform: "translateY(-50%)",
|
|
63
|
-
width: iconSize - 4,
|
|
64
|
-
height: iconSize - 4,
|
|
65
|
-
borderRadius: "50%",
|
|
66
|
-
backgroundColor: "#fff",
|
|
67
|
-
boxShadow: "0 1px 2px rgba(0,0,0,0.3)",
|
|
68
|
-
transition: "left 0.25s ease",
|
|
69
|
-
} }) })] }, option.value));
|
|
70
|
-
}), error && (_jsx("p", { role: "alert", style: {
|
|
71
|
-
color: "#dc2626",
|
|
72
|
-
fontSize: 12,
|
|
73
|
-
marginTop: 4,
|
|
74
|
-
...errorStyle,
|
|
75
|
-
}, children: error }))] }));
|
|
76
|
-
};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import clsx from "clsx";
|
|
4
|
-
/* ---------------------------- Table Container ---------------------------- */
|
|
5
|
-
export const Table = ({ children, style, className }) => (_jsx("div", { className: clsx("overflow-x-auto rounded-lg shadow-sm border border-gray-200", className), style: {
|
|
6
|
-
background: "#ffffff",
|
|
7
|
-
...style,
|
|
8
|
-
}, children: _jsx("table", { className: "w-full border-collapse", style: {
|
|
9
|
-
borderSpacing: 0,
|
|
10
|
-
borderRadius: 12,
|
|
11
|
-
overflow: "hidden",
|
|
12
|
-
}, children: children }) }));
|
|
13
|
-
/* ---------------------------- Table Head ---------------------------- */
|
|
14
|
-
export const THead = ({ children, style, className, }) => (_jsx("thead", { className: clsx("bg-gray-100 text-gray-900 font-semibold", className), style: {
|
|
15
|
-
...style,
|
|
16
|
-
}, children: children }));
|
|
17
|
-
/* ---------------------------- Table Body ---------------------------- */
|
|
18
|
-
export const TBody = ({ children, style, className }) => (_jsx("tbody", { className: clsx("bg-white", className), style: { ...style }, children: children }));
|
|
19
|
-
export const TRow = ({ children, style, className, onClick, hoverBgColor = "#f9fafb", darkMode = false, }) => (_jsx("tr", { className: clsx("transition-colors duration-200 cursor-default", onClick ? "hover:cursor-pointer" : "", className), style: { borderBottom: "1px solid #e5e7eb", ...style }, onClick: onClick, onMouseEnter: (e) => {
|
|
20
|
-
if (!darkMode)
|
|
21
|
-
e.currentTarget.style.backgroundColor = hoverBgColor;
|
|
22
|
-
else
|
|
23
|
-
e.currentTarget.style.backgroundColor = "#1f2937";
|
|
24
|
-
}, onMouseLeave: (e) => {
|
|
25
|
-
e.currentTarget.style.backgroundColor = "transparent";
|
|
26
|
-
}, children: children }));
|
|
27
|
-
/* ---------------------------- Table Head Cell ---------------------------- */
|
|
28
|
-
export const TH = ({ children, style, className }) => (_jsx("th", { className: clsx("text-left px-4 py-3 text-sm text-gray-700 border-b-2 border-gray-200", className), style: { ...style }, children: children }));
|
|
29
|
-
/* ---------------------------- Table Data Cell ---------------------------- */
|
|
30
|
-
export const TD = ({ children, style, className }) => (_jsx("td", { className: clsx("px-4 py-3 text-sm text-gray-600", className), style: { ...style }, children: children }));
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState, useEffect, useRef } from "react";
|
|
4
|
-
/** 💎 Modern, Fully Customizable Tabs */
|
|
5
|
-
export const Tabs = ({ tabs, defaultActive = 0, position = "top", variant = "solid", fullWidth = false, gap = 8, radius = 8, padding = "12px 18px", transitionDuration = 200, elevation = 1, bordered = false, primaryColor = "#2563eb", backgroundColor = "transparent", textColor = "#374151", hoverColor = "#1d4ed8", activeColor = "#ffffff", borderColor = "#e5e7eb", disabledColor = "#9ca3af", responsiveBreakpoint = 768, showDrawerLabel = "Select Tab", drawerIcon = "☰", onTabChange, className = "", style, tabClassName = "", contentClassName = "", activeTabStyle, inactiveTabStyle, contentStyle, }) => {
|
|
6
|
-
const [active, setActive] = useState(defaultActive);
|
|
7
|
-
const [hovered, setHovered] = useState(null);
|
|
8
|
-
const [isMobile, setIsMobile] = useState(false);
|
|
9
|
-
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
10
|
-
const containerRef = useRef(null);
|
|
11
|
-
/** 📱 Responsive detection */
|
|
12
|
-
useEffect(() => {
|
|
13
|
-
const check = () => setIsMobile(window.innerWidth <= responsiveBreakpoint);
|
|
14
|
-
check();
|
|
15
|
-
window.addEventListener("resize", check);
|
|
16
|
-
return () => window.removeEventListener("resize", check);
|
|
17
|
-
}, [responsiveBreakpoint]);
|
|
18
|
-
/** 🎛 Handle tab change */
|
|
19
|
-
const handleChange = (i) => {
|
|
20
|
-
if (tabs[i].disabled)
|
|
21
|
-
return;
|
|
22
|
-
setActive(i);
|
|
23
|
-
onTabChange?.(i);
|
|
24
|
-
if (isMobile)
|
|
25
|
-
setDrawerOpen(false);
|
|
26
|
-
};
|
|
27
|
-
/** ⚡ Keyboard navigation */
|
|
28
|
-
const handleKeyDown = (e, i) => {
|
|
29
|
-
if (e.key === "ArrowRight" || e.key === "ArrowDown") {
|
|
30
|
-
e.preventDefault();
|
|
31
|
-
handleChange((i + 1) % tabs.length);
|
|
32
|
-
}
|
|
33
|
-
else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
|
|
34
|
-
e.preventDefault();
|
|
35
|
-
handleChange((i - 1 + tabs.length) % tabs.length);
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
/** 🎨 Base styles */
|
|
39
|
-
const baseTab = {
|
|
40
|
-
padding,
|
|
41
|
-
borderRadius: radius,
|
|
42
|
-
cursor: "pointer",
|
|
43
|
-
display: "flex",
|
|
44
|
-
alignItems: "center",
|
|
45
|
-
gap: 8,
|
|
46
|
-
justifyContent: "center",
|
|
47
|
-
fontWeight: 500,
|
|
48
|
-
transition: `all ${transitionDuration}ms ease`,
|
|
49
|
-
background: "transparent",
|
|
50
|
-
border: variant === "outline" ? `1px solid ${borderColor}` : "none",
|
|
51
|
-
borderBottom: variant === "underline" ? `2px solid transparent` : undefined,
|
|
52
|
-
color: textColor,
|
|
53
|
-
width: fullWidth ? "100%" : "auto",
|
|
54
|
-
userSelect: "none",
|
|
55
|
-
};
|
|
56
|
-
const activeTab = {
|
|
57
|
-
background: variant === "solid" ? primaryColor : "transparent",
|
|
58
|
-
color: activeColor,
|
|
59
|
-
borderBottom: variant === "underline" ? `2px solid ${primaryColor}` : undefined,
|
|
60
|
-
boxShadow: elevation > 0 ? `0 ${elevation}px ${elevation * 4}px ${primaryColor}33` : undefined,
|
|
61
|
-
...activeTabStyle,
|
|
62
|
-
};
|
|
63
|
-
const inactiveTab = {
|
|
64
|
-
...(variant === "outline" ? { borderColor } : {}),
|
|
65
|
-
...(variant === "underline" ? { borderBottomColor: "transparent" } : {}),
|
|
66
|
-
...inactiveTabStyle,
|
|
67
|
-
};
|
|
68
|
-
const hoverTab = {
|
|
69
|
-
color: hoverColor,
|
|
70
|
-
background: variant === "solid"
|
|
71
|
-
? `${primaryColor}11`
|
|
72
|
-
: variant === "outline"
|
|
73
|
-
? `${primaryColor}11`
|
|
74
|
-
: "transparent",
|
|
75
|
-
};
|
|
76
|
-
const disabledTab = {
|
|
77
|
-
color: disabledColor,
|
|
78
|
-
cursor: "not-allowed",
|
|
79
|
-
opacity: 0.6,
|
|
80
|
-
};
|
|
81
|
-
const contentBox = {
|
|
82
|
-
flexGrow: 1,
|
|
83
|
-
borderTop: bordered && position === "top" ? `1px solid ${borderColor}` : undefined,
|
|
84
|
-
borderLeft: bordered && position === "left" ? `1px solid ${borderColor}` : undefined,
|
|
85
|
-
borderRight: bordered && position === "right" ? `1px solid ${borderColor}` : undefined,
|
|
86
|
-
borderRadius: radius,
|
|
87
|
-
...contentStyle,
|
|
88
|
-
};
|
|
89
|
-
/** 🧱 Layout */
|
|
90
|
-
const isVertical = position === "left" || position === "right";
|
|
91
|
-
return (_jsxs("div", { ref: containerRef, className: `modern-tabs ${className}`, style: {
|
|
92
|
-
display: "flex",
|
|
93
|
-
flexDirection: isVertical ? (position === "right" ? "row-reverse" : "row") : "column",
|
|
94
|
-
background: backgroundColor,
|
|
95
|
-
border: bordered ? `1px solid ${borderColor}` : undefined,
|
|
96
|
-
borderRadius: radius,
|
|
97
|
-
overflow: "hidden",
|
|
98
|
-
...style,
|
|
99
|
-
}, children: [_jsx("style", { children: `
|
|
100
|
-
@keyframes tab-fade {
|
|
101
|
-
from { opacity: 0; transform: translateY(5px); }
|
|
102
|
-
to { opacity: 1; transform: translateY(0); }
|
|
103
|
-
}
|
|
104
|
-
.modern-tabs__content {
|
|
105
|
-
animation: tab-fade ${transitionDuration}ms ease;
|
|
106
|
-
}
|
|
107
|
-
` }), isMobile ? (_jsxs("div", { style: { width: "100%", padding: 8 }, children: [_jsxs("button", { onClick: () => setDrawerOpen(!drawerOpen), style: {
|
|
108
|
-
...baseTab,
|
|
109
|
-
...activeTab,
|
|
110
|
-
justifyContent: "space-between",
|
|
111
|
-
width: "100%",
|
|
112
|
-
fontSize: 16,
|
|
113
|
-
}, children: [showDrawerLabel, _jsx("span", { children: drawerIcon })] }), drawerOpen && (_jsx("div", { style: { display: "flex", flexDirection: "column", marginTop: 8, gap }, children: tabs.map((tab, i) => {
|
|
114
|
-
const isActive = i === active;
|
|
115
|
-
const isHovered = hovered === i;
|
|
116
|
-
const isDisabled = tab.disabled;
|
|
117
|
-
return (_jsxs("button", { disabled: isDisabled, onClick: () => handleChange(i), onKeyDown: (e) => handleKeyDown(e, i), onMouseEnter: () => setHovered(i), onMouseLeave: () => setHovered(null), className: tabClassName, style: {
|
|
118
|
-
...baseTab,
|
|
119
|
-
...(isActive ? activeTab : inactiveTab),
|
|
120
|
-
...(isHovered && !isActive && !isDisabled ? hoverTab : {}),
|
|
121
|
-
...(isDisabled ? disabledTab : {}),
|
|
122
|
-
}, children: [tab.icon && _jsx("span", { children: tab.icon }), tab.label] }, i));
|
|
123
|
-
}) }))] })) : (_jsx("div", { style: {
|
|
124
|
-
display: "flex",
|
|
125
|
-
flexDirection: isVertical ? "column" : "row",
|
|
126
|
-
gap,
|
|
127
|
-
padding: 8,
|
|
128
|
-
minWidth: isVertical ? 200 : undefined,
|
|
129
|
-
}, children: tabs.map((tab, i) => {
|
|
130
|
-
const isActive = i === active;
|
|
131
|
-
const isHovered = hovered === i;
|
|
132
|
-
const isDisabled = tab.disabled;
|
|
133
|
-
return (_jsxs("button", { disabled: isDisabled, onClick: () => handleChange(i), onKeyDown: (e) => handleKeyDown(e, i), onMouseEnter: () => setHovered(i), onMouseLeave: () => setHovered(null), className: tabClassName, style: {
|
|
134
|
-
...baseTab,
|
|
135
|
-
...(isActive ? activeTab : inactiveTab),
|
|
136
|
-
...(isHovered && !isActive && !isDisabled ? hoverTab : {}),
|
|
137
|
-
...(isDisabled ? disabledTab : {}),
|
|
138
|
-
}, role: "tab", "aria-selected": isActive, children: [tab.icon && _jsx("span", { children: tab.icon }), tab.label] }, i));
|
|
139
|
-
}) })), _jsx("div", { className: `modern-tabs__content ${contentClassName}`, style: contentBox, role: "tabpanel", children: tabs[active]?.content })] }));
|
|
140
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import clsx from "clsx";
|
|
4
|
-
const sizeClasses = {
|
|
5
|
-
xs: "text-xs",
|
|
6
|
-
sm: "text-sm",
|
|
7
|
-
md: "text-base",
|
|
8
|
-
lg: "text-lg",
|
|
9
|
-
xl: "text-xl",
|
|
10
|
-
"2xl": "text-2xl",
|
|
11
|
-
};
|
|
12
|
-
export function Text({ as, children, size = "md", weight = 400, align = "left", truncate = false, className, style, ...rest }) {
|
|
13
|
-
const Element = (as || "p");
|
|
14
|
-
return React.createElement(Element, {
|
|
15
|
-
className: clsx("text-inherit", // ✅ inherits parent color
|
|
16
|
-
sizeClasses[size] || "", truncate && "truncate", className),
|
|
17
|
-
style: {
|
|
18
|
-
fontWeight: weight,
|
|
19
|
-
textAlign: align,
|
|
20
|
-
...style,
|
|
21
|
-
},
|
|
22
|
-
...rest,
|
|
23
|
-
}, children);
|
|
24
|
-
}
|
|
25
|
-
export default Text;
|
package/dist/src/index.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import "./style.css"; // 🔹 Global styles import (keep this as the only CSS import)
|
|
2
|
-
// ==============================
|
|
3
|
-
// ✅ BASIC COMPONENT EXPORTS
|
|
4
|
-
// ==============================
|
|
5
|
-
// Alerts & Notifications
|
|
6
|
-
export { ToastProvider, useToast } from "./components/basic/Alert"; // ✅ Modern ShadCN-style toast
|
|
7
|
-
// Accordions
|
|
8
|
-
export { Accordion } from "./components/basic/Accordation"; // ✅ Finalized
|
|
9
|
-
// Avatars
|
|
10
|
-
export { Avatar } from "./components/basic/Avatar"; // ✅ Finalized
|
|
11
|
-
// Audio Components
|
|
12
|
-
export { AudioPlayer } from "./components/basic/AudioPlayer"; // ✅ Finalized
|
|
13
|
-
export { AudioGallery } from "./components/basic/AudioGallery"; // ✅ Finalized
|
|
14
|
-
// Badges
|
|
15
|
-
export { Badge } from "./components/basic/Badge"; // ✅ Finalized
|
|
16
|
-
// Buttons
|
|
17
|
-
export { Button } from "./components/basic/Button"; // ✅ Finalized
|
|
18
|
-
// ✅ Checkbox, Radio & Switch Components
|
|
19
|
-
export { CheckboxGroup } from "./components/basic/CheckboxGroup";
|
|
20
|
-
export { RadioGroup } from "./components/basic/RadioGroup";
|
|
21
|
-
export { SwitchGroup } from "./components/basic/SwitchGroup";
|
|
22
|
-
// Containers & Layout
|
|
23
|
-
export { Container } from "./components/basic/Container"; // ✅ Finalized
|
|
24
|
-
export { FlexView } from "./components/basic/FlexView"; // ✅ Finalized
|
|
25
|
-
export { Stack, HStack, VStack } from "./components/basic/Stack"; // ✅ Finalized
|
|
26
|
-
export { GridView } from "./components/basic/GridView"; // ✅ Finalized
|
|
27
|
-
// Drawers
|
|
28
|
-
export { Drawer, DrawerButton } from "./components/basic/Drawer"; // ✅ Finalized
|
|
29
|
-
// Dropdowns
|
|
30
|
-
export { Dropdown } from "./components/basic/DropDown"; // ✅ Finalized
|
|
31
|
-
// Forms & Inputs
|
|
32
|
-
export { Input } from "./components/basic/Input"; // ✅ Finalized
|
|
33
|
-
// Images
|
|
34
|
-
export { Image } from "./components/basic/Image"; // ✅ Finalized
|
|
35
|
-
// Lists
|
|
36
|
-
export { List } from "./components/basic/List"; // ✅ Finalized
|
|
37
|
-
// Modals
|
|
38
|
-
export { Modal } from "./components/basic/Modal"; // ✅ Finalized
|
|
39
|
-
// Tables
|
|
40
|
-
export { Table, TBody, TD, THead, TH, TRow } from "./components/basic/Table"; // ✅ Finalized
|
|
41
|
-
// Tabs
|
|
42
|
-
export { Tabs } from "./components/basic/Tabs"; // ✅ Finalized
|
|
43
|
-
// Text
|
|
44
|
-
export { Text } from "./components/basic/Text"; // ✅ Finalized
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import React, { ReactNode, CSSProperties } from "react";
|
|
2
|
-
export interface AccordionItem {
|
|
3
|
-
title: string | ReactNode;
|
|
4
|
-
content: ReactNode;
|
|
5
|
-
}
|
|
6
|
-
export interface AccordionProps {
|
|
7
|
-
items: AccordionItem[];
|
|
8
|
-
allowMultiple?: boolean;
|
|
9
|
-
defaultOpen?: number[];
|
|
10
|
-
/** Appearance */
|
|
11
|
-
borderColor?: string;
|
|
12
|
-
backgroundColor?: string;
|
|
13
|
-
textColor?: string;
|
|
14
|
-
hoverBgColor?: string;
|
|
15
|
-
hoverTextColor?: string;
|
|
16
|
-
contentBgColor?: string;
|
|
17
|
-
contentTextColor?: string;
|
|
18
|
-
/** Layout & spacing */
|
|
19
|
-
paddingY?: string | number;
|
|
20
|
-
paddingX?: string | number;
|
|
21
|
-
marginY?: string | number;
|
|
22
|
-
borderRadius?: string | number;
|
|
23
|
-
contentPadding?: string | number;
|
|
24
|
-
/** Typography */
|
|
25
|
-
fontSize?: string | number;
|
|
26
|
-
fontWeight?: string | number;
|
|
27
|
-
contentFontSize?: string | number;
|
|
28
|
-
contentFontWeight?: string | number;
|
|
29
|
-
/** Icon */
|
|
30
|
-
iconOpen?: ReactNode;
|
|
31
|
-
iconClose?: ReactNode;
|
|
32
|
-
iconSize?: string | number;
|
|
33
|
-
/** Motion */
|
|
34
|
-
transitionDuration?: string;
|
|
35
|
-
shadow?: string;
|
|
36
|
-
/** Class overrides */
|
|
37
|
-
className?: string;
|
|
38
|
-
style?: CSSProperties;
|
|
39
|
-
}
|
|
40
|
-
export declare const Accordion: React.FC<AccordionProps>;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import React, { ReactNode } from "react";
|
|
2
|
-
type AlertType = "success" | "error" | "warning" | "info";
|
|
3
|
-
interface Toast {
|
|
4
|
-
id: number;
|
|
5
|
-
title?: string;
|
|
6
|
-
description?: string;
|
|
7
|
-
type?: AlertType;
|
|
8
|
-
duration?: number;
|
|
9
|
-
}
|
|
10
|
-
interface ToastContextProps {
|
|
11
|
-
addToast: (toast: Omit<Toast, "id">) => void;
|
|
12
|
-
}
|
|
13
|
-
export declare const useToast: () => ToastContextProps;
|
|
14
|
-
export declare const ToastProvider: React.FC<{
|
|
15
|
-
children: ReactNode;
|
|
16
|
-
}>;
|
|
17
|
-
export {};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
interface AudioTrack {
|
|
2
|
-
src: string;
|
|
3
|
-
title: string;
|
|
4
|
-
artist?: string;
|
|
5
|
-
thumbnail?: string;
|
|
6
|
-
duration?: string;
|
|
7
|
-
}
|
|
8
|
-
interface AudioGalleryProps {
|
|
9
|
-
tracks?: AudioTrack[];
|
|
10
|
-
className?: string;
|
|
11
|
-
galleryTitle?: string;
|
|
12
|
-
primaryColor?: string;
|
|
13
|
-
backgroundColor?: string;
|
|
14
|
-
textColor?: string;
|
|
15
|
-
secondaryColor?: string;
|
|
16
|
-
autoplay?: boolean;
|
|
17
|
-
borderColor?: string;
|
|
18
|
-
border?: number;
|
|
19
|
-
maxWidth?: number;
|
|
20
|
-
loop?: boolean;
|
|
21
|
-
}
|
|
22
|
-
export declare function AudioGallery({ tracks, className, galleryTitle, primaryColor, backgroundColor, textColor, secondaryColor, border, borderColor, maxWidth, autoplay, loop, }: AudioGalleryProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
-
export {};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
interface AudioPlayerProps {
|
|
3
|
-
src: string;
|
|
4
|
-
thumbnail?: string;
|
|
5
|
-
autoPlay?: boolean;
|
|
6
|
-
loop?: boolean;
|
|
7
|
-
backgroundColor?: string;
|
|
8
|
-
primaryColor?: string;
|
|
9
|
-
secondaryColor?: string;
|
|
10
|
-
borderRadius?: string;
|
|
11
|
-
className?: string;
|
|
12
|
-
padding?: string;
|
|
13
|
-
width?: string;
|
|
14
|
-
}
|
|
15
|
-
export declare const AudioPlayer: React.FC<AudioPlayerProps>;
|
|
16
|
-
export {};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import React, { CSSProperties } from "react";
|
|
2
|
-
type AvatarSize = "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "responsive";
|
|
3
|
-
type AvatarVariant = "circular" | "rounded" | "square";
|
|
4
|
-
type StatusPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";
|
|
5
|
-
interface AvatarProps {
|
|
6
|
-
src?: string;
|
|
7
|
-
alt?: string;
|
|
8
|
-
size?: AvatarSize;
|
|
9
|
-
variant?: AvatarVariant;
|
|
10
|
-
isOnline?: boolean;
|
|
11
|
-
isOffline?: boolean;
|
|
12
|
-
ring?: boolean;
|
|
13
|
-
ringColor?: string;
|
|
14
|
-
fallback?: string;
|
|
15
|
-
onClick?: () => void;
|
|
16
|
-
statusPosition?: StatusPosition;
|
|
17
|
-
className?: string;
|
|
18
|
-
statusClassName?: string;
|
|
19
|
-
style?: CSSProperties;
|
|
20
|
-
statusStyle?: CSSProperties;
|
|
21
|
-
}
|
|
22
|
-
export declare const Avatar: React.FC<AvatarProps>;
|
|
23
|
-
export {};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
export interface BadgeProps {
|
|
3
|
-
text?: string;
|
|
4
|
-
icon?: React.ReactNode;
|
|
5
|
-
iconPosition?: "left" | "right";
|
|
6
|
-
/** 🎨 Theme */
|
|
7
|
-
primaryTheme?: boolean;
|
|
8
|
-
primaryColor?: string;
|
|
9
|
-
/** 📏 Sizes */
|
|
10
|
-
size?: "sm" | "md" | "lg";
|
|
11
|
-
/** Shape */
|
|
12
|
-
rounded?: boolean;
|
|
13
|
-
/** Notification */
|
|
14
|
-
notificationDot?: boolean;
|
|
15
|
-
dotColor?: string;
|
|
16
|
-
count?: number | string;
|
|
17
|
-
pulse?: boolean;
|
|
18
|
-
className?: string;
|
|
19
|
-
onClick?: () => void;
|
|
20
|
-
}
|
|
21
|
-
export declare const Badge: React.FC<BadgeProps>;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
3
|
-
children: React.ReactNode;
|
|
4
|
-
iconBefore?: React.ReactNode;
|
|
5
|
-
iconAfter?: React.ReactNode;
|
|
6
|
-
loading?: boolean;
|
|
7
|
-
loadingText?: string;
|
|
8
|
-
fullWidth?: boolean;
|
|
9
|
-
/** 🎨 Variants (shadcn style) */
|
|
10
|
-
variant?: "default" | "outline" | "ghost";
|
|
11
|
-
/** 📏 Sizes */
|
|
12
|
-
size?: "sm" | "md" | "lg";
|
|
13
|
-
className?: string;
|
|
14
|
-
}
|
|
15
|
-
export declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
interface Option {
|
|
3
|
-
label: string;
|
|
4
|
-
value: string;
|
|
5
|
-
}
|
|
6
|
-
interface CheckboxGroupProps {
|
|
7
|
-
name?: string;
|
|
8
|
-
options: Option[];
|
|
9
|
-
selectedValues?: string[];
|
|
10
|
-
onChange?: (values: string[]) => void;
|
|
11
|
-
disabled?: boolean;
|
|
12
|
-
readOnly?: boolean;
|
|
13
|
-
required?: boolean;
|
|
14
|
-
error?: string;
|
|
15
|
-
className?: string;
|
|
16
|
-
customIcon?: (checked: boolean) => React.ReactNode;
|
|
17
|
-
style?: React.CSSProperties;
|
|
18
|
-
labelStyle?: React.CSSProperties;
|
|
19
|
-
iconSize?: number;
|
|
20
|
-
iconCheckedBgColor?: string;
|
|
21
|
-
iconUncheckedBorderColor?: string;
|
|
22
|
-
textColor?: string;
|
|
23
|
-
errorStyle?: React.CSSProperties;
|
|
24
|
-
darkMode?: boolean;
|
|
25
|
-
}
|
|
26
|
-
export declare const CheckboxGroup: React.FC<CheckboxGroupProps>;
|
|
27
|
-
export {};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
type Breakpoint = "sm" | "md" | "lg" | "xl" | "2xl";
|
|
3
|
-
type Responsive<T> = T | Partial<Record<Breakpoint, T>>;
|
|
4
|
-
type ContainerSize = "sm" | "md" | "lg" | "xl" | "2xl" | "full";
|
|
5
|
-
type DisplayType = "block" | "flex" | "grid";
|
|
6
|
-
export interface ContainerProps {
|
|
7
|
-
size?: Responsive<ContainerSize>;
|
|
8
|
-
padding?: Responsive<"none" | "sm" | "md" | "lg" | "xl">;
|
|
9
|
-
center?: boolean;
|
|
10
|
-
display?: DisplayType;
|
|
11
|
-
direction?: Responsive<"row" | "col" | "row-reverse" | "col-reverse">;
|
|
12
|
-
align?: Responsive<"start" | "center" | "end" | "stretch">;
|
|
13
|
-
justify?: Responsive<"start" | "center" | "end" | "between" | "around" | "evenly">;
|
|
14
|
-
wrap?: Responsive<"wrap" | "nowrap">;
|
|
15
|
-
cols?: Responsive<number>;
|
|
16
|
-
gap?: Responsive<"none" | "sm" | "md" | "lg" | "xl">;
|
|
17
|
-
className?: string;
|
|
18
|
-
children: React.ReactNode;
|
|
19
|
-
}
|
|
20
|
-
export declare const Container: React.FC<ContainerProps>;
|
|
21
|
-
export default Container;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import React, { ReactNode } from "react";
|
|
2
|
-
interface DrawerButtonProps {
|
|
3
|
-
label?: string;
|
|
4
|
-
icon?: ReactNode;
|
|
5
|
-
iconPosition?: "left" | "right";
|
|
6
|
-
onClick?: () => void;
|
|
7
|
-
className?: string;
|
|
8
|
-
}
|
|
9
|
-
export declare const DrawerButton: React.FC<DrawerButtonProps>;
|
|
10
|
-
interface DrawerProps {
|
|
11
|
-
open: boolean;
|
|
12
|
-
onClose?: () => void;
|
|
13
|
-
position?: "left" | "right" | "top" | "bottom";
|
|
14
|
-
size?: string;
|
|
15
|
-
className?: string;
|
|
16
|
-
overlayClassName?: string;
|
|
17
|
-
children?: ReactNode;
|
|
18
|
-
showCloseButton?: boolean;
|
|
19
|
-
closeButtonClassName?: string;
|
|
20
|
-
}
|
|
21
|
-
export declare const Drawer: React.FC<DrawerProps>;
|
|
22
|
-
export {};
|