@cruxkit/button 0.0.3 → 0.0.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/README.md +42 -68
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
</div>
|
|
9
9
|
|
|
10
10
|
<div align="center">
|
|
11
|
-
<img src="https://img.shields.io/badge/v-0.0.
|
|
11
|
+
<img src="https://img.shields.io/badge/v-0.0.5-black"/>
|
|
12
12
|
<a href="https://github.com/cruxkit-org"><img src="https://img.shields.io/badge/🔥-@cruxkit-black"/></a>
|
|
13
13
|
<br>
|
|
14
|
-
<img src="https://img.shields.io/badge/coverage-
|
|
14
|
+
<img src="https://img.shields.io/badge/coverage-100%25-brightgreen" alt="Test Coverage" />
|
|
15
15
|
<img src="https://img.shields.io/github/issues/cruxkit-org/button?style=flat" alt="Github Repo Issues" />
|
|
16
16
|
<img src="https://img.shields.io/github/stars/cruxkit-org/button?style=social" alt="GitHub Repo stars" />
|
|
17
17
|
</div>
|
|
@@ -60,9 +60,7 @@
|
|
|
60
60
|
- ### Basic usage
|
|
61
61
|
|
|
62
62
|
```tsx
|
|
63
|
-
<Button
|
|
64
|
-
Click me
|
|
65
|
-
</Button>
|
|
63
|
+
<Button text="Click me" />
|
|
66
64
|
```
|
|
67
65
|
|
|
68
66
|
- ### With options
|
|
@@ -88,6 +86,9 @@
|
|
|
88
86
|
href="https://example.com"
|
|
89
87
|
variant="link"
|
|
90
88
|
color="brand"
|
|
89
|
+
onMount={(el) => {
|
|
90
|
+
console.log('Button mounted', el);
|
|
91
|
+
}}
|
|
91
92
|
>
|
|
92
93
|
Learn more
|
|
93
94
|
</Button>
|
|
@@ -104,76 +105,49 @@
|
|
|
104
105
|
- #### Functions
|
|
105
106
|
|
|
106
107
|
```tsx
|
|
107
|
-
|
|
108
|
-
* A polymorphic button component that supports multiple variants, colors, sizes, and states.
|
|
109
|
-
*
|
|
110
|
-
* @param props - The properties for the Button component.
|
|
111
|
-
* @param props.variant - Visual style variant: `'solid' | 'outline' | 'ghost' | 'link'`.
|
|
112
|
-
* @param props.color - Color theme: `'brand' | 'success' | 'warning' | 'error' | 'neutral'`.
|
|
113
|
-
* @param props.size - Size scale: `'sm' | 'md' | 'lg'`.
|
|
114
|
-
* @param props.fullWidth - Whether the button spans the full width of its container.
|
|
115
|
-
* @param props.disabled - Whether the button is disabled.
|
|
116
|
-
* @param props.loading - Whether the button is in a loading state (disables interaction).
|
|
117
|
-
* @param props.leftIcon - Optional icon placed to the left of the label (string name or IconProps).
|
|
118
|
-
* @param props.rightIcon - Optional icon placed to the right of the label (string name or IconProps).
|
|
119
|
-
* @param props.as - Element type to render: `'button' | 'a' | any polymorphic component`.
|
|
120
|
-
* @param props.children - Button label content.
|
|
121
|
-
* @param props.className - Additional CSS classes appended to the built-in styles.
|
|
122
|
-
* @param props.type - HTML button type attribute (only applied when `as="button"`).
|
|
123
|
-
* @param props.restProps - Any other props are forwarded to the underlying element.
|
|
124
|
-
*
|
|
125
|
-
* @returns A JSX element representing the styled button.
|
|
126
|
-
*/
|
|
108
|
+
// A polymorphic button component that supports multiple variants, colors, sizes, and states.
|
|
127
109
|
export function Button(props: ButtonProps): JSXElement
|
|
128
110
|
```
|
|
129
111
|
|
|
130
112
|
- #### Types
|
|
131
113
|
|
|
132
114
|
```tsx
|
|
133
|
-
export type
|
|
134
|
-
|
|
135
|
-
export type
|
|
136
|
-
|
|
137
|
-
export
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
size? :
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
115
|
+
export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'link';
|
|
116
|
+
export type ButtonColor = 'brand' | 'success' | 'warning' | 'error' | 'neutral';
|
|
117
|
+
export type ButtonSize = 'sm' | 'md' | 'lg';
|
|
118
|
+
|
|
119
|
+
export interface ButtonProps {
|
|
120
|
+
variant? : ButtonVariant;
|
|
121
|
+
color? : ButtonColor;
|
|
122
|
+
size? : ButtonSize;
|
|
123
|
+
fullWidth? : boolean;
|
|
124
|
+
disabled? : boolean;
|
|
125
|
+
loading? : boolean;
|
|
126
|
+
|
|
127
|
+
leftIcon? : IconProps | IconName;
|
|
128
|
+
rightIcon? : IconProps | IconName;
|
|
129
|
+
|
|
130
|
+
as? : ContainerAs;
|
|
131
|
+
|
|
132
|
+
text? : string | number;
|
|
133
|
+
children? : JSXElement | string | number;
|
|
134
|
+
|
|
135
|
+
className? : string;
|
|
136
|
+
id? : string;
|
|
137
|
+
type? : 'button' | 'submit' | 'reset';
|
|
138
|
+
href? : string;
|
|
139
|
+
target? : string;
|
|
140
|
+
rel? : string;
|
|
141
|
+
|
|
142
|
+
'aria-label'? : string;
|
|
143
|
+
role? : string;
|
|
144
|
+
|
|
145
|
+
onMount? : (e: HTMLElement) => void;
|
|
146
|
+
onLoad? : (e: HTMLElement) => void;
|
|
147
|
+
onClick? : (e: MouseEvent) => void;
|
|
148
|
+
onMouseEnter? : (e: MouseEvent) => void;
|
|
149
|
+
onMouseLeave? : (e: MouseEvent) => void;
|
|
153
150
|
}
|
|
154
|
-
|
|
155
|
-
export interface CustomIconConfig extends IconConfigBase {
|
|
156
|
-
name? : string
|
|
157
|
-
svg : string
|
|
158
|
-
viewBox? : string
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export type IconConfig = NamedIconConfig | CustomIconConfig;
|
|
162
|
-
|
|
163
|
-
export type IconProps = IconConfig | IconName;
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
- #### Constants
|
|
167
|
-
|
|
168
|
-
```tsx
|
|
169
|
-
export const sizeMap: Record<string, string> = {
|
|
170
|
-
xs : '0.75rem',
|
|
171
|
-
sm : '1rem',
|
|
172
|
-
md : '1.25rem',
|
|
173
|
-
lg : '1.5rem',
|
|
174
|
-
xl : '2rem',
|
|
175
|
-
xxl : '2.5rem'
|
|
176
|
-
};
|
|
177
151
|
```
|
|
178
152
|
|
|
179
153
|
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var container=require('@cruxkit/container'),text=require('@cruxkit/text'),icon=require('@cruxkit/icon'),jsxRuntime=require('@minejs/jsx/jsx-runtime');var
|
|
1
|
+
'use strict';var container=require('@cruxkit/container'),text=require('@cruxkit/text'),icon=require('@cruxkit/icon'),client=require('@cruxjs/client'),jsxRuntime=require('@minejs/jsx/jsx-runtime');var G={sm:{px:3,py:1},md:{px:4,py:2},lg:{px:6,py:3}},K={sm:1,md:2,lg:2},Q={sm:"sm",md:"md",lg:"lg"},U={sm:"sm",md:"md",lg:"lg"},Z={solid:{brand:["bg-brand","text-inverse","border","border-transparent","hover:bg-brand-hover","active:bg-brand-active","active:scale-95","shadow-sm","hover:shadow-md"],success:["bg-success","text-inverse","border","border-transparent","hover:bg-success-hover","active:bg-success-active","active:scale-95","shadow-sm","hover:shadow-md"],warning:["bg-warning","text-inverse","border","border-transparent","hover:bg-warning-hover","active:bg-warning-active","active:scale-95","shadow-sm","hover:shadow-md"],error:["bg-error","text-inverse","border","border-transparent","hover:bg-error-hover","active:bg-error-active","active:scale-95","shadow-sm","hover:shadow-md"],neutral:["bg-surface","text-1","border","border-1","hover:bg-raised","active:bg-tertiary","active:scale-95","shadow-sm","hover:shadow-md"]},outline:{brand:["bg-transparent","text-brand","border","border-brand","hover:bg-brand-subtle","active:bg-brand-subtle","active:scale-95"],success:["bg-transparent","text-success","border","border-success","hover:bg-success-subtle","active:bg-success-subtle","active:scale-95"],warning:["bg-transparent","text-warning","border","border-warning","hover:bg-warning-subtle","active:bg-warning-subtle","active:scale-95"],error:["bg-transparent","text-error","border","border-error","hover:bg-error-subtle","active:bg-error-subtle","active:scale-95"],neutral:["bg-transparent","text-1","border","border-1","hover:bg-raised","active:bg-tertiary","active:scale-95"]},ghost:{brand:["bg-transparent","text-brand","border","border-transparent","hover:bg-brand-subtle","active:bg-brand-subtle","active:scale-95"],success:["bg-transparent","text-success","border","border-transparent","hover:bg-success-subtle","active:bg-success-subtle","active:scale-95"],warning:["bg-transparent","text-warning","border","border-transparent","hover:bg-warning-subtle","active:bg-warning-subtle","active:scale-95"],error:["bg-transparent","text-error","border","border-transparent","hover:bg-error-subtle","active:bg-error-subtle","active:scale-95"],neutral:["bg-transparent","text-1","border","border-transparent","hover:bg-raised","active:bg-tertiary","active:scale-95"]},link:{brand:["bg-transparent","text-brand","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],success:["bg-transparent","text-success","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],warning:["bg-transparent","text-warning","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],error:["bg-transparent","text-error","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],neutral:["bg-transparent","text-1","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"]}},E=new WeakSet,M=new WeakSet,I=new WeakSet,$=5,ee=100;function N(r,l){if(!r)return null;let o=U[l];if(typeof r=="string")return jsxRuntime.jsx("span",{className:"inline-flex shrink-0",children:jsxRuntime.jsx(icon.Icon,{name:r,size:o})});let t=r.size??o;return jsxRuntime.jsx("span",{className:"inline-flex shrink-0",children:jsxRuntime.jsx(icon.Icon,{...r,size:t})})}function oe(r){let{variant:l="solid",color:o="brand",size:t="md",fullWidth:C=false,disabled:R=false,loading:k=false,leftIcon:L,rightIcon:P,as:m="button",text:n,children:A,className:q,type:H="button",onMount:b,onLoad:u,...X}=r,_=["inline-flex","items-center","justify-center","font-medium","transition-all","duration-150","select-none","focus:outline-none","focus-visible:ring","focus-visible:ring-offset-2"],p=[];(k||R)&&p.push("opacity-50","cursor-not-allowed","pointer-events-none"),C&&p.push("w-full");let J=Z[l][o],W=[..._,...p,...J,q].filter(Boolean).join(" "),v=G[t],j=K[t],F=Q[t],i=[],f=N(L,t),h=N(P,t);f&&i.push(f);let x=typeof n=="string"&&n.includes("."),c=A??(x?"--":n);c!=null&&c!==""&&i.push(jsxRuntime.jsx(text.Text,{as:"span",size:F,"data-role":"btn-label",className:"flex items-center",children:c})),h&&i.push(h);let O=m==="button"?{type:H}:{},y=x,w=b||u||y?e=>{if(e){if(b&&!E.has(e)&&(E.add(e),b(e)),u&&!M.has(e)){M.add(e);let d=()=>{u(e);};typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>{requestAnimationFrame(d);}):setTimeout(d,0);}if(y&&!I.has(e)){let d=a=>{typeof queueMicrotask=="function"?queueMicrotask(a):setTimeout(a,0);},S=a=>{let z=e.querySelector('[data-role="btn-label"]');if(!z||typeof n!="string")return;let g=client.t(n,void 0,"--");if(g!==n&&g!=="--"||a>=$){z.textContent=String(g),I.add(e);return}setTimeout(()=>{S(a+1);},ee);};d(()=>{S(0);});}}}:void 0,T={as:m,display:"inline-flex",align:"center",justify:"center",gap:j,px:v.px,py:v.py,radius:"md",className:W,...O,...X};return w&&(T.ref=w),jsxRuntime.jsx(container.Container,{...T,children:i})}exports.Button=oe;//# sourceMappingURL=index.cjs.map
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/kit/button.tsx"],"names":["sizePaddingMap","sizeGapMap","labelSizeMap","iconSizeMap","variantClasses","renderIcon","icon","size","iconSize","jsx","Icon","resolvedSize","Button","props","variant","color","fullWidth","disabled","loading","leftIcon","rightIcon","as","children","className","type","restProps","baseClasses","stateClasses","paletteClasses","classes","padding","gap","labelSize","content","left","right","Text","elementTypeProps","Container"],"mappings":"mKAoBI,IAAMA,CAAAA,CAAuE,CACzE,EAAA,CAAI,CAAE,EAAA,CAAI,CAAA,CAAG,EAAA,CAAI,CAAE,CAAA,CACnB,EAAA,CAAI,CAAE,EAAA,CAAI,CAAA,CAAG,GAAI,CAAE,CAAA,CACnB,EAAA,CAAI,CAAE,EAAA,CAAI,CAAA,CAAG,EAAA,CAAI,CAAE,CACvB,CAAA,CAEMC,CAAAA,CAAwC,CAC1C,EAAA,CAAI,CAAA,CACJ,EAAA,CAAI,CAAA,CACJ,GAAI,CACR,CAAA,CAEMC,CAAAA,CAAuD,CACzD,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,IACR,CAAA,CAEMC,CAAAA,CAAsD,CACxD,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,KACJ,EAAA,CAAI,IACR,CAAA,CAEMC,CAAAA,CAAuE,CACzE,KAAA,CAAO,CACH,KAAA,CAAO,CACH,UAAA,CACA,cAAA,CACA,QAAA,CACA,oBAAA,CACA,sBAAA,CACA,wBAAA,CACA,iBAAA,CACA,YACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,YAAA,CACA,cAAA,CACA,QAAA,CACA,oBAAA,CACA,wBAAA,CACA,0BAAA,CACA,iBAAA,CACA,WAAA,CACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,aACA,cAAA,CACA,QAAA,CACA,oBAAA,CACA,wBAAA,CACA,0BAAA,CACA,iBAAA,CACA,WAAA,CACA,iBACJ,CAAA,CACA,KAAA,CAAO,CACH,UAAA,CACA,cAAA,CACA,QAAA,CACA,oBAAA,CACA,sBAAA,CACA,yBACA,iBAAA,CACA,WAAA,CACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,YAAA,CACA,QAAA,CACA,QAAA,CACA,UAAA,CACA,iBAAA,CACA,oBAAA,CACA,iBAAA,CACA,WAAA,CACA,iBACJ,CACJ,EACA,OAAA,CAAS,CACL,KAAA,CAAO,CACH,gBAAA,CACA,YAAA,CACA,QAAA,CACA,cAAA,CACA,uBAAA,CACA,wBAAA,CACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,gBAAA,CACA,cAAA,CACA,QAAA,CACA,gBAAA,CACA,yBAAA,CACA,0BAAA,CACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,gBAAA,CACA,cAAA,CACA,QAAA,CACA,gBAAA,CACA,yBAAA,CACA,0BAAA,CACA,iBACJ,CAAA,CACA,MAAO,CACH,gBAAA,CACA,YAAA,CACA,QAAA,CACA,cAAA,CACA,uBAAA,CACA,wBAAA,CACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,gBAAA,CACA,QAAA,CACA,QAAA,CACA,UAAA,CACA,iBAAA,CACA,qBACA,iBACJ,CACJ,CAAA,CACA,KAAA,CAAO,CACH,KAAA,CAAO,CACH,gBAAA,CACA,YAAA,CACA,QAAA,CACA,oBAAA,CACA,uBAAA,CACA,wBAAA,CACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,gBAAA,CACA,cAAA,CACA,QAAA,CACA,oBAAA,CACA,yBAAA,CACA,0BAAA,CACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,gBAAA,CACA,cAAA,CACA,QAAA,CACA,oBAAA,CACA,yBAAA,CACA,0BAAA,CACA,iBACJ,CAAA,CACA,KAAA,CAAO,CACH,gBAAA,CACA,YAAA,CACA,QAAA,CACA,oBAAA,CACA,uBAAA,CACA,wBAAA,CACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,gBAAA,CACA,QAAA,CACA,QAAA,CACA,qBACA,iBAAA,CACA,oBAAA,CACA,iBACJ,CACJ,CAAA,CACA,IAAA,CAAM,CACF,KAAA,CAAO,CACH,gBAAA,CACA,YAAA,CACA,QAAA,CACA,oBAAA,CACA,iBAAA,CACA,oBAAA,CACA,cAAA,CACA,MACJ,CAAA,CACA,OAAA,CAAS,CACL,gBAAA,CACA,cAAA,CACA,QAAA,CACA,oBAAA,CACA,iBAAA,CACA,oBAAA,CACA,cAAA,CACA,MACJ,CAAA,CACA,OAAA,CAAS,CACL,gBAAA,CACA,cAAA,CACA,SACA,oBAAA,CACA,iBAAA,CACA,oBAAA,CACA,cAAA,CACA,MACJ,CAAA,CACA,KAAA,CAAO,CACH,gBAAA,CACA,YAAA,CACA,QAAA,CACA,oBAAA,CACA,iBAAA,CACA,oBAAA,CACA,cAAA,CACA,MACJ,CAAA,CACA,OAAA,CAAS,CACL,gBAAA,CACA,QAAA,CACA,QAAA,CACA,oBAAA,CACA,iBAAA,CACA,oBAAA,CACA,cAAA,CACA,MACJ,CACJ,CACJ,CAAA,CAQA,SAASC,CAAAA,CAAWC,EAAwCC,CAAAA,CAAqC,CAC7F,GAAI,CAACD,CAAAA,CAAM,OAAO,IAAA,CAElB,IAAME,CAAAA,CAAWL,CAAAA,CAAYI,CAAI,CAAA,CAEjC,GAAI,OAAOD,CAAAA,EAAS,QAAA,CAChB,OACIG,cAAAA,CAAC,MAAA,CAAA,CAAK,SAAA,CAAU,sBAAA,CACZ,QAAA,CAAAA,cAAAA,CAACC,SAAAA,CAAA,CAAK,IAAA,CAAMJ,CAAAA,CAAkB,IAAA,CAAME,CAAAA,CAAU,CAAA,CAClD,CAAA,CAIR,IAAMG,CAAAA,CAAiBL,EAAkC,IAAA,EAAQE,CAAAA,CAEjE,OACIC,cAAAA,CAAC,MAAA,CAAA,CAAK,SAAA,CAAU,sBAAA,CACZ,QAAA,CAAAA,cAAAA,CAACC,SAAAA,CAAA,CAAM,GAAGJ,CAAAA,CAAM,IAAA,CAAMK,CAAAA,CAAc,CAAA,CACxC,CAER,CA6BO,SAASC,CAAAA,CAAOC,CAAAA,CAAgC,CACnD,GAAM,CACF,OAAA,CAAAC,CAAAA,CAAc,OAAA,CACd,KAAA,CAAAC,CAAAA,CAAc,OAAA,CACd,IAAA,CAAAR,CAAAA,CAAc,IAAA,CACd,UAAAS,CAAAA,CAAc,KAAA,CACd,QAAA,CAAAC,CAAAA,CAAc,KAAA,CACd,OAAA,CAAAC,CAAAA,CAAc,KAAA,CACd,QAAA,CAAAC,CAAAA,CACA,SAAA,CAAAC,CAAAA,CACA,EAAA,CAAAC,CAAAA,CAAc,QAAA,CACd,QAAA,CAAAC,EACA,SAAA,CAAAC,CAAAA,CACA,IAAA,CAAAC,CAAAA,CAAc,QAAA,CACd,GAAGC,CACP,CAAA,CAAIZ,CAAAA,CAEEa,CAAAA,CAAc,CAChB,aAAA,CACA,cAAA,CACA,gBAAA,CACA,aAAA,CACA,gBAAA,CACA,eACA,aAAA,CACA,oBAAA,CACA,oBAAA,CACA,6BACJ,CAAA,CAEMC,CAAAA,CAAe,EAAC,CAAA,CAElBT,CAAAA,EAAWD,CAAAA,GACXU,CAAAA,CAAa,IAAA,CAAK,YAAA,CAAc,oBAAA,CAAsB,qBAAqB,CAAA,CAG3EX,GACAW,CAAAA,CAAa,IAAA,CAAK,QAAQ,CAAA,CAG9B,IAAMC,CAAAA,CAAiBxB,CAAAA,CAAeU,CAAO,CAAA,CAAEC,CAAK,CAAA,CAE9Cc,CAAAA,CAAU,CACZ,GAAGH,CAAAA,CACH,GAAGC,EACH,GAAGC,CAAAA,CACHL,CACJ,CAAA,CACK,MAAA,CAAO,OAAO,CAAA,CACd,IAAA,CAAK,GAAG,CAAA,CAEPO,CAAAA,CAAY9B,CAAAA,CAAeO,CAAI,CAAA,CAC/BwB,CAAAA,CAAY9B,CAAAA,CAAWM,CAAI,CAAA,CAC3ByB,CAAAA,CAAY9B,CAAAA,CAAaK,CAAI,CAAA,CAE7B0B,CAAAA,CAAwB,EAAC,CAEzBC,CAAAA,CAAQ7B,CAAAA,CAAWc,CAAAA,CAAUZ,CAAI,CAAA,CACjC4B,CAAAA,CAAQ9B,CAAAA,CAAWe,CAAAA,CAAWb,CAAI,CAAA,CAEpC2B,CAAAA,EACAD,CAAAA,CAAQ,IAAA,CAAKC,CAAI,CAAA,CAGSZ,CAAAA,EAAa,IAAA,EAAQA,CAAAA,GAAa,EAAA,EAC5DW,CAAAA,CAAQ,IAAA,CACJxB,cAAAA,CAAC2B,SAAAA,CAAA,CAAK,EAAA,CAAG,OAAO,IAAA,CAAMJ,CAAAA,CACjB,QAAA,CAAAV,CAAAA,CACL,CACJ,CAAA,CAGAa,CAAAA,EACAF,CAAAA,CAAQ,IAAA,CAAKE,CAAK,CAAA,CAKtB,IAAME,CAAAA,CAFchB,CAAAA,GAGA,QAAA,CACV,CAAE,KAAAG,CAAK,CAAA,CACP,EAAC,CAEX,OACIf,cAAAA,CAAC6B,mBAAAA,CAAA,CACG,EAAA,CAAIjB,CAAAA,CACJ,OAAA,CAAkB,aAAA,CAClB,KAAA,CAAkB,QAAA,CAClB,OAAA,CAAkB,QAAA,CAClB,IAAmBU,CAAAA,CACnB,EAAA,CAAmBD,CAAAA,CAAQ,EAAA,CAC3B,EAAA,CAAmBA,CAAAA,CAAQ,EAAA,CAC3B,MAAA,CAAkB,IAAA,CAClB,SAAA,CAAmBD,CAAAA,CAClB,GAAGQ,CAAAA,CACH,GAAGZ,CAAAA,CAEH,QAAA,CAAAQ,EACL,CAER","file":"index.cjs","sourcesContent":["// src/kit/button.tsx\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import type { JSXElement } from '@minejs/jsx';\r\n import { Container } from '@cruxkit/container';\r\n import { Text } from '@cruxkit/text';\r\n import { Icon, type IconProps, type IconName, type IconConfig } from '@cruxkit/icon';\r\n import type { ButtonProps, ButtonSize, ButtonColor, ButtonVariant } from '../types';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ INIT ════════════════════════════════════════╗\r\n\r\n const sizePaddingMap: Record<ButtonSize, { px: 3 | 4 | 6; py: 1 | 2 | 3 }> = {\r\n sm: { px: 3, py: 1 },\r\n md: { px: 4, py: 2 },\r\n lg: { px: 6, py: 3 }\r\n };\r\n\r\n const sizeGapMap: Record<ButtonSize, 1 | 2> = {\r\n sm: 1,\r\n md: 2,\r\n lg: 2\r\n };\r\n\r\n const labelSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const iconSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const variantClasses: Record<ButtonVariant, Record<ButtonColor, string[]>> = {\r\n solid: {\r\n brand: [\r\n 'bg-brand',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-hover',\r\n 'active:bg-brand-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n success: [\r\n 'bg-success',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-hover',\r\n 'active:bg-success-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n warning: [\r\n 'bg-warning',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-hover',\r\n 'active:bg-warning-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n error: [\r\n 'bg-error',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-hover',\r\n 'active:bg-error-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n neutral: [\r\n 'bg-surface',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ]\r\n },\r\n outline: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-brand',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-success',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-warning',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-error',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n ghost: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n link: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ]\r\n }\r\n };\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n function renderIcon(icon: IconProps | IconName | undefined, size: ButtonSize): JSXElement | null {\r\n if (!icon) return null;\r\n\r\n const iconSize = iconSizeMap[size];\r\n\r\n if (typeof icon === 'string') {\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n <Icon name={icon as IconName} size={iconSize} />\r\n </span>\r\n );\r\n }\r\n\r\n const resolvedSize = ((icon as IconProps) as IconConfig).size ?? iconSize;\r\n\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n <Icon {...icon} size={resolvedSize} />\r\n </span>\r\n );\r\n }\r\n\r\n /**\r\n * A polymorphic button component that supports multiple variants, colors, sizes, and states.\r\n *\r\n * @param props - The properties for the Button component.\r\n * @param props.variant - Visual style variant: `'solid' | 'outline' | 'ghost' | 'link'`.\r\n * @param props.color - Color theme: `'brand' | 'success' | 'warning' | 'error' | 'neutral'`.\r\n * @param props.size - Size scale: `'sm' | 'md' | 'lg'`.\r\n * @param props.fullWidth - Whether the button spans the full width of its container.\r\n * @param props.disabled - Whether the button is disabled.\r\n * @param props.loading - Whether the button is in a loading state (disables interaction).\r\n * @param props.leftIcon - Optional icon placed to the left of the label (string name or IconProps).\r\n * @param props.rightIcon - Optional icon placed to the right of the label (string name or IconProps).\r\n * @param props.as - Element type to render: `'button' | 'a' | any polymorphic component`.\r\n * @param props.children - Button label content.\r\n * @param props.className - Additional CSS classes appended to the built-in styles.\r\n * @param props.type - HTML button type attribute (only applied when `as=\"button\"`).\r\n * @param props.restProps - Any other props are forwarded to the underlying element.\r\n *\r\n * @returns A JSX element representing the styled button.\r\n *\r\n * @example\r\n * ```tsx\r\n * <Button variant=\"solid\" color=\"brand\" size=\"md\" onClick={handleClick}>\r\n * Save\r\n * </Button>\r\n * ```\r\n */\r\n export function Button(props: ButtonProps): JSXElement {\r\n const {\r\n variant = 'solid',\r\n color = 'brand',\r\n size = 'md',\r\n fullWidth = false,\r\n disabled = false,\r\n loading = false,\r\n leftIcon,\r\n rightIcon,\r\n as = 'button',\r\n children,\r\n className,\r\n type = 'button',\r\n ...restProps\r\n } = props;\r\n\r\n const baseClasses = [\r\n 'inline-flex',\r\n 'items-center',\r\n 'justify-center',\r\n 'font-medium',\r\n 'transition-all',\r\n 'duration-150',\r\n 'select-none',\r\n 'focus:outline-none',\r\n 'focus-visible:ring',\r\n 'focus-visible:ring-offset-2'\r\n ];\r\n\r\n const stateClasses = [];\r\n\r\n if (loading || disabled) {\r\n stateClasses.push('opacity-50', 'cursor-not-allowed', 'pointer-events-none');\r\n }\r\n\r\n if (fullWidth) {\r\n stateClasses.push('w-full');\r\n }\r\n\r\n const paletteClasses = variantClasses[variant][color];\r\n\r\n const classes = [\r\n ...baseClasses,\r\n ...stateClasses,\r\n ...paletteClasses,\r\n className\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n const padding = sizePaddingMap[size];\r\n const gap = sizeGapMap[size];\r\n const labelSize = labelSizeMap[size];\r\n\r\n const content: JSXElement[] = [];\r\n\r\n const left = renderIcon(leftIcon, size);\r\n const right = renderIcon(rightIcon, size);\r\n\r\n if (left) {\r\n content.push(left);\r\n }\r\n\r\n if (children !== undefined && children !== null && children !== '') {\r\n content.push(\r\n <Text as=\"span\" size={labelSize}>\r\n {children}\r\n </Text>\r\n );\r\n }\r\n\r\n if (right) {\r\n content.push(right);\r\n }\r\n\r\n const elementType = as;\r\n\r\n const elementTypeProps =\r\n elementType === 'button'\r\n ? { type }\r\n : {};\r\n\r\n return (\r\n <Container\r\n as={as}\r\n display = \"inline-flex\"\r\n align = \"center\"\r\n justify = \"center\"\r\n gap = {gap}\r\n px = {padding.px}\r\n py = {padding.py}\r\n radius = \"md\"\r\n className = {classes}\r\n {...elementTypeProps}\r\n {...restProps}\r\n >\r\n {content}\r\n </Container>\r\n );\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/kit/button.tsx"],"names":["sizePaddingMap","sizeGapMap","labelSizeMap","iconSizeMap","variantClasses","mountedElements","loadedElements","translatedElements","MAX_TRANSLATION_ATTEMPTS","TRANSLATION_RETRY_DELAY_MS","renderIcon","icon","size","iconSize","jsx","Icon","resolvedSize","Button","props","variant","color","fullWidth","disabled","loading","leftIcon","rightIcon","as","text","children","className","type","onMount","onLoad","restProps","baseClasses","stateClasses","paletteClasses","classes","padding","gap","labelSize","content","left","right","isKeyLikeText","label","Text","elementTypeProps","shouldTranslate","handleRef","element","runLoad","schedule","fn","attemptTranslate","attempt","labelNode","translated","t","containerProps","Container"],"mappings":"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","file":"index.cjs","sourcesContent":["// src/kit/button.tsx\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import type { JSXElement } from '@minejs/jsx';\r\n import { Container } from '@cruxkit/container';\r\n import { Text } from '@cruxkit/text';\r\n import { Icon, type IconProps, type IconName, type IconConfig } from '@cruxkit/icon';\r\n import type { ButtonProps, ButtonSize, ButtonColor, ButtonVariant } from '../types';\r\n import { t } from '@cruxjs/client';\r\n \r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ INIT ════════════════════════════════════════╗\r\n\r\n const sizePaddingMap: Record<ButtonSize, { px: 3 | 4 | 6; py: 1 | 2 | 3 }> = {\r\n sm: { px: 3, py: 1 },\r\n md: { px: 4, py: 2 },\r\n lg: { px: 6, py: 3 }\r\n };\r\n\r\n const sizeGapMap: Record<ButtonSize, 1 | 2> = {\r\n sm: 1,\r\n md: 2,\r\n lg: 2\r\n };\r\n\r\n const labelSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const iconSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const variantClasses: Record<ButtonVariant, Record<ButtonColor, string[]>> = {\r\n solid: {\r\n brand: [\r\n 'bg-brand',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-hover',\r\n 'active:bg-brand-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n success: [\r\n 'bg-success',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-hover',\r\n 'active:bg-success-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n warning: [\r\n 'bg-warning',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-hover',\r\n 'active:bg-warning-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n error: [\r\n 'bg-error',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-hover',\r\n 'active:bg-error-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n neutral: [\r\n 'bg-surface',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ]\r\n },\r\n outline: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-brand',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-success',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-warning',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-error',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n ghost: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n link: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ]\r\n }\r\n };\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n const mountedElements = new WeakSet<HTMLElement>();\r\n const loadedElements = new WeakSet<HTMLElement>();\r\n const translatedElements = new WeakSet<HTMLElement>();\r\n const MAX_TRANSLATION_ATTEMPTS = 5;\r\n const TRANSLATION_RETRY_DELAY_MS = 100;\r\n\r\n type ButtonContainerProps = {\r\n as?: unknown;\r\n display?: string;\r\n align?: string;\r\n justify?: string;\r\n gap?: number;\r\n px?: number;\r\n py?: number;\r\n radius?: string;\r\n className?: string;\r\n ref?: (element: HTMLElement | null) => void;\r\n } & Record<string, unknown>;\r\n\r\n function renderIcon(icon: IconProps | IconName | undefined, size: ButtonSize): JSXElement | null {\r\n if (!icon) return null;\r\n\r\n const iconSize = iconSizeMap[size];\r\n\r\n if (typeof icon === 'string') {\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n <Icon name={icon as IconName} size={iconSize} />\r\n </span>\r\n );\r\n }\r\n\r\n const resolvedSize = ((icon as IconProps) as IconConfig).size ?? iconSize;\r\n\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n <Icon {...icon} size={resolvedSize} />\r\n </span>\r\n );\r\n }\r\n\r\n /**\r\n * A polymorphic button component that supports multiple variants, colors, sizes, and states.\r\n *\r\n * @param props - The properties for the Button component.\r\n * @param props.variant - Visual style variant: `'solid' | 'outline' | 'ghost' | 'link'`.\r\n * @param props.color - Color theme: `'brand' | 'success' | 'warning' | 'error' | 'neutral'`.\r\n * @param props.size - Size scale: `'sm' | 'md' | 'lg'`.\r\n * @param props.fullWidth - Whether the button spans the full width of its container.\r\n * @param props.disabled - Whether the button is disabled.\r\n * @param props.loading - Whether the button is in a loading state (disables interaction).\r\n * @param props.leftIcon - Optional icon placed to the left of the label (string name or IconProps).\r\n * @param props.rightIcon - Optional icon placed to the right of the label (string name or IconProps).\r\n * @param props.as - Element type to render: `'button' | 'a' | any polymorphic component`.\r\n * @param props.children - Button label content.\r\n * @param props.className - Additional CSS classes appended to the built-in styles.\r\n * @param props.type - HTML button type attribute (only applied when `as=\"button\"`).\r\n * @param props.restProps - Any other props are forwarded to the underlying element.\r\n *\r\n * @returns A JSX element representing the styled button.\r\n *\r\n * @example\r\n * ```tsx\r\n * <Button variant=\"solid\" color=\"brand\" size=\"md\" onClick={handleClick}>\r\n * Save\r\n * </Button>\r\n * ```\r\n */\r\n export function Button(props: ButtonProps): JSXElement {\r\n const {\r\n variant = 'solid',\r\n color = 'brand',\r\n size = 'md',\r\n fullWidth = false,\r\n disabled = false,\r\n loading = false,\r\n leftIcon,\r\n rightIcon,\r\n as = 'button',\r\n text,\r\n children,\r\n className,\r\n type = 'button',\r\n onMount,\r\n onLoad,\r\n ...restProps\r\n } = props;\r\n\r\n const baseClasses = [\r\n 'inline-flex',\r\n 'items-center',\r\n 'justify-center',\r\n 'font-medium',\r\n 'transition-all',\r\n 'duration-150',\r\n 'select-none',\r\n 'focus:outline-none',\r\n 'focus-visible:ring',\r\n 'focus-visible:ring-offset-2'\r\n ];\r\n\r\n const stateClasses = [];\r\n\r\n if (loading || disabled) {\r\n stateClasses.push('opacity-50', 'cursor-not-allowed', 'pointer-events-none');\r\n }\r\n\r\n if (fullWidth) {\r\n stateClasses.push('w-full');\r\n }\r\n\r\n const paletteClasses = variantClasses[variant][color];\r\n\r\n const classes = [\r\n ...baseClasses,\r\n ...stateClasses,\r\n ...paletteClasses,\r\n className\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n const padding = sizePaddingMap[size];\r\n const gap = sizeGapMap[size];\r\n const labelSize = labelSizeMap[size];\r\n\r\n const content: JSXElement[] = [];\r\n\r\n const left = renderIcon(leftIcon, size);\r\n const right = renderIcon(rightIcon, size);\r\n\r\n if (left) {\r\n content.push(left);\r\n }\r\n\r\n const isKeyLikeText = typeof text === 'string' && text.includes('.');\r\n const label = children ?? (isKeyLikeText ? '--' : text);\r\n\r\n if (label !== undefined && label !== null && label !== '') {\r\n content.push(\r\n <Text as=\"span\" size={labelSize} data-role=\"btn-label\" className='flex items-center'>\r\n {label}\r\n </Text>\r\n );\r\n }\r\n\r\n if (right) {\r\n content.push(right);\r\n }\r\n\r\n const elementType = as;\r\n\r\n const elementTypeProps =\r\n elementType === 'button'\r\n ? { type }\r\n : {};\r\n\r\n const shouldTranslate = isKeyLikeText;\r\n\r\n const handleRef =\r\n (onMount || onLoad || shouldTranslate)\r\n ? (element: HTMLElement | null) => {\r\n if (!element) return;\r\n\r\n if (onMount && !mountedElements.has(element)) {\r\n mountedElements.add(element);\r\n onMount(element);\r\n }\r\n\r\n if (onLoad && !loadedElements.has(element)) {\r\n loadedElements.add(element);\r\n\r\n const runLoad = () => {\r\n onLoad(element);\r\n };\r\n\r\n if (typeof requestAnimationFrame === 'function') {\r\n requestAnimationFrame(() => {\r\n requestAnimationFrame(runLoad);\r\n });\r\n } else {\r\n setTimeout(runLoad, 0);\r\n }\r\n }\r\n\r\n if (shouldTranslate && !translatedElements.has(element)) {\r\n const schedule = (fn: () => void) => {\r\n if (typeof queueMicrotask === 'function') {\r\n queueMicrotask(fn);\r\n } else {\r\n setTimeout(fn, 0);\r\n }\r\n };\r\n\r\n const attemptTranslate = (attempt: number) => {\r\n const labelNode = element.querySelector('[data-role=\\\"btn-label\\\"]');\r\n\r\n if (!labelNode || typeof text !== 'string') return;\r\n\r\n let translated = t(text as string, undefined, '--');\r\n\r\n if (translated !== text && translated !== '--' || attempt >= MAX_TRANSLATION_ATTEMPTS) {\r\n (labelNode as HTMLElement).textContent = String(translated);\r\n translatedElements.add(element);\r\n return;\r\n }\r\n\r\n setTimeout(\r\n () => {\r\n attemptTranslate(attempt + 1);\r\n },\r\n TRANSLATION_RETRY_DELAY_MS\r\n );\r\n };\r\n\r\n schedule(() => {\r\n attemptTranslate(0);\r\n });\r\n }\r\n }\r\n : undefined;\r\n\r\n const containerProps: ButtonContainerProps = {\r\n as,\r\n display : 'inline-flex',\r\n align : 'center',\r\n justify : 'center',\r\n gap,\r\n px : padding.px,\r\n py : padding.py,\r\n radius : 'md',\r\n className : classes,\r\n ...elementTypeProps,\r\n ...restProps\r\n };\r\n\r\n if (handleRef) {\r\n containerProps.ref = handleRef;\r\n }\r\n\r\n return (\r\n <Container {...(containerProps as Record<string, unknown>)}>\r\n {content}\r\n </Container>\r\n );\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -15,6 +15,7 @@ interface ButtonProps {
|
|
|
15
15
|
leftIcon?: IconProps | IconName;
|
|
16
16
|
rightIcon?: IconProps | IconName;
|
|
17
17
|
as?: ContainerAs;
|
|
18
|
+
text?: string | number;
|
|
18
19
|
children?: JSXElement | string | number;
|
|
19
20
|
className?: string;
|
|
20
21
|
id?: string;
|
|
@@ -24,6 +25,8 @@ interface ButtonProps {
|
|
|
24
25
|
rel?: string;
|
|
25
26
|
'aria-label'?: string;
|
|
26
27
|
role?: string;
|
|
28
|
+
onMount?: (e: HTMLElement) => void;
|
|
29
|
+
onLoad?: (e: HTMLElement) => void;
|
|
27
30
|
onClick?: (e: MouseEvent) => void;
|
|
28
31
|
onMouseEnter?: (e: MouseEvent) => void;
|
|
29
32
|
onMouseLeave?: (e: MouseEvent) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ interface ButtonProps {
|
|
|
15
15
|
leftIcon?: IconProps | IconName;
|
|
16
16
|
rightIcon?: IconProps | IconName;
|
|
17
17
|
as?: ContainerAs;
|
|
18
|
+
text?: string | number;
|
|
18
19
|
children?: JSXElement | string | number;
|
|
19
20
|
className?: string;
|
|
20
21
|
id?: string;
|
|
@@ -24,6 +25,8 @@ interface ButtonProps {
|
|
|
24
25
|
rel?: string;
|
|
25
26
|
'aria-label'?: string;
|
|
26
27
|
role?: string;
|
|
28
|
+
onMount?: (e: HTMLElement) => void;
|
|
29
|
+
onLoad?: (e: HTMLElement) => void;
|
|
27
30
|
onClick?: (e: MouseEvent) => void;
|
|
28
31
|
onMouseEnter?: (e: MouseEvent) => void;
|
|
29
32
|
onMouseLeave?: (e: MouseEvent) => void;
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {Container}from'@cruxkit/container';import {Text}from'@cruxkit/text';import {Icon}from'@cruxkit/icon';import {jsx}from'@minejs/jsx/jsx-runtime';var
|
|
1
|
+
import {Container}from'@cruxkit/container';import {Text}from'@cruxkit/text';import {Icon}from'@cruxkit/icon';import {t}from'@cruxjs/client';import {jsx}from'@minejs/jsx/jsx-runtime';var G={sm:{px:3,py:1},md:{px:4,py:2},lg:{px:6,py:3}},K={sm:1,md:2,lg:2},Q={sm:"sm",md:"md",lg:"lg"},U={sm:"sm",md:"md",lg:"lg"},Z={solid:{brand:["bg-brand","text-inverse","border","border-transparent","hover:bg-brand-hover","active:bg-brand-active","active:scale-95","shadow-sm","hover:shadow-md"],success:["bg-success","text-inverse","border","border-transparent","hover:bg-success-hover","active:bg-success-active","active:scale-95","shadow-sm","hover:shadow-md"],warning:["bg-warning","text-inverse","border","border-transparent","hover:bg-warning-hover","active:bg-warning-active","active:scale-95","shadow-sm","hover:shadow-md"],error:["bg-error","text-inverse","border","border-transparent","hover:bg-error-hover","active:bg-error-active","active:scale-95","shadow-sm","hover:shadow-md"],neutral:["bg-surface","text-1","border","border-1","hover:bg-raised","active:bg-tertiary","active:scale-95","shadow-sm","hover:shadow-md"]},outline:{brand:["bg-transparent","text-brand","border","border-brand","hover:bg-brand-subtle","active:bg-brand-subtle","active:scale-95"],success:["bg-transparent","text-success","border","border-success","hover:bg-success-subtle","active:bg-success-subtle","active:scale-95"],warning:["bg-transparent","text-warning","border","border-warning","hover:bg-warning-subtle","active:bg-warning-subtle","active:scale-95"],error:["bg-transparent","text-error","border","border-error","hover:bg-error-subtle","active:bg-error-subtle","active:scale-95"],neutral:["bg-transparent","text-1","border","border-1","hover:bg-raised","active:bg-tertiary","active:scale-95"]},ghost:{brand:["bg-transparent","text-brand","border","border-transparent","hover:bg-brand-subtle","active:bg-brand-subtle","active:scale-95"],success:["bg-transparent","text-success","border","border-transparent","hover:bg-success-subtle","active:bg-success-subtle","active:scale-95"],warning:["bg-transparent","text-warning","border","border-transparent","hover:bg-warning-subtle","active:bg-warning-subtle","active:scale-95"],error:["bg-transparent","text-error","border","border-transparent","hover:bg-error-subtle","active:bg-error-subtle","active:scale-95"],neutral:["bg-transparent","text-1","border","border-transparent","hover:bg-raised","active:bg-tertiary","active:scale-95"]},link:{brand:["bg-transparent","text-brand","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],success:["bg-transparent","text-success","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],warning:["bg-transparent","text-warning","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],error:["bg-transparent","text-error","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],neutral:["bg-transparent","text-1","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"]}},E=new WeakSet,M=new WeakSet,I=new WeakSet,$=5,ee=100;function N(r,l){if(!r)return null;let o=U[l];if(typeof r=="string")return jsx("span",{className:"inline-flex shrink-0",children:jsx(Icon,{name:r,size:o})});let t=r.size??o;return jsx("span",{className:"inline-flex shrink-0",children:jsx(Icon,{...r,size:t})})}function oe(r){let{variant:l="solid",color:o="brand",size:t$1="md",fullWidth:C=false,disabled:R=false,loading:k=false,leftIcon:L,rightIcon:P,as:m="button",text:n,children:A,className:q,type:H="button",onMount:b,onLoad:u,...X}=r,_=["inline-flex","items-center","justify-center","font-medium","transition-all","duration-150","select-none","focus:outline-none","focus-visible:ring","focus-visible:ring-offset-2"],p=[];(k||R)&&p.push("opacity-50","cursor-not-allowed","pointer-events-none"),C&&p.push("w-full");let J=Z[l][o],W=[..._,...p,...J,q].filter(Boolean).join(" "),v=G[t$1],j=K[t$1],F=Q[t$1],i=[],f=N(L,t$1),h=N(P,t$1);f&&i.push(f);let x=typeof n=="string"&&n.includes("."),c=A??(x?"--":n);c!=null&&c!==""&&i.push(jsx(Text,{as:"span",size:F,"data-role":"btn-label",className:"flex items-center",children:c})),h&&i.push(h);let O=m==="button"?{type:H}:{},y=x,w=b||u||y?e=>{if(e){if(b&&!E.has(e)&&(E.add(e),b(e)),u&&!M.has(e)){M.add(e);let d=()=>{u(e);};typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>{requestAnimationFrame(d);}):setTimeout(d,0);}if(y&&!I.has(e)){let d=a=>{typeof queueMicrotask=="function"?queueMicrotask(a):setTimeout(a,0);},S=a=>{let z=e.querySelector('[data-role="btn-label"]');if(!z||typeof n!="string")return;let g=t(n,void 0,"--");if(g!==n&&g!=="--"||a>=$){z.textContent=String(g),I.add(e);return}setTimeout(()=>{S(a+1);},ee);};d(()=>{S(0);});}}}:void 0,T={as:m,display:"inline-flex",align:"center",justify:"center",gap:j,px:v.px,py:v.py,radius:"md",className:W,...O,...X};return w&&(T.ref=w),jsx(Container,{...T,children:i})}export{oe as Button};//# sourceMappingURL=index.js.map
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/kit/button.tsx"],"names":["sizePaddingMap","sizeGapMap","labelSizeMap","iconSizeMap","variantClasses","renderIcon","icon","size","iconSize","jsx","Icon","resolvedSize","Button","props","variant","color","fullWidth","disabled","loading","leftIcon","rightIcon","as","children","className","type","restProps","baseClasses","stateClasses","paletteClasses","classes","padding","gap","labelSize","content","left","right","Text","elementTypeProps","Container"],"mappings":"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","file":"index.js","sourcesContent":["// src/kit/button.tsx\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import type { JSXElement } from '@minejs/jsx';\r\n import { Container } from '@cruxkit/container';\r\n import { Text } from '@cruxkit/text';\r\n import { Icon, type IconProps, type IconName, type IconConfig } from '@cruxkit/icon';\r\n import type { ButtonProps, ButtonSize, ButtonColor, ButtonVariant } from '../types';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ INIT ════════════════════════════════════════╗\r\n\r\n const sizePaddingMap: Record<ButtonSize, { px: 3 | 4 | 6; py: 1 | 2 | 3 }> = {\r\n sm: { px: 3, py: 1 },\r\n md: { px: 4, py: 2 },\r\n lg: { px: 6, py: 3 }\r\n };\r\n\r\n const sizeGapMap: Record<ButtonSize, 1 | 2> = {\r\n sm: 1,\r\n md: 2,\r\n lg: 2\r\n };\r\n\r\n const labelSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const iconSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const variantClasses: Record<ButtonVariant, Record<ButtonColor, string[]>> = {\r\n solid: {\r\n brand: [\r\n 'bg-brand',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-hover',\r\n 'active:bg-brand-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n success: [\r\n 'bg-success',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-hover',\r\n 'active:bg-success-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n warning: [\r\n 'bg-warning',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-hover',\r\n 'active:bg-warning-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n error: [\r\n 'bg-error',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-hover',\r\n 'active:bg-error-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n neutral: [\r\n 'bg-surface',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ]\r\n },\r\n outline: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-brand',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-success',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-warning',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-error',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n ghost: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n link: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ]\r\n }\r\n };\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n function renderIcon(icon: IconProps | IconName | undefined, size: ButtonSize): JSXElement | null {\r\n if (!icon) return null;\r\n\r\n const iconSize = iconSizeMap[size];\r\n\r\n if (typeof icon === 'string') {\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n <Icon name={icon as IconName} size={iconSize} />\r\n </span>\r\n );\r\n }\r\n\r\n const resolvedSize = ((icon as IconProps) as IconConfig).size ?? iconSize;\r\n\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n <Icon {...icon} size={resolvedSize} />\r\n </span>\r\n );\r\n }\r\n\r\n /**\r\n * A polymorphic button component that supports multiple variants, colors, sizes, and states.\r\n *\r\n * @param props - The properties for the Button component.\r\n * @param props.variant - Visual style variant: `'solid' | 'outline' | 'ghost' | 'link'`.\r\n * @param props.color - Color theme: `'brand' | 'success' | 'warning' | 'error' | 'neutral'`.\r\n * @param props.size - Size scale: `'sm' | 'md' | 'lg'`.\r\n * @param props.fullWidth - Whether the button spans the full width of its container.\r\n * @param props.disabled - Whether the button is disabled.\r\n * @param props.loading - Whether the button is in a loading state (disables interaction).\r\n * @param props.leftIcon - Optional icon placed to the left of the label (string name or IconProps).\r\n * @param props.rightIcon - Optional icon placed to the right of the label (string name or IconProps).\r\n * @param props.as - Element type to render: `'button' | 'a' | any polymorphic component`.\r\n * @param props.children - Button label content.\r\n * @param props.className - Additional CSS classes appended to the built-in styles.\r\n * @param props.type - HTML button type attribute (only applied when `as=\"button\"`).\r\n * @param props.restProps - Any other props are forwarded to the underlying element.\r\n *\r\n * @returns A JSX element representing the styled button.\r\n *\r\n * @example\r\n * ```tsx\r\n * <Button variant=\"solid\" color=\"brand\" size=\"md\" onClick={handleClick}>\r\n * Save\r\n * </Button>\r\n * ```\r\n */\r\n export function Button(props: ButtonProps): JSXElement {\r\n const {\r\n variant = 'solid',\r\n color = 'brand',\r\n size = 'md',\r\n fullWidth = false,\r\n disabled = false,\r\n loading = false,\r\n leftIcon,\r\n rightIcon,\r\n as = 'button',\r\n children,\r\n className,\r\n type = 'button',\r\n ...restProps\r\n } = props;\r\n\r\n const baseClasses = [\r\n 'inline-flex',\r\n 'items-center',\r\n 'justify-center',\r\n 'font-medium',\r\n 'transition-all',\r\n 'duration-150',\r\n 'select-none',\r\n 'focus:outline-none',\r\n 'focus-visible:ring',\r\n 'focus-visible:ring-offset-2'\r\n ];\r\n\r\n const stateClasses = [];\r\n\r\n if (loading || disabled) {\r\n stateClasses.push('opacity-50', 'cursor-not-allowed', 'pointer-events-none');\r\n }\r\n\r\n if (fullWidth) {\r\n stateClasses.push('w-full');\r\n }\r\n\r\n const paletteClasses = variantClasses[variant][color];\r\n\r\n const classes = [\r\n ...baseClasses,\r\n ...stateClasses,\r\n ...paletteClasses,\r\n className\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n const padding = sizePaddingMap[size];\r\n const gap = sizeGapMap[size];\r\n const labelSize = labelSizeMap[size];\r\n\r\n const content: JSXElement[] = [];\r\n\r\n const left = renderIcon(leftIcon, size);\r\n const right = renderIcon(rightIcon, size);\r\n\r\n if (left) {\r\n content.push(left);\r\n }\r\n\r\n if (children !== undefined && children !== null && children !== '') {\r\n content.push(\r\n <Text as=\"span\" size={labelSize}>\r\n {children}\r\n </Text>\r\n );\r\n }\r\n\r\n if (right) {\r\n content.push(right);\r\n }\r\n\r\n const elementType = as;\r\n\r\n const elementTypeProps =\r\n elementType === 'button'\r\n ? { type }\r\n : {};\r\n\r\n return (\r\n <Container\r\n as={as}\r\n display = \"inline-flex\"\r\n align = \"center\"\r\n justify = \"center\"\r\n gap = {gap}\r\n px = {padding.px}\r\n py = {padding.py}\r\n radius = \"md\"\r\n className = {classes}\r\n {...elementTypeProps}\r\n {...restProps}\r\n >\r\n {content}\r\n </Container>\r\n );\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/kit/button.tsx"],"names":["sizePaddingMap","sizeGapMap","labelSizeMap","iconSizeMap","variantClasses","mountedElements","loadedElements","translatedElements","MAX_TRANSLATION_ATTEMPTS","TRANSLATION_RETRY_DELAY_MS","renderIcon","icon","size","iconSize","jsx","Icon","resolvedSize","Button","props","variant","color","fullWidth","disabled","loading","leftIcon","rightIcon","as","text","children","className","type","onMount","onLoad","restProps","baseClasses","stateClasses","paletteClasses","classes","padding","gap","labelSize","content","left","right","isKeyLikeText","label","Text","elementTypeProps","shouldTranslate","handleRef","element","runLoad","schedule","fn","attemptTranslate","attempt","labelNode","translated","t","containerProps","Container"],"mappings":"sLAqBI,IAAMA,CAAAA,CAAuE,CACzE,EAAA,CAAI,CAAE,GAAI,CAAA,CAAG,EAAA,CAAI,CAAE,CAAA,CACnB,EAAA,CAAI,CAAE,EAAA,CAAI,CAAA,CAAG,GAAI,CAAE,CAAA,CACnB,GAAI,CAAE,EAAA,CAAI,EAAG,EAAA,CAAI,CAAE,CACvB,CAAA,CAEMC,CAAAA,CAAwC,CAC1C,EAAA,CAAI,EACJ,EAAA,CAAI,CAAA,CACJ,GAAI,CACR,CAAA,CAEMC,EAAuD,CACzD,EAAA,CAAI,KACJ,EAAA,CAAI,IAAA,CACJ,GAAI,IACR,CAAA,CAEMC,EAAsD,CACxD,EAAA,CAAI,KACJ,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,IACR,EAEMC,CAAAA,CAAuE,CACzE,MAAO,CACH,KAAA,CAAO,CACH,UAAA,CACA,cAAA,CACA,SACA,oBAAA,CACA,sBAAA,CACA,yBACA,iBAAA,CACA,WAAA,CACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,YAAA,CACA,cAAA,CACA,QAAA,CACA,oBAAA,CACA,yBACA,0BAAA,CACA,iBAAA,CACA,YACA,iBACJ,CAAA,CACA,QAAS,CACL,YAAA,CACA,eACA,QAAA,CACA,oBAAA,CACA,yBACA,0BAAA,CACA,iBAAA,CACA,YACA,iBACJ,CAAA,CACA,MAAO,CACH,UAAA,CACA,cAAA,CACA,QAAA,CACA,qBACA,sBAAA,CACA,wBAAA,CACA,kBACA,WAAA,CACA,iBACJ,EACA,OAAA,CAAS,CACL,aACA,QAAA,CACA,QAAA,CACA,WACA,iBAAA,CACA,oBAAA,CACA,kBACA,WAAA,CACA,iBACJ,CACJ,CAAA,CACA,OAAA,CAAS,CACL,KAAA,CAAO,CACH,gBAAA,CACA,YAAA,CACA,SACA,cAAA,CACA,uBAAA,CACA,yBACA,iBACJ,CAAA,CACA,QAAS,CACL,gBAAA,CACA,eACA,QAAA,CACA,gBAAA,CACA,0BACA,0BAAA,CACA,iBACJ,EACA,OAAA,CAAS,CACL,gBAAA,CACA,cAAA,CACA,SACA,gBAAA,CACA,yBAAA,CACA,2BACA,iBACJ,CAAA,CACA,MAAO,CACH,gBAAA,CACA,aACA,QAAA,CACA,cAAA,CACA,wBACA,wBAAA,CACA,iBACJ,EACA,OAAA,CAAS,CACL,iBACA,QAAA,CACA,QAAA,CACA,UAAA,CACA,iBAAA,CACA,qBACA,iBACJ,CACJ,EACA,KAAA,CAAO,CACH,MAAO,CACH,gBAAA,CACA,aACA,QAAA,CACA,oBAAA,CACA,wBACA,wBAAA,CACA,iBACJ,EACA,OAAA,CAAS,CACL,iBACA,cAAA,CACA,QAAA,CACA,oBAAA,CACA,yBAAA,CACA,2BACA,iBACJ,CAAA,CACA,QAAS,CACL,gBAAA,CACA,eACA,QAAA,CACA,oBAAA,CACA,0BACA,0BAAA,CACA,iBACJ,EACA,KAAA,CAAO,CACH,iBACA,YAAA,CACA,QAAA,CACA,qBACA,uBAAA,CACA,wBAAA,CACA,iBACJ,CAAA,CACA,QAAS,CACL,gBAAA,CACA,SACA,QAAA,CACA,oBAAA,CACA,kBACA,oBAAA,CACA,iBACJ,CACJ,CAAA,CACA,IAAA,CAAM,CACF,KAAA,CAAO,CACH,iBACA,YAAA,CACA,QAAA,CACA,qBACA,iBAAA,CACA,oBAAA,CACA,cAAA,CACA,MACJ,EACA,OAAA,CAAS,CACL,iBACA,cAAA,CACA,QAAA,CACA,qBACA,iBAAA,CACA,oBAAA,CACA,eACA,MACJ,CAAA,CACA,QAAS,CACL,gBAAA,CACA,eACA,QAAA,CACA,oBAAA,CACA,kBACA,oBAAA,CACA,cAAA,CACA,MACJ,CAAA,CACA,MAAO,CACH,gBAAA,CACA,aACA,QAAA,CACA,oBAAA,CACA,kBACA,oBAAA,CACA,cAAA,CACA,MACJ,CAAA,CACA,OAAA,CAAS,CACL,gBAAA,CACA,QAAA,CACA,SACA,oBAAA,CACA,iBAAA,CACA,qBACA,cAAA,CACA,MACJ,CACJ,CACJ,EAQMC,CAAAA,CAA6B,IAAI,QACjCC,CAAAA,CAA6B,IAAI,QACjCC,CAAAA,CAA6B,IAAI,QACjCC,CAAAA,CAA6B,CAAA,CAC7BC,GAA6B,GAAA,CAenC,SAASC,EAAWC,CAAAA,CAAwCC,CAAAA,CAAqC,CAC7F,GAAI,CAACD,CAAAA,CAAM,OAAO,KAElB,IAAME,CAAAA,CAAWV,EAAYS,CAAI,CAAA,CAEjC,GAAI,OAAOD,CAAAA,EAAS,SAChB,OACIG,GAAAA,CAAC,QAAK,SAAA,CAAU,sBAAA,CACZ,SAAAA,GAAAA,CAACC,IAAAA,CAAA,CAAK,IAAA,CAAMJ,CAAAA,CAAkB,IAAA,CAAME,CAAAA,CAAU,EAClD,CAAA,CAIR,IAAMG,EAAiBL,CAAAA,CAAkC,IAAA,EAAQE,EAEjE,OACIC,GAAAA,CAAC,QAAK,SAAA,CAAU,sBAAA,CACZ,SAAAA,GAAAA,CAACC,IAAAA,CAAA,CAAM,GAAGJ,CAAAA,CAAM,KAAMK,CAAAA,CAAc,CAAA,CACxC,CAER,CA6BO,SAASC,EAAAA,CAAOC,CAAAA,CAAgC,CACnD,GAAM,CACF,QAAAC,CAAAA,CAAc,OAAA,CACd,MAAAC,CAAAA,CAAc,OAAA,CACd,KAAAR,GAAAA,CAAc,IAAA,CACd,UAAAS,CAAAA,CAAc,KAAA,CACd,SAAAC,CAAAA,CAAc,KAAA,CACd,OAAA,CAAAC,CAAAA,CAAc,MACd,QAAA,CAAAC,CAAAA,CACA,UAAAC,CAAAA,CACA,EAAA,CAAAC,EAAc,QAAA,CACd,IAAA,CAAAC,EACA,QAAA,CAAAC,CAAAA,CACA,UAAAC,CAAAA,CACA,IAAA,CAAAC,EAAc,QAAA,CACd,OAAA,CAAAC,EACA,MAAA,CAAAC,CAAAA,CACA,GAAGC,CACP,EAAIf,CAAAA,CAEEgB,CAAAA,CAAc,CAChB,aAAA,CACA,cAAA,CACA,iBACA,aAAA,CACA,gBAAA,CACA,eACA,aAAA,CACA,oBAAA,CACA,qBACA,6BACJ,CAAA,CAEMC,EAAe,EAAC,CAAA,CAElBZ,GAAWD,CAAAA,GACXa,CAAAA,CAAa,IAAA,CAAK,YAAA,CAAc,qBAAsB,qBAAqB,CAAA,CAG3Ed,GACAc,CAAAA,CAAa,IAAA,CAAK,QAAQ,CAAA,CAG9B,IAAMC,EAAiBhC,CAAAA,CAAee,CAAO,EAAEC,CAAK,CAAA,CAE9CiB,EAAU,CACZ,GAAGH,EACH,GAAGC,CAAAA,CACH,GAAGC,CAAAA,CACHP,CACJ,CAAA,CACK,MAAA,CAAO,OAAO,CAAA,CACd,IAAA,CAAK,GAAG,CAAA,CAEPS,CAAAA,CAAYtC,EAAeY,GAAI,CAAA,CAC/B2B,EAAYtC,CAAAA,CAAWW,GAAI,EAC3B4B,CAAAA,CAAYtC,CAAAA,CAAaU,GAAI,CAAA,CAE7B6B,CAAAA,CAAwB,EAAC,CAEzBC,EAAQhC,CAAAA,CAAWc,CAAAA,CAAUZ,GAAI,CAAA,CACjC+B,CAAAA,CAAQjC,EAAWe,CAAAA,CAAWb,GAAI,EAEpC8B,CAAAA,EACAD,CAAAA,CAAQ,KAAKC,CAAI,CAAA,CAGrB,IAAME,CAAAA,CAAgB,OAAOjB,GAAS,QAAA,EAAYA,CAAAA,CAAK,QAAA,CAAS,GAAG,EAC7DkB,CAAAA,CAAgBjB,CAAAA,GAAagB,EAAgB,IAAA,CAAOjB,CAAAA,CAAAA,CAE/BkB,GAAU,IAAA,EAAQA,CAAAA,GAAU,IACnDJ,CAAAA,CAAQ,IAAA,CACJ3B,IAACgC,IAAAA,CAAA,CAAK,GAAG,MAAA,CAAO,IAAA,CAAMN,EAAW,WAAA,CAAU,WAAA,CAAY,SAAA,CAAU,mBAAA,CAC5D,SAAAK,CAAAA,CACL,CACJ,EAGAF,CAAAA,EACAF,CAAAA,CAAQ,KAAKE,CAAK,CAAA,CAKtB,IAAMI,CAAAA,CAFcrB,CAAAA,GAGA,SACV,CAAE,IAAA,CAAAI,CAAK,CAAA,CACP,GAEJkB,CAAAA,CAAkBJ,CAAAA,CAElBK,CAAAA,CACDlB,CAAAA,EAAWC,GAAUgB,CAAAA,CACfE,CAAAA,EAAgC,CAC/B,GAAKA,CAAAA,CAOL,IALInB,CAAAA,EAAW,CAAC1B,EAAgB,GAAA,CAAI6C,CAAO,IACvC7C,CAAAA,CAAgB,GAAA,CAAI6C,CAAO,CAAA,CAC3BnB,CAAAA,CAAQmB,CAAO,CAAA,CAAA,CAGflB,CAAAA,EAAU,CAAC1B,CAAAA,CAAe,IAAI4C,CAAO,CAAA,CAAG,CACxC5C,CAAAA,CAAe,GAAA,CAAI4C,CAAO,CAAA,CAE1B,IAAMC,EAAU,IAAM,CAClBnB,EAAOkB,CAAO,EAClB,EAEI,OAAO,qBAAA,EAA0B,WACjC,qBAAA,CAAsB,IAAM,CACxB,qBAAA,CAAsBC,CAAO,EACjC,CAAC,EAED,UAAA,CAAWA,CAAAA,CAAS,CAAC,EAE7B,CAEA,GAAIH,CAAAA,EAAmB,CAACzC,EAAmB,GAAA,CAAI2C,CAAO,EAAG,CACrD,IAAME,EAAYC,CAAAA,EAAmB,CAC7B,OAAO,cAAA,EAAmB,WAC1B,cAAA,CAAeA,CAAE,EAEjB,UAAA,CAAWA,CAAAA,CAAI,CAAC,EAExB,CAAA,CAEMC,EAAoBC,CAAAA,EAAoB,CAC1C,IAAMC,CAAAA,CAAYN,CAAAA,CAAQ,cAAc,yBAA2B,CAAA,CAEnE,GAAI,CAACM,CAAAA,EAAa,OAAO7B,CAAAA,EAAS,SAAU,OAE5C,IAAI8B,EAAaC,CAAAA,CAAE/B,CAAAA,CAAgB,OAAW,IAAI,CAAA,CAElD,GAAI8B,CAAAA,GAAe9B,CAAAA,EAAQ8B,IAAe,IAAA,EAAQF,CAAAA,EAAW/C,EAA0B,CAClFgD,CAAAA,CAA0B,YAAc,MAAA,CAAOC,CAAU,CAAA,CAC1DlD,CAAAA,CAAmB,IAAI2C,CAAO,CAAA,CAC9B,MACJ,CAEA,UAAA,CACI,IAAM,CACFI,CAAAA,CAAiBC,EAAU,CAAC,EAChC,EACA9C,EACJ,EACJ,EAEA2C,CAAAA,CAAS,IAAM,CACXE,CAAAA,CAAiB,CAAC,EACtB,CAAC,EACL,CAAA,CACJ,CAAA,CACE,OAEJK,CAAAA,CAAuC,CACzC,GAAAjC,CAAAA,CACA,OAAA,CAAY,cACZ,KAAA,CAAY,QAAA,CACZ,QAAY,QAAA,CACZ,GAAA,CAAAa,EACA,EAAA,CAAYD,CAAAA,CAAQ,GACpB,EAAA,CAAYA,CAAAA,CAAQ,GACpB,MAAA,CAAY,IAAA,CACZ,UAAYD,CAAAA,CACZ,GAAGU,EACH,GAAGd,CACP,EAEA,OAAIgB,CAAAA,GACAU,EAAe,GAAA,CAAMV,CAAAA,CAAAA,CAIrBnC,IAAC8C,SAAAA,CAAA,CAAW,GAAID,CAAAA,CACX,QAAA,CAAAlB,EACL,CAER","file":"index.js","sourcesContent":["// src/kit/button.tsx\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import type { JSXElement } from '@minejs/jsx';\r\n import { Container } from '@cruxkit/container';\r\n import { Text } from '@cruxkit/text';\r\n import { Icon, type IconProps, type IconName, type IconConfig } from '@cruxkit/icon';\r\n import type { ButtonProps, ButtonSize, ButtonColor, ButtonVariant } from '../types';\r\n import { t } from '@cruxjs/client';\r\n \r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ INIT ════════════════════════════════════════╗\r\n\r\n const sizePaddingMap: Record<ButtonSize, { px: 3 | 4 | 6; py: 1 | 2 | 3 }> = {\r\n sm: { px: 3, py: 1 },\r\n md: { px: 4, py: 2 },\r\n lg: { px: 6, py: 3 }\r\n };\r\n\r\n const sizeGapMap: Record<ButtonSize, 1 | 2> = {\r\n sm: 1,\r\n md: 2,\r\n lg: 2\r\n };\r\n\r\n const labelSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const iconSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const variantClasses: Record<ButtonVariant, Record<ButtonColor, string[]>> = {\r\n solid: {\r\n brand: [\r\n 'bg-brand',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-hover',\r\n 'active:bg-brand-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n success: [\r\n 'bg-success',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-hover',\r\n 'active:bg-success-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n warning: [\r\n 'bg-warning',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-hover',\r\n 'active:bg-warning-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n error: [\r\n 'bg-error',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-hover',\r\n 'active:bg-error-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n neutral: [\r\n 'bg-surface',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ]\r\n },\r\n outline: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-brand',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-success',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-warning',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-error',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n ghost: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n link: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ]\r\n }\r\n };\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n const mountedElements = new WeakSet<HTMLElement>();\r\n const loadedElements = new WeakSet<HTMLElement>();\r\n const translatedElements = new WeakSet<HTMLElement>();\r\n const MAX_TRANSLATION_ATTEMPTS = 5;\r\n const TRANSLATION_RETRY_DELAY_MS = 100;\r\n\r\n type ButtonContainerProps = {\r\n as?: unknown;\r\n display?: string;\r\n align?: string;\r\n justify?: string;\r\n gap?: number;\r\n px?: number;\r\n py?: number;\r\n radius?: string;\r\n className?: string;\r\n ref?: (element: HTMLElement | null) => void;\r\n } & Record<string, unknown>;\r\n\r\n function renderIcon(icon: IconProps | IconName | undefined, size: ButtonSize): JSXElement | null {\r\n if (!icon) return null;\r\n\r\n const iconSize = iconSizeMap[size];\r\n\r\n if (typeof icon === 'string') {\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n <Icon name={icon as IconName} size={iconSize} />\r\n </span>\r\n );\r\n }\r\n\r\n const resolvedSize = ((icon as IconProps) as IconConfig).size ?? iconSize;\r\n\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n <Icon {...icon} size={resolvedSize} />\r\n </span>\r\n );\r\n }\r\n\r\n /**\r\n * A polymorphic button component that supports multiple variants, colors, sizes, and states.\r\n *\r\n * @param props - The properties for the Button component.\r\n * @param props.variant - Visual style variant: `'solid' | 'outline' | 'ghost' | 'link'`.\r\n * @param props.color - Color theme: `'brand' | 'success' | 'warning' | 'error' | 'neutral'`.\r\n * @param props.size - Size scale: `'sm' | 'md' | 'lg'`.\r\n * @param props.fullWidth - Whether the button spans the full width of its container.\r\n * @param props.disabled - Whether the button is disabled.\r\n * @param props.loading - Whether the button is in a loading state (disables interaction).\r\n * @param props.leftIcon - Optional icon placed to the left of the label (string name or IconProps).\r\n * @param props.rightIcon - Optional icon placed to the right of the label (string name or IconProps).\r\n * @param props.as - Element type to render: `'button' | 'a' | any polymorphic component`.\r\n * @param props.children - Button label content.\r\n * @param props.className - Additional CSS classes appended to the built-in styles.\r\n * @param props.type - HTML button type attribute (only applied when `as=\"button\"`).\r\n * @param props.restProps - Any other props are forwarded to the underlying element.\r\n *\r\n * @returns A JSX element representing the styled button.\r\n *\r\n * @example\r\n * ```tsx\r\n * <Button variant=\"solid\" color=\"brand\" size=\"md\" onClick={handleClick}>\r\n * Save\r\n * </Button>\r\n * ```\r\n */\r\n export function Button(props: ButtonProps): JSXElement {\r\n const {\r\n variant = 'solid',\r\n color = 'brand',\r\n size = 'md',\r\n fullWidth = false,\r\n disabled = false,\r\n loading = false,\r\n leftIcon,\r\n rightIcon,\r\n as = 'button',\r\n text,\r\n children,\r\n className,\r\n type = 'button',\r\n onMount,\r\n onLoad,\r\n ...restProps\r\n } = props;\r\n\r\n const baseClasses = [\r\n 'inline-flex',\r\n 'items-center',\r\n 'justify-center',\r\n 'font-medium',\r\n 'transition-all',\r\n 'duration-150',\r\n 'select-none',\r\n 'focus:outline-none',\r\n 'focus-visible:ring',\r\n 'focus-visible:ring-offset-2'\r\n ];\r\n\r\n const stateClasses = [];\r\n\r\n if (loading || disabled) {\r\n stateClasses.push('opacity-50', 'cursor-not-allowed', 'pointer-events-none');\r\n }\r\n\r\n if (fullWidth) {\r\n stateClasses.push('w-full');\r\n }\r\n\r\n const paletteClasses = variantClasses[variant][color];\r\n\r\n const classes = [\r\n ...baseClasses,\r\n ...stateClasses,\r\n ...paletteClasses,\r\n className\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n const padding = sizePaddingMap[size];\r\n const gap = sizeGapMap[size];\r\n const labelSize = labelSizeMap[size];\r\n\r\n const content: JSXElement[] = [];\r\n\r\n const left = renderIcon(leftIcon, size);\r\n const right = renderIcon(rightIcon, size);\r\n\r\n if (left) {\r\n content.push(left);\r\n }\r\n\r\n const isKeyLikeText = typeof text === 'string' && text.includes('.');\r\n const label = children ?? (isKeyLikeText ? '--' : text);\r\n\r\n if (label !== undefined && label !== null && label !== '') {\r\n content.push(\r\n <Text as=\"span\" size={labelSize} data-role=\"btn-label\" className='flex items-center'>\r\n {label}\r\n </Text>\r\n );\r\n }\r\n\r\n if (right) {\r\n content.push(right);\r\n }\r\n\r\n const elementType = as;\r\n\r\n const elementTypeProps =\r\n elementType === 'button'\r\n ? { type }\r\n : {};\r\n\r\n const shouldTranslate = isKeyLikeText;\r\n\r\n const handleRef =\r\n (onMount || onLoad || shouldTranslate)\r\n ? (element: HTMLElement | null) => {\r\n if (!element) return;\r\n\r\n if (onMount && !mountedElements.has(element)) {\r\n mountedElements.add(element);\r\n onMount(element);\r\n }\r\n\r\n if (onLoad && !loadedElements.has(element)) {\r\n loadedElements.add(element);\r\n\r\n const runLoad = () => {\r\n onLoad(element);\r\n };\r\n\r\n if (typeof requestAnimationFrame === 'function') {\r\n requestAnimationFrame(() => {\r\n requestAnimationFrame(runLoad);\r\n });\r\n } else {\r\n setTimeout(runLoad, 0);\r\n }\r\n }\r\n\r\n if (shouldTranslate && !translatedElements.has(element)) {\r\n const schedule = (fn: () => void) => {\r\n if (typeof queueMicrotask === 'function') {\r\n queueMicrotask(fn);\r\n } else {\r\n setTimeout(fn, 0);\r\n }\r\n };\r\n\r\n const attemptTranslate = (attempt: number) => {\r\n const labelNode = element.querySelector('[data-role=\\\"btn-label\\\"]');\r\n\r\n if (!labelNode || typeof text !== 'string') return;\r\n\r\n let translated = t(text as string, undefined, '--');\r\n\r\n if (translated !== text && translated !== '--' || attempt >= MAX_TRANSLATION_ATTEMPTS) {\r\n (labelNode as HTMLElement).textContent = String(translated);\r\n translatedElements.add(element);\r\n return;\r\n }\r\n\r\n setTimeout(\r\n () => {\r\n attemptTranslate(attempt + 1);\r\n },\r\n TRANSLATION_RETRY_DELAY_MS\r\n );\r\n };\r\n\r\n schedule(() => {\r\n attemptTranslate(0);\r\n });\r\n }\r\n }\r\n : undefined;\r\n\r\n const containerProps: ButtonContainerProps = {\r\n as,\r\n display : 'inline-flex',\r\n align : 'center',\r\n justify : 'center',\r\n gap,\r\n px : padding.px,\r\n py : padding.py,\r\n radius : 'md',\r\n className : classes,\r\n ...elementTypeProps,\r\n ...restProps\r\n };\r\n\r\n if (handleRef) {\r\n containerProps.ref = handleRef;\r\n }\r\n\r\n return (\r\n <Container {...(containerProps as Record<string, unknown>)}>\r\n {content}\r\n </Container>\r\n );\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cruxkit/button",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Polymorphic, theme-aware button component for the Cruxkit ecosystem, built on @minejs/jsx.",
|
|
5
5
|
"keywords": ["crux", "kit", "button"],
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,8 +40,9 @@
|
|
|
40
40
|
"bun": "^1.3.3"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
+
"@cruxjs/client": "^0.2.2",
|
|
43
44
|
"@cruxkit/container": "^0.0.2",
|
|
44
|
-
"@cruxkit/icon": "^0.0.
|
|
45
|
+
"@cruxkit/icon": "^0.0.4",
|
|
45
46
|
"@cruxkit/text": "^0.0.2",
|
|
46
47
|
"@minejs/jsx": "^0.1.3"
|
|
47
48
|
},
|