@gohanfromgoku/ui-kit 0.0.2 → 0.0.4

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/api/index.js CHANGED
@@ -1 +1,82 @@
1
- export const METHODS={GET:"GET",POST:"POST",PUT:"PUT",DELETE:"DELETE"};const appendParams=(t,e)=>{if(!e)return t;const s=new URLSearchParams({...e}).toString();return s?`${t}?${s}`:t},parseResponse=async t=>{const e=t.headers.get("content-type")||"";return e.includes("application/json")?await t.json().catch(()=>null):e.includes("text/")?await t.text():await t.blob().catch(()=>null)},baseHeaders={"Content-Type":"application/json"};export class API{baseURL;constructor(t){this.baseURL=t.replace(/\/+$/,"")}createURL(t){return t.startsWith("http")?t:"/"===t||""===t?this.baseURL:t.startsWith("/")?`${this.baseURL}${t}`:`${this.baseURL}/${t}`}async request(t,e,s={}){const{params:a,headers:r,body:n,signal:i}=s,o=appendParams(this.createURL(e),a),c=n instanceof FormData||t===METHODS.GET?{...r}:{...baseHeaders,...r},T=await fetch(o,{method:t,body:n?n instanceof FormData||"string"==typeof n?n:JSON.stringify(n):void 0,headers:c,signal:i}),E=await parseResponse(T);if(!T.ok)throw E;return E}GET=(t,e)=>this.request(METHODS.GET,t,e);POST=(t,e)=>this.request(METHODS.POST,t,e);PUT=(t,e)=>this.request(METHODS.PUT,t,e);DELETE=(t,e)=>this.request(METHODS.DELETE,t,e)}
1
+ export const METHODS = {
2
+ GET: "GET",
3
+ POST: "POST",
4
+ PUT: "PUT",
5
+ DELETE: "DELETE"
6
+ };
7
+ const appendParams = (url, params) => {
8
+ if (!params)
9
+ return url;
10
+ const urlParams = new URLSearchParams({ ...params }).toString();
11
+ return urlParams ? `${url}?${urlParams}` : url;
12
+ };
13
+ const parseResponse = async (res) => {
14
+ const contentType = res.headers.get("content-type") || "";
15
+ if (contentType.includes("application/json")) {
16
+ return await res.json().catch(() => null);
17
+ }
18
+ if (contentType.includes("text/")) {
19
+ return await res.text();
20
+ }
21
+ return await res.blob().catch(() => null);
22
+ };
23
+ export class API {
24
+ baseURL;
25
+ defaultHeaders = {};
26
+ timeout = 0;
27
+ constructor(baseURL, headers = {}, timeout = 0) {
28
+ this.baseURL = baseURL.replace(/\/+$/, "");
29
+ this.defaultHeaders = { "Content-Type": "application/json", ...headers };
30
+ this.timeout = timeout;
31
+ }
32
+ createURL(endpoint) {
33
+ if (endpoint.startsWith("http"))
34
+ return endpoint;
35
+ if (endpoint === "/" || endpoint === "")
36
+ return this.baseURL;
37
+ if (endpoint.startsWith("/"))
38
+ return `${this.baseURL}${endpoint}`;
39
+ return `${this.baseURL}/${endpoint}`;
40
+ }
41
+ async request(method, endpoint, opts = {}) {
42
+ const { params, headers, body, signal } = opts;
43
+ const url = appendParams(this.createURL(endpoint), params);
44
+ const headersWithDefaults = body instanceof FormData || method === METHODS.GET ? { ...headers } : { ...this.defaultHeaders, ...headers };
45
+ const fetchBody = body ? body instanceof FormData || typeof body === "string" ? body : JSON.stringify(body) : undefined;
46
+ const fetchAbortController = new AbortController();
47
+ const onAbort = () => fetchAbortController.abort();
48
+ let timeoutId = null;
49
+ try {
50
+ if (this.timeout > 0) {
51
+ timeoutId = setTimeout(onAbort, this.timeout);
52
+ }
53
+ if (signal) {
54
+ signal.addEventListener("abort", onAbort);
55
+ }
56
+ const res = await fetch(url, {
57
+ method,
58
+ body: fetchBody,
59
+ headers: headersWithDefaults,
60
+ signal: fetchAbortController.signal,
61
+ });
62
+ const data = await parseResponse(res);
63
+ if (!res.ok)
64
+ throw data || new Error(res.statusText);
65
+ return data;
66
+ }
67
+ catch (error) {
68
+ console.error(`${method}: ${endpoint} :: `, error);
69
+ throw error;
70
+ }
71
+ finally {
72
+ if (timeoutId)
73
+ clearTimeout(timeoutId);
74
+ if (signal)
75
+ signal.removeEventListener("abort", onAbort);
76
+ }
77
+ }
78
+ GET = (endpoint, opts) => this.request(METHODS.GET, endpoint, opts);
79
+ POST = (endpoint, opts) => this.request(METHODS.POST, endpoint, opts);
80
+ PUT = (endpoint, opts) => this.request(METHODS.PUT, endpoint, opts);
81
+ DELETE = (endpoint, opts) => this.request(METHODS.DELETE, endpoint, opts);
82
+ }
@@ -1 +1,21 @@
1
- import{jsx as _jsx}from"preact/jsx-runtime";import{memo,forwardRef}from"preact/compat";import checkProps from"../../helpers/checkProps";const defaultProps={onClick:()=>{},disabled:!1,className:"",type:"button"},Button=forwardRef((e,t)=>{const{children:o,className:r,onClick:s,disabled:c,type:a,...p}={...defaultProps,...e};return _jsx("button",{ref:t,className:r,onClick:e=>{"button"!==a&&a||e.preventDefault(),!c&&s&&s(e)},...p,children:o})});export default memo(Button,checkProps);
1
+ import { jsx as _jsx } from "preact/jsx-runtime";
2
+ import { memo, forwardRef } from "preact/compat";
3
+ import checkProps from "../../helpers/checkProps";
4
+ const defaultProps = {
5
+ onClick: () => { },
6
+ disabled: false,
7
+ className: "",
8
+ type: "button",
9
+ };
10
+ const Button = forwardRef((props, ref) => {
11
+ const { children, className, onClick, disabled, type, ...rest } = { ...defaultProps, ...props };
12
+ return (_jsx("button", { ref: ref, className: className, onClick: (event) => {
13
+ if (type === "button" || !type) {
14
+ event.preventDefault();
15
+ }
16
+ if (!disabled && onClick) {
17
+ onClick(event);
18
+ }
19
+ }, ...rest, children: children }));
20
+ });
21
+ export default memo(Button, checkProps);
@@ -1 +1,19 @@
1
- import{jsx as _jsx}from"preact/jsx-runtime";import{forwardRef,memo}from"preact/compat";import checkProps from"../../helpers/checkProps";const defaultProps={altImage:null,className:"",alt:"",priority:!0,onClick:()=>{}},Image=forwardRef((r,e)=>{const{altImage:a,className:t,src:o,priority:c,onClick:s,alt:l,...m}={...defaultProps,...r};return _jsx("img",{src:o,ref:e,width:"100%",height:"100%",onClick:r=>{r.preventDefault(),s(r)},draggable:!1,onError:async()=>{e&&"current"in e&&e.current&&(e.current.src=a||"")},alt:l,className:t,fetchPriority:c?"high":"auto",loading:c?"eager":"lazy",...m})});export default memo(Image,checkProps);
1
+ import { jsx as _jsx } from "preact/jsx-runtime";
2
+ import { forwardRef, memo } from "preact/compat";
3
+ import checkProps from "../../helpers/checkProps";
4
+ const defaultProps = {
5
+ altImage: null,
6
+ className: "",
7
+ alt: "",
8
+ priority: true,
9
+ onClick: () => { }
10
+ };
11
+ const Image = forwardRef((props, ref) => {
12
+ const { altImage, className, src, priority, onClick, alt, ...rest } = { ...defaultProps, ...props };
13
+ return (_jsx("img", { src: src, ref: ref, width: "100%", height: "100%", onClick: (event) => { event.preventDefault(); onClick(event); }, draggable: false, onError: async () => {
14
+ if (ref && 'current' in ref && ref.current) {
15
+ ref.current.src = altImage || "";
16
+ }
17
+ }, alt: alt, className: className, fetchPriority: priority ? "high" : "auto", loading: priority ? "eager" : "lazy", ...rest }));
18
+ });
19
+ export default memo(Image, checkProps);
@@ -1 +1,16 @@
1
- import{jsx as _jsx}from"preact/jsx-runtime";import{memo}from"preact/compat";import checkProps from"../../helpers/checkProps";import{translate}from"../../translations/index";const defaultProps={onChange:()=>{},className:"",placeholder:"",type:"text",name:""},Input=e=>{const{onChange:t,className:a,placeholder:r,type:o,name:p,...s}={...defaultProps,...e};return _jsx("input",{className:a,placeholder:translate(r),type:o,name:p,onChange:e=>t(e.currentTarget.value,e),...s})};export default memo(Input,checkProps);
1
+ import { jsx as _jsx } from "preact/jsx-runtime";
2
+ import { memo } from "preact/compat";
3
+ import checkProps from "../../helpers/checkProps";
4
+ import { translate } from "../../translations/index";
5
+ const defaultProps = {
6
+ onChange: () => { },
7
+ className: "",
8
+ placeholder: "",
9
+ type: "text",
10
+ name: ""
11
+ };
12
+ const Input = (props) => {
13
+ const { onChange, className, placeholder, type, name, ...rest } = { ...defaultProps, ...props };
14
+ return _jsx("input", { className: className, placeholder: translate(placeholder), type: type, name: name, onChange: event => onChange(event.currentTarget.value, event), ...rest });
15
+ };
16
+ export default memo(Input, checkProps);
@@ -1 +1,21 @@
1
- import{jsx as _jsx}from"preact/jsx-runtime";import checkProps from"../../helpers/checkProps";import{translate}from"../../translations/index";import{forwardRef,memo,useMemo}from"preact/compat";const defaultProps={text:"",data:{},html:!1,className:"",tag:"span",onClick:()=>{}},Text=forwardRef((e,t)=>{const{text:r,data:a,html:s,className:o,tag:m,onClick:l,...n}={...defaultProps,...e},c=useMemo(()=>translate(r,a),[r,JSON.stringify(a)]);return _jsx(m,s?{...n,ref:t,dangerouslySetInnerHTML:{__html:c},className:o,onClick:e=>{e.preventDefault(),l(e)}}:{...n,ref:t,className:o,onClick:e=>{e.preventDefault(),l(e)},children:c})});export default memo(Text,checkProps);
1
+ import { jsx as _jsx } from "preact/jsx-runtime";
2
+ import checkProps from "../../helpers/checkProps";
3
+ import { translate } from "../../translations/index";
4
+ import { forwardRef, memo, useMemo } from "preact/compat";
5
+ const defaultProps = {
6
+ text: "",
7
+ data: {},
8
+ html: false,
9
+ className: "",
10
+ tag: "span",
11
+ onClick: () => { },
12
+ };
13
+ const Text = forwardRef((props, ref) => {
14
+ const { text, data, html, className, tag: Tag, onClick, ...rest } = { ...defaultProps, ...props };
15
+ const translated = useMemo(() => translate(text, data), [text, JSON.stringify(data)]);
16
+ if (html) {
17
+ return (_jsx(Tag, { ...rest, ref: ref, dangerouslySetInnerHTML: { __html: translated }, className: className, onClick: (event) => { event.preventDefault(); onClick(event); } }));
18
+ }
19
+ return (_jsx(Tag, { ...rest, ref: ref, className: className, onClick: (event) => { event.preventDefault(); onClick(event); }, children: translated }));
20
+ });
21
+ export default memo(Text, checkProps);
@@ -1 +1,53 @@
1
- import{jsx as _jsx}from"preact/jsx-runtime";import{useEffect,useRef}from"preact/hooks";import{memo}from"preact/compat";import checkProps from"../../helpers/checkProps";import toast from"../../helpers/toast";import{translate}from"../../translations/index";const isTouchDevice=()=>"undefined"!=typeof window&&"ontouchstart"in window,styles={width:"fit-content",height:"fit-content"},Tooltip=({message:e,children:t,className:o})=>{const r=useRef(null),s=useRef(null);useEffect(()=>()=>{s.current?.(),s.current=null},[]);const n=()=>{s.current?.(),s.current=null};return _jsx("section",{className:`${styles} ${o||""}`,ref:r,onMouseEnter:t=>{isTouchDevice()||(t.stopPropagation(),t.preventDefault(),r.current&&(s.current=toast(translate(e),r.current,0)))},onMouseLeave:e=>{isTouchDevice()||(e.stopPropagation(),e.preventDefault(),n())},onClick:t=>{t.stopPropagation(),t.preventDefault(),isTouchDevice()&&(s.current?n():s.current=toast(translate(e),r.current,2e3))},children:t})};export default memo(Tooltip,checkProps);
1
+ import { jsx as _jsx } from "preact/jsx-runtime";
2
+ import { useEffect, useRef } from "preact/hooks";
3
+ import { memo } from "preact/compat";
4
+ import checkProps from "../../helpers/checkProps";
5
+ import toast from "../../helpers/toast";
6
+ import { translate } from "../../translations/index";
7
+ const isTouchDevice = () => typeof window !== "undefined" && "ontouchstart" in window;
8
+ const styles = {
9
+ width: "fit-content",
10
+ height: "fit-content"
11
+ };
12
+ const Tooltip = ({ message, children, className }) => {
13
+ const ref = useRef(null);
14
+ const toastRef = useRef(null);
15
+ useEffect(() => {
16
+ return () => {
17
+ toastRef.current?.();
18
+ toastRef.current = null;
19
+ };
20
+ }, []);
21
+ const showToast = () => {
22
+ if (ref.current) {
23
+ toastRef.current = toast(translate(message), ref.current, 0);
24
+ }
25
+ };
26
+ const hideToast = () => {
27
+ toastRef.current?.();
28
+ toastRef.current = null;
29
+ };
30
+ return (_jsx("section", { className: `${styles} ${className || ""}`, ref: ref, onMouseEnter: (e) => {
31
+ if (isTouchDevice())
32
+ return;
33
+ e.stopPropagation();
34
+ e.preventDefault();
35
+ showToast();
36
+ }, onMouseLeave: (e) => {
37
+ if (isTouchDevice())
38
+ return;
39
+ e.stopPropagation();
40
+ e.preventDefault();
41
+ hideToast();
42
+ }, onClick: (e) => {
43
+ e.stopPropagation();
44
+ e.preventDefault();
45
+ if (!isTouchDevice())
46
+ return;
47
+ if (toastRef.current)
48
+ hideToast();
49
+ else
50
+ toastRef.current = toast(translate(message), ref.current, 2000);
51
+ }, children: children }));
52
+ };
53
+ export default memo(Tooltip, checkProps);
@@ -1 +1,5 @@
1
- const checkProps=(e,c)=>Array.from(new Set([...Object.keys(e),...Object.keys(c)])).every(r=>e[r]===c[r]);export default checkProps;
1
+ const checkProps = (prevProps, nextProps) => {
2
+ const allKeys = Array.from(new Set([...Object.keys(prevProps), ...Object.keys(nextProps)]));
3
+ return allKeys.every(key => prevProps[key] === nextProps[key]);
4
+ };
5
+ export default checkProps;
@@ -1 +1,21 @@
1
- const getPath=(t,e)=>{if(t)return e.split(".").reduce((t,e)=>{if(null!=t&&e in t)return t[e]},t)},hasPath=(t,e)=>void 0!==getPath(t,e),objectPath=t=>({get:e=>getPath(t,e),has:e=>hasPath(t,e),print:()=>t});export default objectPath;
1
+ const getPath = (object, path) => {
2
+ if (!object)
3
+ return undefined;
4
+ return path
5
+ .split('.')
6
+ .reduce((current, segment) => {
7
+ if (current == null || !(segment in current)) {
8
+ return undefined;
9
+ }
10
+ return current[segment];
11
+ }, object);
12
+ };
13
+ const hasPath = (obj, path) => {
14
+ return getPath(obj, path) !== undefined;
15
+ };
16
+ const objectPath = (root) => ({
17
+ get: (p) => getPath(root, p),
18
+ has: (p) => hasPath(root, p),
19
+ print: () => root,
20
+ });
21
+ export default objectPath;
@@ -1 +1,45 @@
1
- const toast=(t,e,n=1500)=>{if(!e)return;const s=e.getBoundingClientRect(),o=document.createElement("div");o.textContent=t,o.className="cursor-toast",o.style.opacity="0",o.style.position="fixed",o.style.top="0",o.style.left="0",o.style.transform="translateY(0)",o.style.transition="opacity 0.3s ease, transform 0.3s ease",document.body.appendChild(o),requestAnimationFrame(()=>{const t=o.getBoundingClientRect();let e=s.top-t.height-8,n=s.left+s.width/2-t.width/2;e=Math.max(8,Math.min(e,window.innerHeight-t.height-8)),n=Math.max(8,Math.min(n,window.innerWidth-t.width-8)),Object.assign(o.style,{top:`${e}px`,left:`${n}px`,opacity:"1",transform:"translateY(-4px)"})});let i=null;const a=()=>{o.isConnected&&(o.style.opacity="0",o.style.transform="translateY(0)",setTimeout(()=>o.remove(),300))};return n>0&&(i=setTimeout(a,n)),()=>{i&&clearTimeout(i),a()}};export default toast;
1
+ const toast = (message, target, duration = 1500) => {
2
+ if (!target)
3
+ return;
4
+ const rect = target.getBoundingClientRect();
5
+ const el = document.createElement("div");
6
+ el.textContent = message;
7
+ el.className = "cursor-toast";
8
+ el.style.opacity = "0";
9
+ el.style.position = "fixed";
10
+ el.style.top = "0";
11
+ el.style.left = "0";
12
+ el.style.transform = "translateY(0)";
13
+ el.style.transition = "opacity 0.3s ease, transform 0.3s ease";
14
+ document.body.appendChild(el);
15
+ requestAnimationFrame(() => {
16
+ const toastRect = el.getBoundingClientRect();
17
+ let top = rect.top - toastRect.height - 8;
18
+ let left = rect.left + rect.width / 2 - toastRect.width / 2;
19
+ top = Math.max(8, Math.min(top, window.innerHeight - toastRect.height - 8));
20
+ left = Math.max(8, Math.min(left, window.innerWidth - toastRect.width - 8));
21
+ Object.assign(el.style, {
22
+ top: `${top}px`,
23
+ left: `${left}px`,
24
+ opacity: "1",
25
+ transform: "translateY(-4px)",
26
+ });
27
+ });
28
+ let hideTimeout = null;
29
+ const hide = () => {
30
+ if (!el.isConnected)
31
+ return;
32
+ el.style.opacity = "0";
33
+ el.style.transform = "translateY(0)";
34
+ setTimeout(() => el.remove(), 300);
35
+ };
36
+ if (duration > 0) {
37
+ hideTimeout = setTimeout(hide, duration);
38
+ }
39
+ return () => {
40
+ if (hideTimeout)
41
+ clearTimeout(hideTimeout);
42
+ hide();
43
+ };
44
+ };
45
+ export default toast;
@@ -1 +1,17 @@
1
- import{useEffect}from"preact/compat";const useHandleClickOutside=(e,t)=>{useEffect(()=>{const n=n=>{e.current&&(e.current.contains(n.target)||t())};return document.addEventListener("pointerdown",n,{passive:!0}),()=>{document.removeEventListener("pointerdown",n)}},[e,t])};export default useHandleClickOutside;
1
+ import { useEffect } from "preact/compat";
2
+ const useHandleClickOutside = (ref, cb) => {
3
+ useEffect(() => {
4
+ const handlePointerDown = (event) => {
5
+ if (!ref.current)
6
+ return;
7
+ if (!ref.current.contains(event.target)) {
8
+ cb();
9
+ }
10
+ };
11
+ document.addEventListener("pointerdown", handlePointerDown, { passive: true });
12
+ return () => {
13
+ document.removeEventListener("pointerdown", handlePointerDown);
14
+ };
15
+ }, [ref, cb]);
16
+ };
17
+ export default useHandleClickOutside;
@@ -1 +1,31 @@
1
- import{signal}from"@preact/signals";const queryParamsSignal=signal({}),getParams=()=>{const a=window.location.search.slice(1),e=new URLSearchParams(a),r={};for(const[a,t]of e.entries())r[a]=t;return r};queryParamsSignal.value=getParams(),window.addEventListener("popstate",()=>{queryParamsSignal.value=getParams()});export const setQueryParams=(a,{replace:e=!1,pathname:r}={})=>{const t=new URLSearchParams;Object.entries(a).forEach(([a,e])=>{null!=e&&t.set(a,e)});const s=t.toString(),n=window.location.pathname,o=r??n,i=s?`${o}?${s}`:o;e?window.history.replaceState({},"",i):window.history.pushState({},"",i),queryParamsSignal.value=getParams()};export{queryParamsSignal as queryParams};
1
+ import { signal } from "@preact/signals";
2
+ const queryParamsSignal = signal({});
3
+ const getParams = () => {
4
+ const search = window.location.search.slice(1);
5
+ const params = new URLSearchParams(search);
6
+ const obj = {};
7
+ for (const [key, value] of params.entries())
8
+ obj[key] = value;
9
+ return obj;
10
+ };
11
+ queryParamsSignal.value = getParams();
12
+ window.addEventListener("popstate", () => {
13
+ queryParamsSignal.value = getParams();
14
+ });
15
+ export const setQueryParams = (updates, { replace = false, pathname } = {}) => {
16
+ const params = new URLSearchParams();
17
+ Object.entries(updates).forEach(([key, value]) => {
18
+ if (value !== null && value !== undefined)
19
+ params.set(key, value);
20
+ });
21
+ const queryString = params.toString();
22
+ const currentPath = window.location.pathname;
23
+ const newPath = pathname ?? currentPath;
24
+ const newUrl = queryString ? `${newPath}?${queryString}` : newPath;
25
+ if (replace)
26
+ window.history.replaceState({}, "", newUrl);
27
+ else
28
+ window.history.pushState({}, "", newUrl);
29
+ queryParamsSignal.value = getParams();
30
+ };
31
+ export { queryParamsSignal as queryParams };
@@ -1 +1,13 @@
1
- import{useLayoutEffect,useMemo,useState}from"preact/hooks";const useWindowSize=()=>{const[e,t]=useState({height:window.innerHeight,width:window.innerWidth});return useLayoutEffect(()=>{const e=()=>{t({height:window.innerHeight,width:window.innerWidth})};return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}},[]),useMemo(()=>({height:e.height,width:e.width}),[e.height,e.width])};export default useWindowSize;
1
+ import { useLayoutEffect, useMemo, useState } from "preact/hooks";
2
+ const useWindowSize = () => {
3
+ const [size, setSize] = useState({ height: window.innerHeight, width: window.innerWidth });
4
+ useLayoutEffect(() => {
5
+ const handleResize = () => {
6
+ setSize({ height: window.innerHeight, width: window.innerWidth });
7
+ };
8
+ window.addEventListener("resize", handleResize);
9
+ return () => { window.removeEventListener("resize", handleResize); };
10
+ }, []);
11
+ return useMemo(() => ({ height: size.height, width: size.width }), [size.height, size.width]);
12
+ };
13
+ export default useWindowSize;
@@ -1 +1,23 @@
1
- import toast from"../helpers/toast";const copyToClipboard=async(o="",t="Copied")=>{try{if(navigator.clipboard&&window.isSecureContext)return await navigator.clipboard.writeText(o),!0;const e=document.createElement("textarea");e.value=o,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.focus(),e.select(),document.execCommand("copy"),document.body.removeChild(e),toast(t,document.body,1e3)}catch{toast("Failed to copy",document.body,1e3)}};export default copyToClipboard;
1
+ import toast from "../helpers/toast";
2
+ const copyToClipboard = async (text = "", message = "Copied") => {
3
+ try {
4
+ if (navigator.clipboard && window.isSecureContext) {
5
+ await navigator.clipboard.writeText(text);
6
+ return true;
7
+ }
8
+ const textarea = document.createElement("textarea");
9
+ textarea.value = text;
10
+ textarea.style.position = "fixed";
11
+ textarea.style.opacity = "0";
12
+ document.body.appendChild(textarea);
13
+ textarea.focus();
14
+ textarea.select();
15
+ document.execCommand("copy");
16
+ document.body.removeChild(textarea);
17
+ toast(message, document.body, 1000);
18
+ }
19
+ catch {
20
+ toast("Failed to copy", document.body, 1000);
21
+ }
22
+ };
23
+ export default copyToClipboard;
@@ -1 +1,6 @@
1
- import copyToClipboard from"./copyToClipboard";import maskString from"./maskString";String.prototype.copy||(String.prototype.copy=copyToClipboard,String.prototype.mask=maskString);
1
+ import copyToClipboard from "./copyToClipboard";
2
+ import maskString from "./maskString";
3
+ if (!String.prototype.copy) {
4
+ String.prototype.copy = copyToClipboard;
5
+ String.prototype.mask = maskString;
6
+ }
@@ -1 +1,13 @@
1
- const maskString=function(t=6,n="..."){if(null==this)return"";const r=String(this);if(!r)return"";if(r.length<=2*t)return r;return`${r.slice(0,t)}${n}${r.slice(-t)}`};export default maskString;
1
+ const maskString = function (visibleCharacters = 6, maskWith = "...") {
2
+ if (this == null)
3
+ return "";
4
+ const str = String(this);
5
+ if (!str)
6
+ return "";
7
+ if (str.length <= visibleCharacters * 2)
8
+ return str;
9
+ const start = str.slice(0, visibleCharacters);
10
+ const end = str.slice(-visibleCharacters);
11
+ return `${start}${maskWith}${end}`;
12
+ };
13
+ export default maskString;
@@ -1 +1,51 @@
1
- import{signal}from"@preact/signals";const createStore=(e,t,a=[])=>{const r=signal({...t});try{const t=localStorage.getItem(e);t&&(r.value={...r.value,...JSON.parse(t)})}catch{}const l=t=>{if(r.value={...r.value,...t},a.length){const t=a.reduce((e,t)=>(e[t]=r.value[t],e),{});localStorage.setItem(e,JSON.stringify(t))}},s=()=>{r.value=t,localStorage.removeItem(e)};return Object.assign(new Proxy(t,{get(e,t){switch(t){case"setState":return l;case"resetState":return s;default:return r.value[t]}},set(t,l,s){if(r.value={...r.value,[l]:s},a.includes(l)){const t=a.reduce((e,t)=>(e[t]=r.value[t],e),{});localStorage.setItem(e,JSON.stringify(t))}return!0}}),{__signal:r})};export default createStore;
1
+ import { signal } from "@preact/signals";
2
+ const createStore = (name, initialState, persist = []) => {
3
+ const state = signal({ ...initialState });
4
+ try {
5
+ const stored = localStorage.getItem(name);
6
+ if (stored) {
7
+ state.value = { ...state.value, ...JSON.parse(stored) };
8
+ }
9
+ }
10
+ catch {
11
+ // Catch any Errors
12
+ }
13
+ const setState = (values) => {
14
+ state.value = { ...state.value, ...values };
15
+ if (persist.length) {
16
+ const toStore = persist.reduce((acc, key) => {
17
+ acc[key] = state.value[key];
18
+ return acc;
19
+ }, {});
20
+ localStorage.setItem(name, JSON.stringify(toStore));
21
+ }
22
+ };
23
+ const resetState = () => {
24
+ state.value = initialState;
25
+ localStorage.removeItem(name);
26
+ };
27
+ return Object.assign(new Proxy(initialState, {
28
+ get(_, prop) {
29
+ switch (prop) {
30
+ case "setState":
31
+ return setState;
32
+ case "resetState":
33
+ return resetState;
34
+ default:
35
+ return state.value[prop];
36
+ }
37
+ },
38
+ set(_, prop, value) {
39
+ state.value = { ...state.value, [prop]: value };
40
+ if (persist.includes(prop)) {
41
+ const toStore = persist.reduce((acc, key) => {
42
+ acc[key] = state.value[key];
43
+ return acc;
44
+ }, {});
45
+ localStorage.setItem(name, JSON.stringify(toStore));
46
+ }
47
+ return true;
48
+ },
49
+ }), { __signal: state });
50
+ };
51
+ export default createStore;
@@ -1 +1,34 @@
1
- import{signal,computed}from"@preact/signals";import objectPath from"../helpers/objectPath";export const languages=signal({});export const language=signal(window.localStorage.getItem("language")||"en");const translations=computed(()=>objectPath(languages.value[language.value])),interpolate=(t,e)=>"string"==typeof t?t.replace(/{{\s*(\w+)\s*}}/g,(t,a)=>a in e?String(e[a]):`{{${a}}}`):JSON.stringify(t);export const initTranslations=async t=>{try{return languages.value=t,!0}catch(t){return console.error(t),!1}};export const translate=(t,e={})=>{const a=translations.value;if(!a.has(t))return t;const n=a.get(t);return Object.keys(e).length?interpolate(n,e):n};export const changeLanguage=t=>(language.value=t,window.localStorage.setItem("language",t),!0);
1
+ import { signal, computed } from "@preact/signals";
2
+ import objectPath from "../helpers/objectPath";
3
+ export const languages = signal({});
4
+ export const language = signal(window.localStorage.getItem("language") || "en");
5
+ const translations = computed(() => objectPath(languages.value[language.value]));
6
+ const interpolate = (str, data) => {
7
+ if (typeof str === "string") {
8
+ return str.replace(/{{\s*(\w+)\s*}}/g, (_, key) => key in data ? String(data[key]) : `{{${key}}}`);
9
+ }
10
+ ;
11
+ return JSON.stringify(str);
12
+ };
13
+ export const initTranslations = async (langs) => {
14
+ try {
15
+ languages.value = langs;
16
+ return true;
17
+ }
18
+ catch (e) {
19
+ console.error(e);
20
+ return false;
21
+ }
22
+ };
23
+ export const translate = (key, data = {}) => {
24
+ const dictionary = translations.value;
25
+ if (!dictionary.has(key))
26
+ return key;
27
+ const value = dictionary.get(key);
28
+ return Object.keys(data).length ? interpolate(value, data) : value;
29
+ };
30
+ export const changeLanguage = (lang) => {
31
+ language.value = lang;
32
+ window.localStorage.setItem("language", lang);
33
+ return true;
34
+ };
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@gohanfromgoku/ui-kit",
3
- "version": "0.0.2",
4
- "description": "",
3
+ "version": "0.0.4",
4
+ "description": "ui-kit is a TypeScript based UI component library designed for building modern web applications with ease and efficiency.",
5
+ "sideEffects": false,
5
6
  "scripts": {
6
- "build": "tsc && tsc-alias && pnpm run minify",
7
- "minify": "find dist -name '*.js' -exec terser {} --compress --mangle --output {} \\;",
7
+ "build": "tsc && tsc-alias",
8
8
  "watch": "tsc --watch"
9
9
  },
10
10
  "keywords": [
@@ -21,7 +21,7 @@
21
21
  ],
22
22
  "repository": {
23
23
  "type": "git",
24
- "url": "https://github.com/iamgohanfromgoku/kit.git"
24
+ "url": "https://github.com/iamgohanfromgoku/ui-kit.git"
25
25
  },
26
26
  "author": "GohanfromGoku",
27
27
  "license": "MIT",
@@ -30,7 +30,6 @@
30
30
  "preact": "^10.28.0"
31
31
  },
32
32
  "devDependencies": {
33
- "terser": "^5.44.1",
34
33
  "tsc-alias": "^1.8.16",
35
34
  "typescript": "^5.9.3"
36
35
  },
@@ -13,7 +13,9 @@ export interface RequestOptions {
13
13
  }
14
14
  export declare class API {
15
15
  private baseURL;
16
- constructor(baseURL: string);
16
+ private defaultHeaders;
17
+ private timeout;
18
+ constructor(baseURL: string, headers?: Record<string, string>, timeout?: number);
17
19
  private createURL;
18
20
  private request;
19
21
  GET: <T = any>(endpoint: string, opts?: RequestOptions) => Promise<T>;