@sanvika/ui 0.1.3 → 0.1.5
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/EmailIcon-DumDw7u2.js +781 -0
- package/dist/EmailIcon-ssF1iAVu.js +782 -0
- package/dist/icons/index.js +4 -0
- package/dist/index.js +555 -0
- package/package.json +16 -20
- package/src/components/buttons/Button.jsx +0 -96
- package/src/components/buttons/FavoriteHeartButton.jsx +0 -41
- package/src/components/buttons/ScrollButton.jsx +0 -36
- package/src/components/buttons/ThreeDotButton.jsx +0 -36
- package/src/components/common/Container.jsx +0 -38
- package/src/components/common/Section.jsx +0 -60
- package/src/components/icons/BellIcon.jsx +0 -10
- package/src/components/icons/ChevronDown.jsx +0 -20
- package/src/components/icons/EmailIcon.jsx +0 -9
- package/src/components/icons/FaAngleDown.jsx +0 -9
- package/src/components/icons/FaAngleRight.jsx +0 -9
- package/src/components/icons/FaArrowDown.jsx +0 -9
- package/src/components/icons/FaArrowLeft.jsx +0 -9
- package/src/components/icons/FaArrowUp.jsx +0 -9
- package/src/components/icons/FaBell.jsx +0 -9
- package/src/components/icons/FaBullhorn.jsx +0 -10
- package/src/components/icons/FaCalendarAlt.jsx +0 -9
- package/src/components/icons/FaCheck.jsx +0 -9
- package/src/components/icons/FaCheckCircle.jsx +0 -9
- package/src/components/icons/FaCheckDouble.jsx +0 -9
- package/src/components/icons/FaChevronDown.jsx +0 -9
- package/src/components/icons/FaChevronRight.jsx +0 -9
- package/src/components/icons/FaCircle.jsx +0 -9
- package/src/components/icons/FaComments.jsx +0 -9
- package/src/components/icons/FaEye.jsx +0 -9
- package/src/components/icons/FaEyeSlash.jsx +0 -9
- package/src/components/icons/FaHome.jsx +0 -9
- package/src/components/icons/FaKeyboard.jsx +0 -9
- package/src/components/icons/FaLocationArrow.jsx +0 -9
- package/src/components/icons/FaMapMarkerAlt.jsx +0 -9
- package/src/components/icons/FaMoon.jsx +0 -9
- package/src/components/icons/FaPaperPlane.jsx +0 -9
- package/src/components/icons/FaPaperclip.jsx +0 -9
- package/src/components/icons/FaSignInAlt.jsx +0 -9
- package/src/components/icons/FaSmile.jsx +0 -9
- package/src/components/icons/FaStar.jsx +0 -9
- package/src/components/icons/FaTag.jsx +0 -9
- package/src/components/icons/FaThumbsDown.jsx +0 -9
- package/src/components/icons/FaThumbsUp.jsx +0 -9
- package/src/components/icons/FaTrash.jsx +0 -9
- package/src/components/icons/FaUser.jsx +0 -9
- package/src/components/icons/FaUserCircle.jsx +0 -9
- package/src/components/icons/FacebookIcon.jsx +0 -9
- package/src/components/icons/HalfMoonIcon.jsx +0 -18
- package/src/components/icons/HeartIcon.jsx +0 -9
- package/src/components/icons/InstagramIcon.jsx +0 -9
- package/src/components/icons/LinkedInIcon.jsx +0 -9
- package/src/components/icons/MapMarkerIcon.jsx +0 -9
- package/src/components/icons/MdWbSunny.jsx +0 -9
- package/src/components/icons/ReFreshIcon.jsx +0 -49
- package/src/components/icons/SearchIcon.jsx +0 -20
- package/src/components/icons/StarIcon.jsx +0 -9
- package/src/components/icons/TelegramIcon.jsx +0 -9
- package/src/components/icons/TwitterIcon.jsx +0 -9
- package/src/components/icons/UserIcon.jsx +0 -9
- package/src/components/icons/WhatsappIcon.jsx +0 -9
- package/src/components/icons/YoutubeIcon.jsx +0 -9
- package/src/components/icons/index.js +0 -60
- package/src/components/layout/Footer.jsx +0 -53
- package/src/components/layout/Navbar.jsx +0 -50
- package/src/components/layout/SubNavbar.jsx +0 -36
- package/src/components/modals/Modal.jsx +0 -74
- package/src/components/progressBar/ProgressBar.jsx +0 -113
- package/src/context/ThemeContext.jsx +0 -91
- package/src/index.js +0 -30
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
// src/components/progressBar/ProgressBar.jsx
|
|
3
|
-
import React, { useEffect, useRef, useState } from "react";
|
|
4
|
-
import styles from "../../styles/components/progressBar/ProgressBar.module.css";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* ProgressBar — animated, pure props-driven progress indicator.
|
|
8
|
-
*
|
|
9
|
-
* @param {number} [progress=0] - 0 to 100
|
|
10
|
-
* @param {number} [height=6] - bar height in px
|
|
11
|
-
* @param {string} [color] - CSS color or var() for the filled bar
|
|
12
|
-
* @param {string} [backgroundColor] - CSS color or var() for the track
|
|
13
|
-
* @param {boolean} [animate=true] - smooth animation
|
|
14
|
-
* @param {number} [speed=300] - animation base duration in ms
|
|
15
|
-
* @param {boolean} [showLabel=false] - show percentage label
|
|
16
|
-
* @param {"top"|"bottom"} [labelPosition="top"]
|
|
17
|
-
* @param {function} [onComplete] - called when progress reaches 100
|
|
18
|
-
* @param {string} [className]
|
|
19
|
-
* @param {object} [style]
|
|
20
|
-
*/
|
|
21
|
-
const ProgressBar = ({
|
|
22
|
-
progress = 0,
|
|
23
|
-
height = 6,
|
|
24
|
-
color = "var(--primary-color, #007bff)",
|
|
25
|
-
backgroundColor = "var(--progress-bg, rgba(0, 0, 0, 0.1))",
|
|
26
|
-
animate = true,
|
|
27
|
-
speed = 300,
|
|
28
|
-
showLabel = false,
|
|
29
|
-
labelPosition = "top",
|
|
30
|
-
onComplete = null,
|
|
31
|
-
className = "",
|
|
32
|
-
style = {},
|
|
33
|
-
}) => {
|
|
34
|
-
const [animatedProgress, setAnimatedProgress] = useState(0);
|
|
35
|
-
const rafIdRef = useRef(null);
|
|
36
|
-
const startRef = useRef(0);
|
|
37
|
-
const endRef = useRef(progress);
|
|
38
|
-
const startTimeRef = useRef(null);
|
|
39
|
-
const completedRef = useRef(false);
|
|
40
|
-
|
|
41
|
-
const easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);
|
|
42
|
-
|
|
43
|
-
useEffect(() => {
|
|
44
|
-
if (!animate) return;
|
|
45
|
-
startRef.current = animatedProgress;
|
|
46
|
-
}, [animatedProgress, animate]);
|
|
47
|
-
|
|
48
|
-
useEffect(() => {
|
|
49
|
-
if (!animate) return; // non-animated: use progress directly via clampedProgress below
|
|
50
|
-
if (rafIdRef.current) cancelAnimationFrame(rafIdRef.current);
|
|
51
|
-
endRef.current = progress;
|
|
52
|
-
startTimeRef.current = null;
|
|
53
|
-
if (startRef.current === endRef.current) return;
|
|
54
|
-
|
|
55
|
-
const delta = Math.abs(endRef.current - startRef.current);
|
|
56
|
-
const duration = Math.max(speed, Math.min(1500, 20 * delta));
|
|
57
|
-
|
|
58
|
-
const step = (ts) => {
|
|
59
|
-
if (startTimeRef.current === null) startTimeRef.current = ts;
|
|
60
|
-
const elapsed = ts - startTimeRef.current;
|
|
61
|
-
const t = Math.max(0, Math.min(1, elapsed / duration));
|
|
62
|
-
const eased = easeOutCubic(t);
|
|
63
|
-
const next = startRef.current + (endRef.current - startRef.current) * eased;
|
|
64
|
-
setAnimatedProgress(next);
|
|
65
|
-
if (t < 1) {
|
|
66
|
-
rafIdRef.current = requestAnimationFrame(step);
|
|
67
|
-
} else {
|
|
68
|
-
setAnimatedProgress(endRef.current);
|
|
69
|
-
if (endRef.current >= 100 && onComplete && !completedRef.current) {
|
|
70
|
-
completedRef.current = true;
|
|
71
|
-
onComplete();
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
rafIdRef.current = requestAnimationFrame(step);
|
|
76
|
-
return () => {
|
|
77
|
-
if (rafIdRef.current) cancelAnimationFrame(rafIdRef.current);
|
|
78
|
-
};
|
|
79
|
-
}, [progress, animate, speed, onComplete]);
|
|
80
|
-
|
|
81
|
-
// When not animated, use progress directly; when animated, use animatedProgress
|
|
82
|
-
const clampedProgress = Math.max(0, Math.min(100, animate ? animatedProgress : progress));
|
|
83
|
-
const label = `${Math.round(clampedProgress)}%`;
|
|
84
|
-
|
|
85
|
-
return (
|
|
86
|
-
<div
|
|
87
|
-
className={`${styles.wrapper} ${className}`}
|
|
88
|
-
style={style}
|
|
89
|
-
role="progressbar"
|
|
90
|
-
aria-valuenow={Math.round(clampedProgress)}
|
|
91
|
-
aria-valuemin={0}
|
|
92
|
-
aria-valuemax={100}
|
|
93
|
-
>
|
|
94
|
-
{showLabel && labelPosition === "top" && (
|
|
95
|
-
<span className={styles.label}>{label}</span>
|
|
96
|
-
)}
|
|
97
|
-
<div
|
|
98
|
-
className={styles.track}
|
|
99
|
-
style={{ height, backgroundColor }}
|
|
100
|
-
>
|
|
101
|
-
<div
|
|
102
|
-
className={styles.bar}
|
|
103
|
-
style={{ width: `${clampedProgress}%`, background: color }}
|
|
104
|
-
/>
|
|
105
|
-
</div>
|
|
106
|
-
{showLabel && labelPosition === "bottom" && (
|
|
107
|
-
<span className={styles.label}>{label}</span>
|
|
108
|
-
)}
|
|
109
|
-
</div>
|
|
110
|
-
);
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
export default ProgressBar;
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
// src/context/ThemeContext.jsx
|
|
3
|
-
import {
|
|
4
|
-
createContext,
|
|
5
|
-
useContext,
|
|
6
|
-
useEffect,
|
|
7
|
-
useState,
|
|
8
|
-
useCallback,
|
|
9
|
-
} from "react";
|
|
10
|
-
|
|
11
|
-
const ThemeContext = createContext();
|
|
12
|
-
|
|
13
|
-
export const ThemeProvider = ({ children }) => {
|
|
14
|
-
const [mounted, setMounted] = useState(false);
|
|
15
|
-
const [theme, setTheme] = useState("light"); // SSR fallback
|
|
16
|
-
|
|
17
|
-
// Step 1: On mount, load theme from localStorage. Default = dark.
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
try {
|
|
20
|
-
const saved = localStorage.getItem("theme");
|
|
21
|
-
const resolved = saved ?? "dark"; // First visit = dark
|
|
22
|
-
setTheme(resolved);
|
|
23
|
-
document.documentElement.setAttribute("data-theme", resolved);
|
|
24
|
-
|
|
25
|
-
// Listen for OS-level theme changes only if user has not set a preference
|
|
26
|
-
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
27
|
-
const onSystemChange = (e) => {
|
|
28
|
-
if (!localStorage.getItem("theme")) {
|
|
29
|
-
const sys = e.matches ? "dark" : "light";
|
|
30
|
-
setTheme(sys);
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
mq.addEventListener("change", onSystemChange);
|
|
34
|
-
setMounted(true);
|
|
35
|
-
return () => mq.removeEventListener("change", onSystemChange);
|
|
36
|
-
} catch {
|
|
37
|
-
setTheme("dark");
|
|
38
|
-
document.documentElement.setAttribute("data-theme", "dark");
|
|
39
|
-
setMounted(true);
|
|
40
|
-
}
|
|
41
|
-
}, []);
|
|
42
|
-
|
|
43
|
-
// Step 2: Apply theme with smooth transition class
|
|
44
|
-
const applyTheme = useCallback((next) => {
|
|
45
|
-
const root = document.documentElement;
|
|
46
|
-
root.classList.add("theme-transition");
|
|
47
|
-
root.setAttribute("data-theme", next);
|
|
48
|
-
localStorage.setItem("theme", next);
|
|
49
|
-
const t = setTimeout(() => root.classList.remove("theme-transition"), 300);
|
|
50
|
-
return () => clearTimeout(t);
|
|
51
|
-
}, []);
|
|
52
|
-
|
|
53
|
-
// Step 3: Apply whenever theme state changes (after mount)
|
|
54
|
-
useEffect(() => {
|
|
55
|
-
if (mounted) applyTheme(theme);
|
|
56
|
-
}, [theme, mounted, applyTheme]);
|
|
57
|
-
|
|
58
|
-
// Step 4: Toggle
|
|
59
|
-
const toggleTheme = useCallback(() => {
|
|
60
|
-
setTheme((prev) => (prev === "light" ? "dark" : "light"));
|
|
61
|
-
}, []);
|
|
62
|
-
|
|
63
|
-
// Step 5: Explicit setter (for admin/testing)
|
|
64
|
-
const setThemeExplicitly = useCallback((next) => {
|
|
65
|
-
if (next !== "light" && next !== "dark") return;
|
|
66
|
-
setTheme(next);
|
|
67
|
-
}, []);
|
|
68
|
-
|
|
69
|
-
// React 19 direct context syntax
|
|
70
|
-
return (
|
|
71
|
-
<ThemeContext
|
|
72
|
-
value={{
|
|
73
|
-
theme,
|
|
74
|
-
toggleTheme,
|
|
75
|
-
setTheme: setThemeExplicitly,
|
|
76
|
-
isDarkMode: theme === "dark",
|
|
77
|
-
isThemeReady: mounted,
|
|
78
|
-
}}
|
|
79
|
-
>
|
|
80
|
-
{children}
|
|
81
|
-
</ThemeContext>
|
|
82
|
-
);
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
export const useTheme = () => {
|
|
86
|
-
const ctx = useContext(ThemeContext);
|
|
87
|
-
if (!ctx) throw new Error("useTheme must be used inside ThemeProvider");
|
|
88
|
-
return ctx;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
export { ThemeContext };
|
package/src/index.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// src/index.js
|
|
2
|
-
// @sanvika/ui — main barrel export
|
|
3
|
-
// Import this in your project: import { Button, Modal, Navbar, ... } from "@sanvika/ui"
|
|
4
|
-
|
|
5
|
-
// ─── Layout ──────────────────────────────────────────────────────────────────
|
|
6
|
-
export { default as Navbar } from "./components/layout/Navbar.jsx";
|
|
7
|
-
export { default as SubNavbar } from "./components/layout/SubNavbar.jsx";
|
|
8
|
-
export { default as Footer } from "./components/layout/Footer.jsx";
|
|
9
|
-
|
|
10
|
-
// ─── Buttons ─────────────────────────────────────────────────────────────────
|
|
11
|
-
export { default as Button } from "./components/buttons/Button.jsx";
|
|
12
|
-
export { default as FavoriteHeartButton } from "./components/buttons/FavoriteHeartButton.jsx";
|
|
13
|
-
export { default as ScrollButton } from "./components/buttons/ScrollButton.jsx";
|
|
14
|
-
export { default as ThreeDotButton } from "./components/buttons/ThreeDotButton.jsx";
|
|
15
|
-
|
|
16
|
-
// ─── Common ──────────────────────────────────────────────────────────────────
|
|
17
|
-
export { default as Container } from "./components/common/Container.jsx";
|
|
18
|
-
export { default as Section } from "./components/common/Section.jsx";
|
|
19
|
-
|
|
20
|
-
// ─── Modals ──────────────────────────────────────────────────────────────────
|
|
21
|
-
export { default as Modal } from "./components/modals/Modal.jsx";
|
|
22
|
-
|
|
23
|
-
// ─── ProgressBar ─────────────────────────────────────────────────────────────
|
|
24
|
-
export { default as ProgressBar } from "./components/progressBar/ProgressBar.jsx";
|
|
25
|
-
|
|
26
|
-
// ─── Icons (re-exported from icons barrel) ───────────────────────────────────
|
|
27
|
-
export * from "./components/icons/index.js";
|
|
28
|
-
|
|
29
|
-
// ─── Theme Context ────────────────────────────────────────────────────────────
|
|
30
|
-
export { ThemeProvider, useTheme } from "./context/ThemeContext.jsx";
|