@bgord/ui 0.6.2 → 0.6.3
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/hooks/index.d.ts +1 -0
- package/dist/hooks/use-file.d.ts +65 -0
- package/dist/index.js +1 -1
- package/package.json +4 -4
- package/readme.md +2 -1
package/dist/hooks/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./use-click-outside";
|
|
|
2
2
|
export * from "./use-client-filter";
|
|
3
3
|
export * from "./use-exit-action";
|
|
4
4
|
export * from "./use-field";
|
|
5
|
+
export * from "./use-file";
|
|
5
6
|
export * from "./use-focus-shortcut";
|
|
6
7
|
export * from "./use-hover";
|
|
7
8
|
export * from "./use-meta-enter-submit";
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
type UseFileNameType = string;
|
|
2
|
+
export type UseFileConfigType = {
|
|
3
|
+
mimeTypes: string[];
|
|
4
|
+
maxSizeBytes?: number;
|
|
5
|
+
};
|
|
6
|
+
export declare enum UseFileState {
|
|
7
|
+
idle = "idle",
|
|
8
|
+
selected = "selected",
|
|
9
|
+
error = "error"
|
|
10
|
+
}
|
|
11
|
+
type UseFileLabelType = {
|
|
12
|
+
props: {
|
|
13
|
+
htmlFor: UseFileNameType;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
type UseFileInputType = {
|
|
17
|
+
props: {
|
|
18
|
+
id: UseFileNameType;
|
|
19
|
+
name: UseFileNameType;
|
|
20
|
+
multiple: false;
|
|
21
|
+
accept: React.JSX.IntrinsicElements["input"]["accept"];
|
|
22
|
+
};
|
|
23
|
+
key: React.Key;
|
|
24
|
+
};
|
|
25
|
+
type UseFileActionsType = {
|
|
26
|
+
selectFile(event: React.ChangeEvent<HTMLInputElement>): File | undefined;
|
|
27
|
+
clearFile: VoidFunction;
|
|
28
|
+
};
|
|
29
|
+
type UseFileIdle = {
|
|
30
|
+
actions: UseFileActionsType;
|
|
31
|
+
data: null;
|
|
32
|
+
input: UseFileInputType;
|
|
33
|
+
isError: false;
|
|
34
|
+
isIdle: true;
|
|
35
|
+
isSelected: false;
|
|
36
|
+
label: UseFileLabelType;
|
|
37
|
+
matches: (states: UseFileState[]) => boolean;
|
|
38
|
+
state: UseFileState.idle;
|
|
39
|
+
};
|
|
40
|
+
type UseFileSelected = {
|
|
41
|
+
actions: UseFileActionsType;
|
|
42
|
+
data: File;
|
|
43
|
+
input: UseFileInputType;
|
|
44
|
+
isError: false;
|
|
45
|
+
isIdle: false;
|
|
46
|
+
isSelected: true;
|
|
47
|
+
label: UseFileLabelType;
|
|
48
|
+
matches: (states: UseFileState[]) => boolean;
|
|
49
|
+
preview: ReturnType<typeof URL.createObjectURL> | undefined;
|
|
50
|
+
state: UseFileState.selected;
|
|
51
|
+
};
|
|
52
|
+
type UseFileError = {
|
|
53
|
+
actions: UseFileActionsType;
|
|
54
|
+
data: null;
|
|
55
|
+
input: UseFileInputType;
|
|
56
|
+
isError: true;
|
|
57
|
+
isIdle: false;
|
|
58
|
+
isSelected: false;
|
|
59
|
+
label: UseFileLabelType;
|
|
60
|
+
matches: (states: UseFileState[]) => boolean;
|
|
61
|
+
state: UseFileState.error;
|
|
62
|
+
};
|
|
63
|
+
export type UseFileReturnType = UseFileIdle | UseFileSelected | UseFileError;
|
|
64
|
+
export declare function useFile(name: UseFileNameType, config: UseFileConfigType): UseFileReturnType;
|
|
65
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useEffect as
|
|
1
|
+
import{useEffect as Z,useRef as V}from"react";import{useEffect as H}from"react";function R(e,t){H(()=>{if(typeof document>"u")return;function n(r){let i=e.current;if(!i)return;if(i.contains(r.target))if(r.target===i){let{left:o,right:s,top:l,bottom:u}=i.getBoundingClientRect(),m=r instanceof MouseEvent?r.clientX:r.touches[0].clientX,d=r instanceof MouseEvent?r.clientY:r.touches[0].clientY;if(m>=o&&m<=s&&d>=l&&d<=u)return}else return;t(r)}return document.addEventListener("mousedown",n),document.addEventListener("touchstart",n),()=>{document.removeEventListener("mousedown",n),document.removeEventListener("touchstart",n)}},[e,t])}import{useCallback as q,useMemo as b}from"react";class a{static emptyValue=void 0;static isEmpty(e){return e===void 0||e===""||e===null}static compare(e,t){if(a.isEmpty(e)&&a.isEmpty(t))return!0;return e===t}value=a.emptyValue;constructor(e){this.value=a.isEmpty(e)?a.emptyValue:e}get(){return this.value}isEmpty(){return a.isEmpty(this.value)}}import{useEffect as k,useState as M}from"react";import{useSearchParams as X}from"react-router";var S;((n)=>{n.params="params";n.local="local"})(S||={});function w(e){let t=e.strategy??"local",[n,r]=X(),i=new a(n.get(e.name)),o=new a(e.defaultValue),[s,l]=M(i.isEmpty()?o.get():i.get()),u=(c)=>{let g=new a(c);l(g.get())};k(()=>{let c=new a(s);if(t==="params")if(c.isEmpty())n.delete(e.name),r(n);else n.set(e.name,c.get()),r(n)},[s,n,r,e.name,t]);let m=a.isEmpty(s)?"":s,d=(c)=>u(c.currentTarget.value);return{strategy:t,defaultValue:o.get(),currentValue:s,value:m,set:u,handleChange:d,clear:()=>u(o.get()),label:{props:{htmlFor:e.name}},input:{props:{id:e.name,name:e.name,value:m,onChange:d}},changed:!a.compare(s,o.get()),unchanged:a.compare(s,o.get()),empty:a.isEmpty(s)}}class O{static clearAll(e){return()=>e.forEach((t)=>t.clear())}}function Ue(e){let t=w({...e,strategy:"local"}),n=q((o)=>{if(t.empty)return!0;return a.compare(o,t.currentValue)},[t.empty,t.currentValue]),r=b(()=>e.filterFn??n,[e.filterFn,n]),i=b(()=>Object.entries(e.enum).map(([o,s])=>({name:o,value:s})),[e.enum]);return b(()=>({...t,filterFn:r,options:i,strategy:"local"}),[t,r,i])}import W from"react";function Se(e){let[t,n]=W.useState("idle"),r=(s)=>{if(s.preventDefault(),t==="idle")n("exiting")},i=(s)=>{if(s.animationName!==e.animation)return;e.action(),n("gone")},o=t==="exiting"?{"data-animation":e.animation,onAnimationEnd:i}:void 0;return{visible:t!=="gone",attach:o,trigger:r}}import{useMemo as N,useState as E}from"react";var P;((r)=>{r.idle="idle";r.selected="selected";r.error="error"})(P||={});function Ae(e,t){let n=t?.maxSizeBytes??Number.POSITIVE_INFINITY,[r,i]=E(0),[o,s]=E("idle"),[l,u]=E(null);function m(y){let f=y.currentTarget.files;if(!f?.[0])return;let T=f[0];if(T.size>n){s("error");return}if(!t.mimeTypes.includes(T.type)){s("error");return}return u(T),s("selected"),T}function d(){i((y)=>y+1),u(null),s("idle")}let c=N(()=>l?URL.createObjectURL(l):void 0,[l]);function g(y){return y.some((f)=>f===o)}let h={actions:{selectFile:m,clearFile:d},input:{props:{id:e,name:e,multiple:!1,accept:t.mimeTypes.join(",")},key:r},label:{props:{htmlFor:e}},matches:g};if(o==="idle")return{data:null,isError:!1,isIdle:!0,isSelected:!1,state:o,...h};if(o==="selected")return{data:l,isError:!1,isIdle:!1,isSelected:!0,preview:c,state:o,...h};return{data:null,isError:!0,isIdle:!1,isSelected:!1,state:o,...h}}import{useCallback as B,useMemo as K,useRef as $}from"react";import{useEffect as D}from"react";import{tinykeys as J}from"tinykeys";function x(e,t){let n=t?.enabled??!0;D(()=>{if(!n)return;let r=J(window,e);return()=>r()},[e,n])}function Xe(e){let t=$(null),n=B(()=>{if(t.current)t.current.focus()},[]);return x({[e]:n}),K(()=>({ref:t}),[])}import{useCallback as j,useRef as Y}from"react";import{useState as _}from"react";function C({name:e,defaultValue:t=!1}){let[n,r]=_(t);return{on:n,off:!n,enable:()=>r(!0),disable:()=>r(!1),toggle:()=>r((m)=>!m),props:{controller:{"aria-expanded":n?"true":"false","aria-controls":e,role:"button",tabIndex:0},target:{id:e,role:"region","aria-hidden":n?"false":"true"}}}}function A(e){let{on:t,off:n,enable:r,disable:i,toggle:o,props:s,...l}=e;return{toggle:{on:t,off:n,enable:r,disable:i,toggle:o,props:s},rest:l}}function De(e){let t=e?.enabled??!0,n=C({name:"_internal"}),r=Y(null),i=typeof window<"u"&&"PointerEvent"in window?"pointerenter":"mouseenter",o=typeof window<"u"&&"PointerEvent"in window?"pointerleave":"mouseleave";return{attach:{ref:j((l)=>{let u=r.current;if(u)u.removeEventListener(i,n.enable),u.removeEventListener(o,n.disable);if(r.current=l,l&&t)l.addEventListener(i,n.enable),l.addEventListener(o,n.disable)},[i,o,t,n.enable,n.disable])},hovering:n.on&&t}}import{useCallback as Q}from"react";function Ke(){return{onKeyDown:Q((t)=>{if(!t.metaKey||t.key!=="Enter")return;t.preventDefault(),t.currentTarget.form?.requestSubmit()},[])}}import{useEffect as z}from"react";function I(e=!0){z(()=>{if(typeof document>"u")return;let t=document.body.style.overflow;if(e)document.body.style.overflow="hidden";return()=>{document.body.style.overflow=t}},[e])}import{jsx as ee}from"react/jsx-runtime";function st(e){let{toggle:t,rest:n}=A(e),r=V(null);return Z(()=>{if(e.on)r.current?.showModal();else r.current?.close()},[e.on]),x({Escape:t.disable}),I(e.on),R(r,t.disable),ee("dialog",{ref:r,tabIndex:0,"aria-modal":"true","data-disp":e.on?"flex":"none","data-dir":"column","data-mx":"auto","data-p":"5","data-position":"fixed","data-z":"2","data-bg":"neutral-900","data-br":"xs","data-backdrop":"stronger","data-animation":"grow-fade-in",...n})}var mt={email:{inputMode:"email",autoComplete:"email",autoCapitalize:"none",spellCheck:"false"},password:{new:{autoComplete:"new-password"},current:{autoComplete:"current-password"}},off:{autoComplete:"off",spellCheck:!1}};function L(){}class te{static async copy(e){let t=e.onSuccess??L;if(!navigator.clipboard)return;await navigator.clipboard.writeText(e.text),t()}}import ne from"js-cookie";class re{static extractFrom(e){return e.headers.get("cookie")??""}static set(e,t){ne.set(e,t)}}class oe{static fromRevision(e){return{"if-match":String(e)}}}function ht(e){return function(){for(let t of e)t()}}class ie{static allUnchanged(e){return e.every((t)=>t.unchanged)}static allEmpty(e){return e.every((t)=>t.empty)}static anyEmpty(e){return e.some((t)=>t.empty)}static anyUnchanged(e){return e.some((t)=>t.unchanged)}static anyChanged(e){return e.some((t)=>t.changed)}}class se{static input(e){let t=e.required??!0;if(e.min&&!e.max)return{pattern:`.{${e.min}}`,required:t};if(e.min&&e.max)return{pattern:`.{${e.min},${e.max}}`,required:t};if(!e.min&&e.max)return{pattern:`.{,${e.max}}`,required:t};return{pattern:void 0,required:t}}static textarea(e){let t=e.required??!0;if(e.min&&!e.max)return{minLength:e.min,required:t};if(e.min&&e.max)return{minLength:e.min,maxLength:e.max,required:t};if(!e.min&&e.max)return{maxLength:e.max,required:t};return{required:t}}static exact(e){let t=e.required??!0;return{pattern:e.text,required:t}}}function Ft(){if(typeof window>"u")return;return window}import{polishPlurals as le}from"polish-plurals";function v(e){if(e.language==="en"){let t=e.plural??`${e.singular}s`;if(e.value===1)return e.singular;return t}if(e.language==="pl"){let t=e.value??1;if(t===1)return e.singular;return le(e.singular,String(e.plural),String(e.genitive),t)}return console.warn(`[@bgord/frontend] missing pluralization function for language: ${e.language}.`),e.singular}function Ct(e=12){return{times(t){let n=e*t,r={height:{height:p(n)},minHeight:{minHeight:p(n)},maxHeight:{maxHeight:p(n)},width:{width:p(n)},minWidth:{minWidth:p(n)},maxWidth:{maxWidth:p(n)},square:{height:p(n),width:p(n)}},i={height:{style:{height:p(n)}},minHeight:{style:{minHeight:p(n)}},maxHeight:{style:{maxHeight:p(n)}},width:{style:{width:p(n)}},minWidth:{style:{minWidth:p(n)}},maxWidth:{style:{maxWidth:p(n)}},square:{style:{height:p(n),width:p(n)}}};return{px:p(n),raw:n,style:i,...r}}}}function p(e){return`${e}px`}import{createContext as ae,use as U,useCallback as pe}from"react";var F=ae({translations:{},language:"en",supportedLanguages:{en:"en"}});function vt(){let e=U(F);if(e===void 0)throw Error("useTranslations must be used within the TranslationsContext");return pe((n,r)=>{let i=e.translations[n];if(!i)return console.warn(`[@bgord/ui] missing translation for key: ${n}`),n;if(!r)return i;return Object.entries(r).reduce((o,[s,l])=>{let u=new RegExp(`{{${s}}}`,"g");return o.replace(u,String(l))},i)},[e.translations])}function ue(){let e=U(F);if(e===void 0)throw Error("useLanguage must be used within the TranslationsContext");return e.language}function Ht(){let e=U(F);if(e===void 0)throw Error("useSupportedLanguages must be used within the TranslationsContext");return e.supportedLanguages}function kt(){let e=ue();return(t)=>v({...t,language:e})}class me{static fromRevision(e){return{"if-match":`W/${e}`}}}export{vt as useTranslations,C as useToggle,Ht as useSupportedLanguages,x as useShortcuts,I as useScrollLock,kt as usePluralize,Ke as useMetaEnterSubmit,ue as useLanguage,De as useHover,Xe as useFocusKeyboardShortcut,Ae as useFile,S as useFieldStrategyEnum,w as useField,Se as useExitAction,Ue as useClientFilter,R as useClickOutside,v as pluralize,L as noop,Ft as getSafeWindow,A as extractUseToggle,ht as exec,me as WeakETag,P as UseFileState,F as TranslationsContext,Ct as Rhythm,O as LocalFields,se as Form,ie as Fields,a as Field,oe as ETag,st as Dialog,re as Cookies,te as Clipboard,mt as Autocomplete};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bgord/ui",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"@types/react": "19.2.2",
|
|
38
38
|
"@types/react-dom": "19.2.2",
|
|
39
39
|
"cspell": "9.2.2",
|
|
40
|
-
"knip": "5.66.
|
|
41
|
-
"lefthook": "2.0.
|
|
40
|
+
"knip": "5.66.3",
|
|
41
|
+
"lefthook": "2.0.1",
|
|
42
42
|
"only-allow": "1.2.1",
|
|
43
43
|
"shellcheck": "4.1.0"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"better-auth": "1.3.
|
|
46
|
+
"better-auth": "1.3.31",
|
|
47
47
|
"js-cookie": "3.0.5",
|
|
48
48
|
"polish-plurals": "1.1.0",
|
|
49
49
|
"tinykeys": "3.0.0"
|
package/readme.md
CHANGED
|
@@ -31,9 +31,10 @@ src/
|
|
|
31
31
|
│ ├── use-client-filter.ts
|
|
32
32
|
│ ├── use-exit-action.ts
|
|
33
33
|
│ ├── use-field.ts
|
|
34
|
+
│ ├── use-file.ts
|
|
34
35
|
│ ├── use-focus-shortcut.ts
|
|
35
36
|
│ ├── use-hover.ts
|
|
36
|
-
│ ├── use-meta-enter-submit.
|
|
37
|
+
│ ├── use-meta-enter-submit.ts
|
|
37
38
|
│ ├── use-scroll-lock.ts
|
|
38
39
|
│ ├── use-shortcuts.ts
|
|
39
40
|
│ └── use-toggle.ts
|