@cruxkit/button 0.2.4 β†’ 0.2.6

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 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.2.4-black"/>
11
+ <img src="https://img.shields.io/badge/v-0.2.6-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-98.12%25-brightgreen" alt="Test Coverage" />
14
+ <img src="https://img.shields.io/badge/coverage-99.91%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>
@@ -24,17 +24,12 @@
24
24
  <!-- ╔══════════════════════════════ DOC ══════════════════════════════╗ -->
25
25
 
26
26
  - ## Overview πŸ‘€
27
+
27
28
  - #### Why ?
28
- > A small, focused Button primitive for the **Cruxkit** ecosystem. It exposes a
29
- > single, strongly‑typed API that works across apps, sites, and design systems
30
- > built on `@minejs/jsx`, so you don’t reimplement button variants, sizes, and
31
- > states in every project.
29
+ > A lightweight, reactive button kit, built for [`@cruxjs`](https://github.com/cruxjs-org) ecosystem.
32
30
 
33
31
  - #### When ?
34
- > Use it whenever you need a consistent, theme‑aware button: primary actions,
35
- > subtle ghost or outline actions, link‑styled buttons, or full‑width CTAs. It
36
- > fits best in projects already using `@cruxkit/container`, `@cruxkit/text`, and
37
- > `@cruxkit/icon`.
32
+ > When you need a flexible, theme-ready button with built-in variants, colors, sizes, hover/active effects, icons, loading states, and full TypeScript supportβ€”without writing custom styles or logic.
38
33
 
39
34
  <br>
40
35
  <br>
@@ -59,39 +54,32 @@
59
54
 
60
55
  - ### Basic usage
61
56
 
62
- ```tsx
57
+ ```jsx
63
58
  <Button text="Click me" />
64
59
  ```
65
60
 
66
61
  - ### With options
67
62
 
68
- ```tsx
69
- <Button variant="solid" color="brand" size="md">
70
- Save
71
- </Button>
72
-
73
- <Button
74
- variant="outline"
75
- color="success"
76
- size="sm"
77
- fullWidth
78
- leftIcon="check"
79
- rightIcon={{ name: 'arrow-right' }}
80
- >
81
- Continue
82
- </Button>
83
-
84
- <Button
85
- as="a"
86
- href="https://example.com"
87
- variant="link"
88
- color="brand"
89
- onMount={(el) => {
90
- console.log('Button mounted', el);
91
- }}
92
- >
93
- Learn more
94
- </Button>
63
+ ```jsx
64
+ // Variants & Colors
65
+ <Button variant="solid" color="brand" text="Solid Brand" />
66
+ <Button variant="outline" color="success" text="Outline Success" />
67
+ <Button variant="ghost" color="error" text="Ghost Error" />
68
+ <Button variant="link" text="Read More" />
69
+
70
+ // Sizes
71
+ <Button size="sm" text="Small" />
72
+ <Button size="lg" text="Large" />
73
+
74
+ // Icons
75
+ <Button leftIcon="plus" text="Add Item" />
76
+ <Button rightIcon={name:"arrow-left", rotate: 180} text="Continue" />
77
+
78
+ // States & Effects
79
+ <Button loading text="Processing..." />
80
+ <Button disabled text="Not Allowed" />
81
+ <Button hover="scale" active="scale" shadow="md" text="Interactive" />
82
+ <Button fullWidth text="Full Width" />
95
83
  ```
96
84
 
97
85
  <br>
@@ -105,45 +93,42 @@
105
93
  - #### Functions
106
94
 
107
95
  ```tsx
108
- // A polymorphic button component that supports multiple variants, colors, sizes, and states.
109
96
  export function Button(props: ButtonProps): JSXElement
110
97
  ```
111
98
 
112
99
  - #### Types
113
100
 
114
101
  ```tsx
115
- export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'link';
116
- export type ButtonColor = 'brand' | 'success' | 'warning' | 'error' | 'neutral';
117
- export type ButtonSize = 'sm' | 'md' | 'lg';
102
+ export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'link' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info';
103
+ export type ButtonColor = 'brand' | 'success' | 'warning' | 'error' | 'neutral' | 'info';
104
+ export type ButtonSize = 'sm' | 'md' | 'lg';
105
+
106
+ export type ButtonHoverEffect = 'none' | 'opacity' | 'scale' | 'shadow';
107
+ export type ButtonActiveEffect = 'none' | 'scale';
108
+ export type ButtonUnderline = 'none' | 'hover' | 'always';
118
109
 
119
- export interface ButtonProps {
110
+ export interface ButtonProps extends Omit<JSXProps, 'children' | 'color'> {
120
111
  variant? : ButtonVariant;
121
112
  color? : ButtonColor;
122
113
  size? : ButtonSize;
114
+
115
+ hover? : ButtonHoverEffect;
116
+ active? : ButtonActiveEffect;
117
+ underline? : ButtonUnderline;
118
+ uppercase? : boolean;
119
+
123
120
  fullWidth? : boolean;
121
+ labelFullWidth? : boolean;
124
122
  disabled? : boolean;
125
123
  loading? : boolean;
126
124
 
127
125
  leftIcon? : IconProps | IconName;
128
126
  rightIcon? : IconProps | IconName;
129
127
 
130
- as? : ContainerAs;
131
-
132
128
  text? : string | number;
133
129
  children? : JSXElement | string | number;
134
130
 
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;
131
+ // Explicitly define common event handlers for better DX
147
132
  onClick? : (e: MouseEvent) => void;
148
133
  onMouseEnter? : (e: MouseEvent) => void;
149
134
  onMouseLeave? : (e: MouseEvent) => void;
@@ -163,10 +148,6 @@
163
148
 
164
149
  - ##### [@cruxkit/icon](https://github.com/cruxkit-org/icon)
165
150
 
166
- - ##### [@cruxkit/container](https://github.com/cruxkit-org/container)
167
-
168
- - ##### [@cruxkit/..](https://github.com/cruxkit-org)
169
-
170
151
 
171
152
  <!-- β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• -->
172
153
 
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 A={sm:{px:3,py:1},md:{px:4,py:2},lg:{px:6,py:3}},V={sm:1,md:2,lg:2},G={sm:"sm",md:"md",lg:"lg"},K={sm:"sm",md:"md",lg:"lg"},$={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"]}},w=new WeakSet,y=new WeakSet;function z(e,i){if(!e)return null;let s=K[i];if(typeof e=="string")return jsxRuntime.jsx("span",{className:"inline-flex shrink-0",children:jsxRuntime.jsx(icon.Icon,{name:e,size:s})});let r=e.size??s;return jsxRuntime.jsx("span",{className:"inline-flex shrink-0",children:jsxRuntime.jsx(icon.Icon,{...e,size:r})})}function Y(e){let{variant:i="solid",color:s="brand",size:r="md",fullWidth:S=false,labelFullWidth:B=false,disabled:C=false,loading:I=false,leftIcon:P,rightIcon:T,as:u="button",text:c,children:E,className:k,type:M="button",onMount:d,onLoad:l,...N}=e,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"],b=[];(I||C)&&b.push("opacity-50","cursor-not-allowed","pointer-events-none"),S&&b.push("w-full");let L=$[i][s],j=[...R,...b,...L,k].filter(Boolean).join(" "),p=A[r],F=V[r],H=G[r],a=[],g=z(P,r),v=z(T,r);g&&a.push(g);let J=typeof c=="string"&&c.includes("."),o=E??(J?"--":c);o!=null&&o!==""&&a.push(jsxRuntime.jsx(text.Text,{as:"span",size:H,"data-role":"btn-label",className:`flex items-center${B?" w-full justify-center":""}`,children:o})),v&&a.push(v);let W=u==="button"?{type:M}:{},m=d||l?t=>{if(t&&(d&&!w.has(t)&&(w.add(t),d(t)),l&&!y.has(t))){y.add(t);let h=()=>{l(t);};typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>{requestAnimationFrame(h);}):setTimeout(h,0);}}:void 0,f={as:u,display:"inline-flex",align:"center",justify:"center",gap:F,px:p.px,py:p.py,radius:"md",className:j,...W,...N};return m&&(f.ref=m),jsxRuntime.jsx(container.Container,{...f,children:a})}exports.Button=Y;//# sourceMappingURL=index.cjs.map
1
+ 'use strict';var text=require('@cruxkit/text'),icon=require('@cruxkit/icon'),jsxRuntime=require('@minejs/jsx/jsx-runtime');var d={sm:{px:3,py:1},md:{px:4,py:2},lg:{px:6,py:3}},f={sm:1,md:2,lg:2},p={sm:"sm",md:"md",lg:"lg"},c={sm:"sm",md:"md",lg:"lg"},h={solid:{brand:["bg-brand","text-inverse","border","border-transparent","hover:bg-brand-hover","active:bg-brand-active"],success:["bg-success","text-inverse","border","border-transparent","hover:bg-success-hover","active:bg-success-active"],warning:["bg-warning","text-inverse","border","border-transparent","hover:bg-warning-hover","active:bg-warning-active"],error:["bg-error","text-inverse","border","border-transparent","hover:bg-error-hover","active:bg-error-active"],neutral:["bg-surface","text-1","border","border-1","hover:bg-raised","active:bg-tertiary"],info:["bg-info","text-inverse","border","border-transparent","hover:opacity-90"]},outline:{brand:["bg-transparent","text-brand","border","border-brand","hover:bg-brand-subtle","active:bg-brand-subtle"],success:["bg-transparent","text-success","border","border-success","hover:bg-success-subtle","active:bg-success-subtle"],warning:["bg-transparent","text-warning","border","border-warning","hover:bg-warning-subtle","active:bg-warning-subtle"],error:["bg-transparent","text-error","border","border-error","hover:bg-error-subtle","active:bg-error-subtle"],neutral:["bg-transparent","text-1","border","border-1","hover:bg-raised","active:bg-tertiary"],info:["bg-transparent","text-info","border","border-info","hover:opacity-90"]},ghost:{brand:["bg-transparent","text-brand","border","border-transparent","hover:bg-brand-subtle","active:bg-brand-subtle"],success:["bg-transparent","text-success","border","border-transparent","hover:bg-success-subtle","active:bg-success-subtle"],warning:["bg-transparent","text-warning","border","border-transparent","hover:bg-warning-subtle","active:bg-warning-subtle"],error:["bg-transparent","text-error","border","border-transparent","hover:bg-error-subtle","active:bg-error-subtle"],neutral:["bg-transparent","text-1","border","border-transparent","hover:bg-raised","active:bg-tertiary"],info:["bg-transparent","text-info","border","border-transparent","hover:opacity-90"]},link:{brand:["bg-transparent","text-brand","border","border-transparent","px-1"],success:["bg-transparent","text-success","border","border-transparent","px-1"],warning:["bg-transparent","text-warning","border","border-transparent","px-1"],error:["bg-transparent","text-error","border","border-transparent","px-1"],neutral:["bg-transparent","text-1","border","border-transparent","px-1"],info:["bg-transparent","text-info","border","border-transparent","px-1"]},danger:{brand:["bg-error","text-inverse","border","border-transparent"],success:["bg-error","text-inverse","border","border-transparent"],warning:["bg-error","text-inverse","border","border-transparent"],error:["bg-error","text-inverse","border","border-transparent"],neutral:["bg-error","text-inverse","border","border-transparent"],info:["bg-error","text-inverse","border","border-transparent"]},primary:{brand:["bg-brand","text-inverse","border","border-transparent"],success:["bg-brand","text-inverse","border","border-transparent"],warning:["bg-brand","text-inverse","border","border-transparent"],error:["bg-brand","text-inverse","border","border-transparent"],neutral:["bg-brand","text-inverse","border","border-transparent"],info:["bg-brand","text-inverse","border","border-transparent"]},secondary:{brand:["bg-raised","text-1","border","border-transparent"],success:["bg-raised","text-1","border","border-transparent"],warning:["bg-raised","text-1","border","border-transparent"],error:["bg-raised","text-1","border","border-transparent"],neutral:["bg-raised","text-1","border","border-transparent"],info:["bg-raised","text-1","border","border-transparent"]},success:{brand:["bg-success","text-inverse","border","border-transparent"],success:["bg-success","text-inverse","border","border-transparent"],warning:["bg-success","text-inverse","border","border-transparent"],error:["bg-success","text-inverse","border","border-transparent"],neutral:["bg-success","text-inverse","border","border-transparent"],info:["bg-success","text-inverse","border","border-transparent"]},warning:{brand:["bg-warning","text-inverse","border","border-transparent"],success:["bg-warning","text-inverse","border","border-transparent"],warning:["bg-warning","text-inverse","border","border-transparent"],error:["bg-warning","text-inverse","border","border-transparent"],neutral:["bg-warning","text-inverse","border","border-transparent"],info:["bg-warning","text-inverse","border","border-transparent"]},info:{brand:["bg-info","text-inverse","border","border-transparent"],success:["bg-info","text-inverse","border","border-transparent"],warning:["bg-info","text-inverse","border","border-transparent"],error:["bg-info","text-inverse","border","border-transparent"],neutral:["bg-info","text-inverse","border","border-transparent"],info:["bg-info","text-inverse","border","border-transparent"]}};function m(n,s){if(!n)return null;let b=c[s];if(typeof n=="string")return jsxRuntime.jsx("span",{className:"inline-flex shrink-0",children:jsxRuntime.jsx(icon.Icon,{name:n,size:b})});let e=n.size??b;return jsxRuntime.jsx("span",{className:"inline-flex shrink-0",children:jsxRuntime.jsx(icon.Icon,{...n,size:e})})}function Z(n){let{variant:s="solid",color:b="brand",size:e="md",hover:y,active:z,shadow:S,radius:B,underline:M,uppercase:I,fullWidth:C,labelFullWidth:N,disabled:u,loading:o,leftIcon:k,rightIcon:P,as:R="button",text:E,children:$,className:l,onClick:J,onMouseEnter:L,onMouseLeave:X,...G}=n,v=["primary","secondary","success","warning","danger","info"].includes(s),T=s==="solid",V=s==="link",W=S??(v||T?"sm":"none"),j=z??"scale",i=y??(v?"opacity":"none"),x=M??(V?"hover":"none"),A=B??"base",r=["inline-flex","items-center","justify-center","transition-all","duration-200","focus:outline-none","font-medium"];u||o?r.push("opacity-50","cursor-not-allowed","pointer-events-none"):r.push("cursor-pointer"),C&&r.push("w-full"),r.push(`gap-${f[e]}`),r.push(`px-${d[e].px}`),r.push(`py-${d[e].py}`),r.push(`text-${p[e]}`);let F=h[s]?.[b]||[];r.push(...F),i==="opacity"&&r.push("hover:opacity-90"),i==="scale"&&r.push("hover:scale-105"),i==="shadow"&&r.push("hover:shadow-md"),j==="scale"&&r.push("active:scale-95"),x==="hover"&&r.push("hover:underline","underline-offset-4","decoration-2"),x==="always"&&r.push("underline","underline-offset-4","decoration-2"),I&&r.push("uppercase","tracking-wide"),l&&r.push(l);let a=$||E,H=p[e];return jsxRuntime.jsxs("div",{as:R,className:r.join(" "),radius:A,shadow:W,onClick:U=>{!u&&!o&&J?.(U);},onMouseEnter:L,onMouseLeave:X,...G,children:[o&&jsxRuntime.jsx("span",{className:"animate-spin mr-2",children:jsxRuntime.jsx(icon.Icon,{name:"spinner",size:c[e]})}),o?jsxRuntime.jsx(jsxRuntime.Fragment,{}):m(k,e),a&&(typeof a=="string"||typeof a=="number")?jsxRuntime.jsx(text.Text,{size:H,className:N?"flex-1 text-center":"",children:a}):a,o?jsxRuntime.jsx(jsxRuntime.Fragment,{}):m(P,e)]})}exports.Button=Z;//# sourceMappingURL=index.cjs.map
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/kit/button.tsx"],"names":["sizePaddingMap","sizeGapMap","labelSizeMap","iconSizeMap","variantClasses","mountedElements","loadedElements","renderIcon","icon","size","iconSize","jsx","Icon","resolvedSize","Button","props","variant","color","fullWidth","labelFullWidth","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","handleRef","element","runLoad","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 \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\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.labelFullWidth - Whether the label spans the full width of the button.\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 labelFullWidth = 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${labelFullWidth ? ' w-full justify-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\r\n const handleRef =\r\n (onMount || onLoad)\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 : 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"]}
1
+ {"version":3,"sources":["../src/kit/constants.ts","../src/kit/button.tsx"],"names":["sizePaddingMap","sizeGapMap","labelSizeMap","iconSizeMap","variantClasses","renderIcon","icon","size","iconSize","jsx","Icon","resolvedSize","Button","props","variant","color","hover","active","shadow","radius","underline","uppercase","fullWidth","labelFullWidth","disabled","loading","leftIcon","rightIcon","as","text","children","className","onClick","onMouseEnter","onMouseLeave","rest","isSemantic","isSolid","isLink","resolvedShadow","resolvedActive","resolvedHover","resolvedUnderline","resolvedRadius","baseClasses","variantStyle","content","labelSize","jsxs","e","Fragment","Text"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ButtonSize, ButtonVariant, ButtonColor } from '../types';\n\nexport const sizePaddingMap: Record<ButtonSize, { px: 3 | 4 | 6; py: 1 | 2 | 3 }> = {\n sm: { px: 3, py: 1 },\n md: { px: 4, py: 2 },\n lg: { px: 6, py: 3 }\n};\n\nexport const sizeGapMap: Record<ButtonSize, 1 | 2> = {\n sm: 1,\n md: 2,\n lg: 2\n};\n\nexport const labelSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\n sm: 'sm',\n md: 'md',\n lg: 'lg'\n};\n\nexport const iconSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\n sm: 'sm',\n md: 'md',\n lg: 'lg'\n};\n\nexport const variantClasses: Record<ButtonVariant, Record<ButtonColor, string[]>> = {\n solid: {\n brand: ['bg-brand', 'text-inverse', 'border', 'border-transparent', 'hover:bg-brand-hover', 'active:bg-brand-active'],\n success: ['bg-success', 'text-inverse', 'border', 'border-transparent', 'hover:bg-success-hover', 'active:bg-success-active'],\n warning: ['bg-warning', 'text-inverse', 'border', 'border-transparent', 'hover:bg-warning-hover', 'active:bg-warning-active'],\n error: ['bg-error', 'text-inverse', 'border', 'border-transparent', 'hover:bg-error-hover', 'active:bg-error-active'],\n neutral: ['bg-surface', 'text-1', 'border', 'border-1', 'hover:bg-raised', 'active:bg-tertiary'],\n info: ['bg-info', 'text-inverse', 'border', 'border-transparent', 'hover:opacity-90']\n },\n outline: {\n brand: ['bg-transparent', 'text-brand', 'border', 'border-brand', 'hover:bg-brand-subtle', 'active:bg-brand-subtle'],\n success: ['bg-transparent', 'text-success', 'border', 'border-success', 'hover:bg-success-subtle', 'active:bg-success-subtle'],\n warning: ['bg-transparent', 'text-warning', 'border', 'border-warning', 'hover:bg-warning-subtle', 'active:bg-warning-subtle'],\n error: ['bg-transparent', 'text-error', 'border', 'border-error', 'hover:bg-error-subtle', 'active:bg-error-subtle'],\n neutral: ['bg-transparent', 'text-1', 'border', 'border-1', 'hover:bg-raised', 'active:bg-tertiary'],\n info: ['bg-transparent', 'text-info', 'border', 'border-info', 'hover:opacity-90']\n },\n ghost: {\n brand: ['bg-transparent', 'text-brand', 'border', 'border-transparent', 'hover:bg-brand-subtle', 'active:bg-brand-subtle'],\n success: ['bg-transparent', 'text-success', 'border', 'border-transparent', 'hover:bg-success-subtle', 'active:bg-success-subtle'],\n warning: ['bg-transparent', 'text-warning', 'border', 'border-transparent', 'hover:bg-warning-subtle', 'active:bg-warning-subtle'],\n error: ['bg-transparent', 'text-error', 'border', 'border-transparent', 'hover:bg-error-subtle', 'active:bg-error-subtle'],\n neutral: ['bg-transparent', 'text-1', 'border', 'border-transparent', 'hover:bg-raised', 'active:bg-tertiary'],\n info: ['bg-transparent', 'text-info', 'border', 'border-transparent', 'hover:opacity-90']\n },\n link: {\n brand: ['bg-transparent', 'text-brand', 'border', 'border-transparent', 'px-1'],\n success: ['bg-transparent', 'text-success', 'border', 'border-transparent', 'px-1'],\n warning: ['bg-transparent', 'text-warning', 'border', 'border-transparent', 'px-1'],\n error: ['bg-transparent', 'text-error', 'border', 'border-transparent', 'px-1'],\n neutral: ['bg-transparent', 'text-1', 'border', 'border-transparent', 'px-1'],\n info: ['bg-transparent', 'text-info', 'border', 'border-transparent', 'px-1']\n },\n danger: {\n brand: ['bg-error', 'text-inverse', 'border', 'border-transparent'],\n success: ['bg-error', 'text-inverse', 'border', 'border-transparent'],\n warning: ['bg-error', 'text-inverse', 'border', 'border-transparent'],\n error: ['bg-error', 'text-inverse', 'border', 'border-transparent'],\n neutral: ['bg-error', 'text-inverse', 'border', 'border-transparent'],\n info: ['bg-error', 'text-inverse', 'border', 'border-transparent']\n },\n primary: {\n brand: ['bg-brand', 'text-inverse', 'border', 'border-transparent'],\n success: ['bg-brand', 'text-inverse', 'border', 'border-transparent'],\n warning: ['bg-brand', 'text-inverse', 'border', 'border-transparent'],\n error: ['bg-brand', 'text-inverse', 'border', 'border-transparent'],\n neutral: ['bg-brand', 'text-inverse', 'border', 'border-transparent'],\n info: ['bg-brand', 'text-inverse', 'border', 'border-transparent']\n },\n secondary: {\n brand: ['bg-raised', 'text-1', 'border', 'border-transparent'],\n success: ['bg-raised', 'text-1', 'border', 'border-transparent'],\n warning: ['bg-raised', 'text-1', 'border', 'border-transparent'],\n error: ['bg-raised', 'text-1', 'border', 'border-transparent'],\n neutral: ['bg-raised', 'text-1', 'border', 'border-transparent'],\n info: ['bg-raised', 'text-1', 'border', 'border-transparent']\n },\n success: {\n brand: ['bg-success', 'text-inverse', 'border', 'border-transparent'],\n success: ['bg-success', 'text-inverse', 'border', 'border-transparent'],\n warning: ['bg-success', 'text-inverse', 'border', 'border-transparent'],\n error: ['bg-success', 'text-inverse', 'border', 'border-transparent'],\n neutral: ['bg-success', 'text-inverse', 'border', 'border-transparent'],\n info: ['bg-success', 'text-inverse', 'border', 'border-transparent']\n },\n warning: {\n brand: ['bg-warning', 'text-inverse', 'border', 'border-transparent'],\n success: ['bg-warning', 'text-inverse', 'border', 'border-transparent'],\n warning: ['bg-warning', 'text-inverse', 'border', 'border-transparent'],\n error: ['bg-warning', 'text-inverse', 'border', 'border-transparent'],\n neutral: ['bg-warning', 'text-inverse', 'border', 'border-transparent'],\n info: ['bg-warning', 'text-inverse', 'border', 'border-transparent']\n },\n info: {\n brand: ['bg-info', 'text-inverse', 'border', 'border-transparent'],\n success: ['bg-info', 'text-inverse', 'border', 'border-transparent'],\n warning: ['bg-info', 'text-inverse', 'border', 'border-transparent'],\n error: ['bg-info', 'text-inverse', 'border', 'border-transparent'],\n neutral: ['bg-info', 'text-inverse', 'border', 'border-transparent'],\n info: ['bg-info', 'text-inverse', 'border', 'border-transparent']\n }\n};\n","// 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 { Text } from '@cruxkit/text';\r\n import { Icon, type IconProps, type IconName, type IconConfig } from '@cruxkit/icon';\r\n import type { ButtonProps, ButtonSize } from '../types';\r\n import {\r\n sizePaddingMap,\r\n sizeGapMap,\r\n labelSizeMap,\r\n iconSizeMap,\r\n variantClasses\r\n } from './constants';\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 * Button Component\r\n *\r\n * A versatile button component with support for variants, colors, sizes, and icons.\r\n * Now features enhanced style controllers for effects and interactions.\r\n *\r\n * @param {ButtonProps } props - The properties for the button.\r\n * @param {ButtonVariant } [props.variant='solid'] - Visual style variant.\r\n * - `solid`: Filled background (default).\r\n * - `outline`: Border with transparent background.\r\n * - `ghost`: Transparent background, hover effect.\r\n * - `link`: Looks like a text link.\r\n * - `primary`, `secondary`, `success`, `warning`, `danger`, `info`: Semantic variants.\r\n * @param {ButtonColor } [props.color='brand'] - Color theme.\r\n * - `brand`, `success`, `warning`, `error`, `neutral`, `info`.\r\n * @param {ButtonSize } [props.size='md'] - Button size.\r\n * - `sm`: Small.\r\n * - `md`: Medium.\r\n * - `lg`: Large.\r\n * @param {ButtonHoverEffect } [props.hover] - Hover effect.\r\n * - `opacity`: Reduces opacity on hover.\r\n * - `scale`: Scales up slightly on hover.\r\n * - `shadow`: Adds shadow on hover.\r\n * - `none`: No hover effect.\r\n * - Defaults depend on variant (e.g., semantic variants default to `opacity`).\r\n * @param {ButtonActiveEffect } [props.active='scale'] - Click/Active effect.\r\n * - `scale`: Scales down slightly on click.\r\n * - `none`: No active effect.\r\n * @param {string } [props.shadow] - Box shadow style (e.g., 'sm', 'md', 'lg', 'none'). Defaults based on variant.\r\n * @param {string } [props.radius='base'] - Border radius (e.g., 'none', 'sm', 'base', 'md', 'lg', 'full').\r\n * @param {ButtonUnderline } [props.underline] - Underline style for text.\r\n * - `hover`: Underline on hover.\r\n * - `always`: Always underlined.\r\n * - `none`: No underline.\r\n * @param {boolean} [props.uppercase=false] - If true, transforms text to uppercase.\r\n * @param {boolean} [props.fullWidth=false] - If true, the button takes up the full width of its container.\r\n * @param {boolean} [props.labelFullWidth=false] - If true, the label text takes up the remaining space (useful with icons).\r\n * @param {boolean} [props.disabled=false] - If true, disables interaction and applies disabled styles.\r\n * @param {boolean} [props.loading=false] - If true, shows a loading spinner and disables interaction.\r\n * @param {IconProps | IconName} [props.leftIcon] - Icon to display on the left side.\r\n * @param {IconProps | IconName} [props.rightIcon] - Icon to display on the right side.\r\n * @param {string} [props.as='button'] - The HTML element or component to render as.\r\n * @param {string | number} [props.text] - The text content of the button.\r\n * @param {JSXElement | string | number} [props.children] - Child elements (overrides text).\r\n * @param {string} [props.className] - Additional CSS classes.\r\n * @param {(e: MouseEvent) => void} [props.onClick] - Click handler.\r\n * @param {(e: MouseEvent) => void} [props.onMouseEnter] - Mouse enter handler.\r\n * @param {(e: MouseEvent) => void} [props.onMouseLeave] - Mouse leave handler.\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\r\n // Style Controllers\r\n hover,\r\n active,\r\n shadow,\r\n radius,\r\n underline,\r\n uppercase,\r\n\r\n fullWidth,\r\n labelFullWidth,\r\n disabled,\r\n loading,\r\n\r\n leftIcon,\r\n rightIcon,\r\n\r\n as = 'button',\r\n text,\r\n children,\r\n\r\n className,\r\n onClick,\r\n onMouseEnter,\r\n onMouseLeave,\r\n\r\n ...rest\r\n } = props;\r\n\r\n // 1. Resolve Defaults based on Variant\r\n const isSemantic = ['primary', 'secondary', 'success', 'warning', 'danger', 'info'].includes(variant);\r\n const isSolid = variant === 'solid';\r\n const isLink = variant === 'link';\r\n\r\n const resolvedShadow = shadow ?? ((isSemantic || isSolid) ? 'sm' : 'none');\r\n const resolvedActive = active ?? 'scale';\r\n // Legacy variants (solid/outline/ghost) have built-in color hovers, so we default to 'none' to avoid double effects\r\n // Semantic variants use opacity hover by default\r\n const resolvedHover = hover ?? (isSemantic ? 'opacity' : 'none');\r\n const resolvedUnderline = underline ?? (isLink ? 'hover' : 'none');\r\n const resolvedRadius = radius ?? 'base'; // Default to base rounded\r\n\r\n // 2. Compose Classes\r\n const baseClasses = [\r\n 'inline-flex', 'items-center', 'justify-center',\r\n 'transition-all', 'duration-200',\r\n 'focus:outline-none',\r\n 'font-medium'\r\n ];\r\n\r\n // State Classes\r\n if (disabled || loading) {\r\n baseClasses.push('opacity-50', 'cursor-not-allowed', 'pointer-events-none');\r\n } else {\r\n baseClasses.push('cursor-pointer');\r\n }\r\n\r\n // Size Classes\r\n if (fullWidth) baseClasses.push('w-full');\r\n baseClasses.push(`gap-${sizeGapMap[size]}`);\r\n baseClasses.push(`px-${sizePaddingMap[size].px}`);\r\n baseClasses.push(`py-${sizePaddingMap[size].py}`);\r\n baseClasses.push(`text-${labelSizeMap[size]}`); // Ensure text size matches button size\r\n\r\n // Variant & Color Classes (from Constants)\r\n const variantStyle = variantClasses[variant]?.[color] || [];\r\n baseClasses.push(...variantStyle);\r\n\r\n // Hover Effects\r\n if (resolvedHover === 'opacity') baseClasses.push('hover:opacity-90');\r\n if (resolvedHover === 'scale') baseClasses.push('hover:scale-105');\r\n if (resolvedHover === 'shadow') baseClasses.push('hover:shadow-md');\r\n\r\n // Active Effects\r\n if (resolvedActive === 'scale') baseClasses.push('active:scale-95');\r\n\r\n // Underline\r\n if (resolvedUnderline === 'hover') baseClasses.push('hover:underline', 'underline-offset-4', 'decoration-2');\r\n if (resolvedUnderline === 'always') baseClasses.push('underline', 'underline-offset-4', 'decoration-2');\r\n\r\n // Uppercase\r\n if (uppercase) baseClasses.push('uppercase', 'tracking-wide');\r\n\r\n // Custom ClassName\r\n if (className) baseClasses.push(className);\r\n\r\n\r\n // 3. Render\r\n const content = children || text;\r\n const labelSize = labelSizeMap[size];\r\n\r\n return (\r\n <div\r\n as={as}\r\n className={baseClasses.join(' ')}\r\n radius={resolvedRadius}\r\n shadow={resolvedShadow}\r\n onClick={(e: MouseEvent) => {\r\n if (!disabled && !loading) {\r\n onClick?.(e);\r\n }\r\n }}\r\n onMouseEnter={onMouseEnter}\r\n onMouseLeave={onMouseLeave}\r\n {...rest}\r\n >\r\n {loading && (\r\n <span className=\"animate-spin mr-2\">\r\n <Icon name='spinner' size={iconSizeMap[size]} />\r\n </span>\r\n )}\r\n\r\n {!loading ? renderIcon(leftIcon, size) : <></>}\r\n\r\n {content && (typeof content === 'string' || typeof content === 'number') ? (\r\n <Text\r\n size={labelSize}\r\n className={labelFullWidth ? 'flex-1 text-center' : ''}\r\n >\r\n {content}\r\n </Text>\r\n ) : content}\r\n\r\n {!loading ? renderIcon(rightIcon, size) : <></>}\r\n </div>\r\n );\r\n }\r\n\r\n// β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•\r\n"]}
package/dist/index.d.cts CHANGED
@@ -1,66 +1,82 @@
1
- import { JSXElement } from '@minejs/jsx';
2
- import { ContainerAs } from '@cruxkit/container';
1
+ import { JSXProps, JSXElement } from '@minejs/jsx';
3
2
  import { IconProps, IconName } from '@cruxkit/icon';
4
3
 
5
- type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'link';
6
- type ButtonColor = 'brand' | 'success' | 'warning' | 'error' | 'neutral';
4
+ type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'link' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info';
5
+ type ButtonColor = 'brand' | 'success' | 'warning' | 'error' | 'neutral' | 'info';
7
6
  type ButtonSize = 'sm' | 'md' | 'lg';
8
- interface ButtonProps {
7
+ type ButtonHoverEffect = 'none' | 'opacity' | 'scale' | 'shadow';
8
+ type ButtonActiveEffect = 'none' | 'scale';
9
+ type ButtonUnderline = 'none' | 'hover' | 'always';
10
+ interface ButtonProps extends Omit<JSXProps, 'children' | 'color'> {
9
11
  variant?: ButtonVariant;
10
12
  color?: ButtonColor;
11
13
  size?: ButtonSize;
14
+ hover?: ButtonHoverEffect;
15
+ active?: ButtonActiveEffect;
16
+ underline?: ButtonUnderline;
17
+ uppercase?: boolean;
12
18
  fullWidth?: boolean;
13
19
  labelFullWidth?: boolean;
14
20
  disabled?: boolean;
15
21
  loading?: boolean;
16
22
  leftIcon?: IconProps | IconName;
17
23
  rightIcon?: IconProps | IconName;
18
- as?: ContainerAs;
19
24
  text?: string | number;
20
25
  children?: JSXElement | string | number;
21
- className?: string;
22
- id?: string;
23
- type?: 'button' | 'submit' | 'reset';
24
- href?: string;
25
- target?: string;
26
- rel?: string;
27
- 'aria-label'?: string;
28
- role?: string;
29
- onMount?: (e: HTMLElement) => void;
30
- onLoad?: (e: HTMLElement) => void;
31
26
  onClick?: (e: MouseEvent) => void;
32
27
  onMouseEnter?: (e: MouseEvent) => void;
33
28
  onMouseLeave?: (e: MouseEvent) => void;
34
29
  }
35
30
 
36
31
  /**
37
- * A polymorphic button component that supports multiple variants, colors, sizes, and states.
38
- *
39
- * @param props - The properties for the Button component.
40
- * @param props.variant - Visual style variant: `'solid' | 'outline' | 'ghost' | 'link'`.
41
- * @param props.color - Color theme: `'brand' | 'success' | 'warning' | 'error' | 'neutral'`.
42
- * @param props.size - Size scale: `'sm' | 'md' | 'lg'`.
43
- * @param props.fullWidth - Whether the button spans the full width of its container.
44
- * @param props.labelFullWidth - Whether the label spans the full width of the button.
45
- * @param props.disabled - Whether the button is disabled.
46
- * @param props.loading - Whether the button is in a loading state (disables interaction).
47
- * @param props.leftIcon - Optional icon placed to the left of the label (string name or IconProps).
48
- * @param props.rightIcon - Optional icon placed to the right of the label (string name or IconProps).
49
- * @param props.as - Element type to render: `'button' | 'a' | any polymorphic component`.
50
- * @param props.children - Button label content.
51
- * @param props.className - Additional CSS classes appended to the built-in styles.
52
- * @param props.type - HTML button type attribute (only applied when `as="button"`).
53
- * @param props.restProps - Any other props are forwarded to the underlying element.
54
- *
55
- * @returns A JSX element representing the styled button.
56
- *
57
- * @example
58
- * ```tsx
59
- * <Button variant="solid" color="brand" size="md" onClick={handleClick}>
60
- * Save
61
- * </Button>
62
- * ```
63
- */
32
+ * Button Component
33
+ *
34
+ * A versatile button component with support for variants, colors, sizes, and icons.
35
+ * Now features enhanced style controllers for effects and interactions.
36
+ *
37
+ * @param {ButtonProps } props - The properties for the button.
38
+ * @param {ButtonVariant } [props.variant='solid'] - Visual style variant.
39
+ * - `solid`: Filled background (default).
40
+ * - `outline`: Border with transparent background.
41
+ * - `ghost`: Transparent background, hover effect.
42
+ * - `link`: Looks like a text link.
43
+ * - `primary`, `secondary`, `success`, `warning`, `danger`, `info`: Semantic variants.
44
+ * @param {ButtonColor } [props.color='brand'] - Color theme.
45
+ * - `brand`, `success`, `warning`, `error`, `neutral`, `info`.
46
+ * @param {ButtonSize } [props.size='md'] - Button size.
47
+ * - `sm`: Small.
48
+ * - `md`: Medium.
49
+ * - `lg`: Large.
50
+ * @param {ButtonHoverEffect } [props.hover] - Hover effect.
51
+ * - `opacity`: Reduces opacity on hover.
52
+ * - `scale`: Scales up slightly on hover.
53
+ * - `shadow`: Adds shadow on hover.
54
+ * - `none`: No hover effect.
55
+ * - Defaults depend on variant (e.g., semantic variants default to `opacity`).
56
+ * @param {ButtonActiveEffect } [props.active='scale'] - Click/Active effect.
57
+ * - `scale`: Scales down slightly on click.
58
+ * - `none`: No active effect.
59
+ * @param {string } [props.shadow] - Box shadow style (e.g., 'sm', 'md', 'lg', 'none'). Defaults based on variant.
60
+ * @param {string } [props.radius='base'] - Border radius (e.g., 'none', 'sm', 'base', 'md', 'lg', 'full').
61
+ * @param {ButtonUnderline } [props.underline] - Underline style for text.
62
+ * - `hover`: Underline on hover.
63
+ * - `always`: Always underlined.
64
+ * - `none`: No underline.
65
+ * @param {boolean} [props.uppercase=false] - If true, transforms text to uppercase.
66
+ * @param {boolean} [props.fullWidth=false] - If true, the button takes up the full width of its container.
67
+ * @param {boolean} [props.labelFullWidth=false] - If true, the label text takes up the remaining space (useful with icons).
68
+ * @param {boolean} [props.disabled=false] - If true, disables interaction and applies disabled styles.
69
+ * @param {boolean} [props.loading=false] - If true, shows a loading spinner and disables interaction.
70
+ * @param {IconProps | IconName} [props.leftIcon] - Icon to display on the left side.
71
+ * @param {IconProps | IconName} [props.rightIcon] - Icon to display on the right side.
72
+ * @param {string} [props.as='button'] - The HTML element or component to render as.
73
+ * @param {string | number} [props.text] - The text content of the button.
74
+ * @param {JSXElement | string | number} [props.children] - Child elements (overrides text).
75
+ * @param {string} [props.className] - Additional CSS classes.
76
+ * @param {(e: MouseEvent) => void} [props.onClick] - Click handler.
77
+ * @param {(e: MouseEvent) => void} [props.onMouseEnter] - Mouse enter handler.
78
+ * @param {(e: MouseEvent) => void} [props.onMouseLeave] - Mouse leave handler.
79
+ */
64
80
  declare function Button(props: ButtonProps): JSXElement;
65
81
 
66
- export { Button, type ButtonColor, type ButtonProps, type ButtonSize, type ButtonVariant };
82
+ export { Button, type ButtonActiveEffect, type ButtonColor, type ButtonHoverEffect, type ButtonProps, type ButtonSize, type ButtonUnderline, type ButtonVariant };
package/dist/index.d.ts CHANGED
@@ -1,66 +1,82 @@
1
- import { JSXElement } from '@minejs/jsx';
2
- import { ContainerAs } from '@cruxkit/container';
1
+ import { JSXProps, JSXElement } from '@minejs/jsx';
3
2
  import { IconProps, IconName } from '@cruxkit/icon';
4
3
 
5
- type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'link';
6
- type ButtonColor = 'brand' | 'success' | 'warning' | 'error' | 'neutral';
4
+ type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'link' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info';
5
+ type ButtonColor = 'brand' | 'success' | 'warning' | 'error' | 'neutral' | 'info';
7
6
  type ButtonSize = 'sm' | 'md' | 'lg';
8
- interface ButtonProps {
7
+ type ButtonHoverEffect = 'none' | 'opacity' | 'scale' | 'shadow';
8
+ type ButtonActiveEffect = 'none' | 'scale';
9
+ type ButtonUnderline = 'none' | 'hover' | 'always';
10
+ interface ButtonProps extends Omit<JSXProps, 'children' | 'color'> {
9
11
  variant?: ButtonVariant;
10
12
  color?: ButtonColor;
11
13
  size?: ButtonSize;
14
+ hover?: ButtonHoverEffect;
15
+ active?: ButtonActiveEffect;
16
+ underline?: ButtonUnderline;
17
+ uppercase?: boolean;
12
18
  fullWidth?: boolean;
13
19
  labelFullWidth?: boolean;
14
20
  disabled?: boolean;
15
21
  loading?: boolean;
16
22
  leftIcon?: IconProps | IconName;
17
23
  rightIcon?: IconProps | IconName;
18
- as?: ContainerAs;
19
24
  text?: string | number;
20
25
  children?: JSXElement | string | number;
21
- className?: string;
22
- id?: string;
23
- type?: 'button' | 'submit' | 'reset';
24
- href?: string;
25
- target?: string;
26
- rel?: string;
27
- 'aria-label'?: string;
28
- role?: string;
29
- onMount?: (e: HTMLElement) => void;
30
- onLoad?: (e: HTMLElement) => void;
31
26
  onClick?: (e: MouseEvent) => void;
32
27
  onMouseEnter?: (e: MouseEvent) => void;
33
28
  onMouseLeave?: (e: MouseEvent) => void;
34
29
  }
35
30
 
36
31
  /**
37
- * A polymorphic button component that supports multiple variants, colors, sizes, and states.
38
- *
39
- * @param props - The properties for the Button component.
40
- * @param props.variant - Visual style variant: `'solid' | 'outline' | 'ghost' | 'link'`.
41
- * @param props.color - Color theme: `'brand' | 'success' | 'warning' | 'error' | 'neutral'`.
42
- * @param props.size - Size scale: `'sm' | 'md' | 'lg'`.
43
- * @param props.fullWidth - Whether the button spans the full width of its container.
44
- * @param props.labelFullWidth - Whether the label spans the full width of the button.
45
- * @param props.disabled - Whether the button is disabled.
46
- * @param props.loading - Whether the button is in a loading state (disables interaction).
47
- * @param props.leftIcon - Optional icon placed to the left of the label (string name or IconProps).
48
- * @param props.rightIcon - Optional icon placed to the right of the label (string name or IconProps).
49
- * @param props.as - Element type to render: `'button' | 'a' | any polymorphic component`.
50
- * @param props.children - Button label content.
51
- * @param props.className - Additional CSS classes appended to the built-in styles.
52
- * @param props.type - HTML button type attribute (only applied when `as="button"`).
53
- * @param props.restProps - Any other props are forwarded to the underlying element.
54
- *
55
- * @returns A JSX element representing the styled button.
56
- *
57
- * @example
58
- * ```tsx
59
- * <Button variant="solid" color="brand" size="md" onClick={handleClick}>
60
- * Save
61
- * </Button>
62
- * ```
63
- */
32
+ * Button Component
33
+ *
34
+ * A versatile button component with support for variants, colors, sizes, and icons.
35
+ * Now features enhanced style controllers for effects and interactions.
36
+ *
37
+ * @param {ButtonProps } props - The properties for the button.
38
+ * @param {ButtonVariant } [props.variant='solid'] - Visual style variant.
39
+ * - `solid`: Filled background (default).
40
+ * - `outline`: Border with transparent background.
41
+ * - `ghost`: Transparent background, hover effect.
42
+ * - `link`: Looks like a text link.
43
+ * - `primary`, `secondary`, `success`, `warning`, `danger`, `info`: Semantic variants.
44
+ * @param {ButtonColor } [props.color='brand'] - Color theme.
45
+ * - `brand`, `success`, `warning`, `error`, `neutral`, `info`.
46
+ * @param {ButtonSize } [props.size='md'] - Button size.
47
+ * - `sm`: Small.
48
+ * - `md`: Medium.
49
+ * - `lg`: Large.
50
+ * @param {ButtonHoverEffect } [props.hover] - Hover effect.
51
+ * - `opacity`: Reduces opacity on hover.
52
+ * - `scale`: Scales up slightly on hover.
53
+ * - `shadow`: Adds shadow on hover.
54
+ * - `none`: No hover effect.
55
+ * - Defaults depend on variant (e.g., semantic variants default to `opacity`).
56
+ * @param {ButtonActiveEffect } [props.active='scale'] - Click/Active effect.
57
+ * - `scale`: Scales down slightly on click.
58
+ * - `none`: No active effect.
59
+ * @param {string } [props.shadow] - Box shadow style (e.g., 'sm', 'md', 'lg', 'none'). Defaults based on variant.
60
+ * @param {string } [props.radius='base'] - Border radius (e.g., 'none', 'sm', 'base', 'md', 'lg', 'full').
61
+ * @param {ButtonUnderline } [props.underline] - Underline style for text.
62
+ * - `hover`: Underline on hover.
63
+ * - `always`: Always underlined.
64
+ * - `none`: No underline.
65
+ * @param {boolean} [props.uppercase=false] - If true, transforms text to uppercase.
66
+ * @param {boolean} [props.fullWidth=false] - If true, the button takes up the full width of its container.
67
+ * @param {boolean} [props.labelFullWidth=false] - If true, the label text takes up the remaining space (useful with icons).
68
+ * @param {boolean} [props.disabled=false] - If true, disables interaction and applies disabled styles.
69
+ * @param {boolean} [props.loading=false] - If true, shows a loading spinner and disables interaction.
70
+ * @param {IconProps | IconName} [props.leftIcon] - Icon to display on the left side.
71
+ * @param {IconProps | IconName} [props.rightIcon] - Icon to display on the right side.
72
+ * @param {string} [props.as='button'] - The HTML element or component to render as.
73
+ * @param {string | number} [props.text] - The text content of the button.
74
+ * @param {JSXElement | string | number} [props.children] - Child elements (overrides text).
75
+ * @param {string} [props.className] - Additional CSS classes.
76
+ * @param {(e: MouseEvent) => void} [props.onClick] - Click handler.
77
+ * @param {(e: MouseEvent) => void} [props.onMouseEnter] - Mouse enter handler.
78
+ * @param {(e: MouseEvent) => void} [props.onMouseLeave] - Mouse leave handler.
79
+ */
64
80
  declare function Button(props: ButtonProps): JSXElement;
65
81
 
66
- export { Button, type ButtonColor, type ButtonProps, type ButtonSize, type ButtonVariant };
82
+ export { Button, type ButtonActiveEffect, type ButtonColor, type ButtonHoverEffect, type ButtonProps, type ButtonSize, type ButtonUnderline, type ButtonVariant };
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 A={sm:{px:3,py:1},md:{px:4,py:2},lg:{px:6,py:3}},V={sm:1,md:2,lg:2},G={sm:"sm",md:"md",lg:"lg"},K={sm:"sm",md:"md",lg:"lg"},$={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"]}},w=new WeakSet,y=new WeakSet;function z(e,i){if(!e)return null;let s=K[i];if(typeof e=="string")return jsx("span",{className:"inline-flex shrink-0",children:jsx(Icon,{name:e,size:s})});let r=e.size??s;return jsx("span",{className:"inline-flex shrink-0",children:jsx(Icon,{...e,size:r})})}function Y(e){let{variant:i="solid",color:s="brand",size:r="md",fullWidth:S=false,labelFullWidth:B=false,disabled:C=false,loading:I=false,leftIcon:P,rightIcon:T,as:u="button",text:c,children:E,className:k,type:M="button",onMount:d,onLoad:l,...N}=e,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"],b=[];(I||C)&&b.push("opacity-50","cursor-not-allowed","pointer-events-none"),S&&b.push("w-full");let L=$[i][s],j=[...R,...b,...L,k].filter(Boolean).join(" "),p=A[r],F=V[r],H=G[r],a=[],g=z(P,r),v=z(T,r);g&&a.push(g);let J=typeof c=="string"&&c.includes("."),o=E??(J?"--":c);o!=null&&o!==""&&a.push(jsx(Text,{as:"span",size:H,"data-role":"btn-label",className:`flex items-center${B?" w-full justify-center":""}`,children:o})),v&&a.push(v);let W=u==="button"?{type:M}:{},m=d||l?t=>{if(t&&(d&&!w.has(t)&&(w.add(t),d(t)),l&&!y.has(t))){y.add(t);let h=()=>{l(t);};typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>{requestAnimationFrame(h);}):setTimeout(h,0);}}:void 0,f={as:u,display:"inline-flex",align:"center",justify:"center",gap:F,px:p.px,py:p.py,radius:"md",className:j,...W,...N};return m&&(f.ref=m),jsx(Container,{...f,children:a})}export{Y as Button};//# sourceMappingURL=index.js.map
1
+ import {Text}from'@cruxkit/text';import {Icon}from'@cruxkit/icon';import {jsxs,jsx,Fragment}from'@minejs/jsx/jsx-runtime';var d={sm:{px:3,py:1},md:{px:4,py:2},lg:{px:6,py:3}},f={sm:1,md:2,lg:2},p={sm:"sm",md:"md",lg:"lg"},c={sm:"sm",md:"md",lg:"lg"},h={solid:{brand:["bg-brand","text-inverse","border","border-transparent","hover:bg-brand-hover","active:bg-brand-active"],success:["bg-success","text-inverse","border","border-transparent","hover:bg-success-hover","active:bg-success-active"],warning:["bg-warning","text-inverse","border","border-transparent","hover:bg-warning-hover","active:bg-warning-active"],error:["bg-error","text-inverse","border","border-transparent","hover:bg-error-hover","active:bg-error-active"],neutral:["bg-surface","text-1","border","border-1","hover:bg-raised","active:bg-tertiary"],info:["bg-info","text-inverse","border","border-transparent","hover:opacity-90"]},outline:{brand:["bg-transparent","text-brand","border","border-brand","hover:bg-brand-subtle","active:bg-brand-subtle"],success:["bg-transparent","text-success","border","border-success","hover:bg-success-subtle","active:bg-success-subtle"],warning:["bg-transparent","text-warning","border","border-warning","hover:bg-warning-subtle","active:bg-warning-subtle"],error:["bg-transparent","text-error","border","border-error","hover:bg-error-subtle","active:bg-error-subtle"],neutral:["bg-transparent","text-1","border","border-1","hover:bg-raised","active:bg-tertiary"],info:["bg-transparent","text-info","border","border-info","hover:opacity-90"]},ghost:{brand:["bg-transparent","text-brand","border","border-transparent","hover:bg-brand-subtle","active:bg-brand-subtle"],success:["bg-transparent","text-success","border","border-transparent","hover:bg-success-subtle","active:bg-success-subtle"],warning:["bg-transparent","text-warning","border","border-transparent","hover:bg-warning-subtle","active:bg-warning-subtle"],error:["bg-transparent","text-error","border","border-transparent","hover:bg-error-subtle","active:bg-error-subtle"],neutral:["bg-transparent","text-1","border","border-transparent","hover:bg-raised","active:bg-tertiary"],info:["bg-transparent","text-info","border","border-transparent","hover:opacity-90"]},link:{brand:["bg-transparent","text-brand","border","border-transparent","px-1"],success:["bg-transparent","text-success","border","border-transparent","px-1"],warning:["bg-transparent","text-warning","border","border-transparent","px-1"],error:["bg-transparent","text-error","border","border-transparent","px-1"],neutral:["bg-transparent","text-1","border","border-transparent","px-1"],info:["bg-transparent","text-info","border","border-transparent","px-1"]},danger:{brand:["bg-error","text-inverse","border","border-transparent"],success:["bg-error","text-inverse","border","border-transparent"],warning:["bg-error","text-inverse","border","border-transparent"],error:["bg-error","text-inverse","border","border-transparent"],neutral:["bg-error","text-inverse","border","border-transparent"],info:["bg-error","text-inverse","border","border-transparent"]},primary:{brand:["bg-brand","text-inverse","border","border-transparent"],success:["bg-brand","text-inverse","border","border-transparent"],warning:["bg-brand","text-inverse","border","border-transparent"],error:["bg-brand","text-inverse","border","border-transparent"],neutral:["bg-brand","text-inverse","border","border-transparent"],info:["bg-brand","text-inverse","border","border-transparent"]},secondary:{brand:["bg-raised","text-1","border","border-transparent"],success:["bg-raised","text-1","border","border-transparent"],warning:["bg-raised","text-1","border","border-transparent"],error:["bg-raised","text-1","border","border-transparent"],neutral:["bg-raised","text-1","border","border-transparent"],info:["bg-raised","text-1","border","border-transparent"]},success:{brand:["bg-success","text-inverse","border","border-transparent"],success:["bg-success","text-inverse","border","border-transparent"],warning:["bg-success","text-inverse","border","border-transparent"],error:["bg-success","text-inverse","border","border-transparent"],neutral:["bg-success","text-inverse","border","border-transparent"],info:["bg-success","text-inverse","border","border-transparent"]},warning:{brand:["bg-warning","text-inverse","border","border-transparent"],success:["bg-warning","text-inverse","border","border-transparent"],warning:["bg-warning","text-inverse","border","border-transparent"],error:["bg-warning","text-inverse","border","border-transparent"],neutral:["bg-warning","text-inverse","border","border-transparent"],info:["bg-warning","text-inverse","border","border-transparent"]},info:{brand:["bg-info","text-inverse","border","border-transparent"],success:["bg-info","text-inverse","border","border-transparent"],warning:["bg-info","text-inverse","border","border-transparent"],error:["bg-info","text-inverse","border","border-transparent"],neutral:["bg-info","text-inverse","border","border-transparent"],info:["bg-info","text-inverse","border","border-transparent"]}};function m(n,s){if(!n)return null;let b=c[s];if(typeof n=="string")return jsx("span",{className:"inline-flex shrink-0",children:jsx(Icon,{name:n,size:b})});let e=n.size??b;return jsx("span",{className:"inline-flex shrink-0",children:jsx(Icon,{...n,size:e})})}function Z(n){let{variant:s="solid",color:b="brand",size:e="md",hover:y,active:z,shadow:S,radius:B,underline:M,uppercase:I,fullWidth:C,labelFullWidth:N,disabled:u,loading:o,leftIcon:k,rightIcon:P,as:R="button",text:E,children:$,className:l,onClick:J,onMouseEnter:L,onMouseLeave:X,...G}=n,v=["primary","secondary","success","warning","danger","info"].includes(s),T=s==="solid",V=s==="link",W=S??(v||T?"sm":"none"),j=z??"scale",i=y??(v?"opacity":"none"),x=M??(V?"hover":"none"),A=B??"base",r=["inline-flex","items-center","justify-center","transition-all","duration-200","focus:outline-none","font-medium"];u||o?r.push("opacity-50","cursor-not-allowed","pointer-events-none"):r.push("cursor-pointer"),C&&r.push("w-full"),r.push(`gap-${f[e]}`),r.push(`px-${d[e].px}`),r.push(`py-${d[e].py}`),r.push(`text-${p[e]}`);let F=h[s]?.[b]||[];r.push(...F),i==="opacity"&&r.push("hover:opacity-90"),i==="scale"&&r.push("hover:scale-105"),i==="shadow"&&r.push("hover:shadow-md"),j==="scale"&&r.push("active:scale-95"),x==="hover"&&r.push("hover:underline","underline-offset-4","decoration-2"),x==="always"&&r.push("underline","underline-offset-4","decoration-2"),I&&r.push("uppercase","tracking-wide"),l&&r.push(l);let a=$||E,H=p[e];return jsxs("div",{as:R,className:r.join(" "),radius:A,shadow:W,onClick:U=>{!u&&!o&&J?.(U);},onMouseEnter:L,onMouseLeave:X,...G,children:[o&&jsx("span",{className:"animate-spin mr-2",children:jsx(Icon,{name:"spinner",size:c[e]})}),o?jsx(Fragment,{}):m(k,e),a&&(typeof a=="string"||typeof a=="number")?jsx(Text,{size:H,className:N?"flex-1 text-center":"",children:a}):a,o?jsx(Fragment,{}):m(P,e)]})}export{Z 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","mountedElements","loadedElements","renderIcon","icon","size","iconSize","jsx","Icon","resolvedSize","Button","props","variant","color","fullWidth","labelFullWidth","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","handleRef","element","runLoad","containerProps","Container"],"mappings":"uJAoBI,IAAMA,EAAuE,CACzE,EAAA,CAAI,CAAE,EAAA,CAAI,EAAG,EAAA,CAAI,CAAE,CAAA,CACnB,EAAA,CAAI,CAAE,EAAA,CAAI,CAAA,CAAG,EAAA,CAAI,CAAE,EACnB,EAAA,CAAI,CAAE,EAAA,CAAI,CAAA,CAAG,GAAI,CAAE,CACvB,CAAA,CAEMC,CAAAA,CAAwC,CAC1C,EAAA,CAAI,CAAA,CACJ,EAAA,CAAI,CAAA,CACJ,GAAI,CACR,CAAA,CAEMC,CAAAA,CAAuD,CACzD,GAAI,IAAA,CACJ,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,IACR,CAAA,CAEMC,CAAAA,CAAsD,CACxD,EAAA,CAAI,KACJ,EAAA,CAAI,IAAA,CACJ,EAAA,CAAI,IACR,EAEMC,CAAAA,CAAuE,CACzE,KAAA,CAAO,CACH,MAAO,CACH,UAAA,CACA,cAAA,CACA,QAAA,CACA,qBACA,sBAAA,CACA,wBAAA,CACA,iBAAA,CACA,WAAA,CACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,YAAA,CACA,eACA,QAAA,CACA,oBAAA,CACA,wBAAA,CACA,0BAAA,CACA,kBACA,WAAA,CACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,YAAA,CACA,cAAA,CACA,QAAA,CACA,oBAAA,CACA,yBACA,0BAAA,CACA,iBAAA,CACA,WAAA,CACA,iBACJ,EACA,KAAA,CAAO,CACH,UAAA,CACA,cAAA,CACA,SACA,oBAAA,CACA,sBAAA,CACA,wBAAA,CACA,iBAAA,CACA,YACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,aACA,QAAA,CACA,QAAA,CACA,UAAA,CACA,iBAAA,CACA,qBACA,iBAAA,CACA,WAAA,CACA,iBACJ,CACJ,EACA,OAAA,CAAS,CACL,KAAA,CAAO,CACH,iBACA,YAAA,CACA,QAAA,CACA,cAAA,CACA,uBAAA,CACA,yBACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,iBACA,cAAA,CACA,QAAA,CACA,gBAAA,CACA,yBAAA,CACA,2BACA,iBACJ,CAAA,CACA,QAAS,CACL,gBAAA,CACA,eACA,QAAA,CACA,gBAAA,CACA,yBAAA,CACA,0BAAA,CACA,iBACJ,CAAA,CACA,KAAA,CAAO,CACH,gBAAA,CACA,aACA,QAAA,CACA,cAAA,CACA,uBAAA,CACA,wBAAA,CACA,iBACJ,CAAA,CACA,OAAA,CAAS,CACL,gBAAA,CACA,SACA,QAAA,CACA,UAAA,CACA,iBAAA,CACA,oBAAA,CACA,iBACJ,CACJ,CAAA,CACA,KAAA,CAAO,CACH,MAAO,CACH,gBAAA,CACA,YAAA,CACA,QAAA,CACA,qBACA,uBAAA,CACA,wBAAA,CACA,iBACJ,CAAA,CACA,QAAS,CACL,gBAAA,CACA,cAAA,CACA,QAAA,CACA,qBACA,yBAAA,CACA,0BAAA,CACA,iBACJ,CAAA,CACA,QAAS,CACL,gBAAA,CACA,cAAA,CACA,QAAA,CACA,qBACA,yBAAA,CACA,0BAAA,CACA,iBACJ,CAAA,CACA,MAAO,CACH,gBAAA,CACA,YAAA,CACA,QAAA,CACA,qBACA,uBAAA,CACA,wBAAA,CACA,iBACJ,CAAA,CACA,QAAS,CACL,gBAAA,CACA,QAAA,CACA,QAAA,CACA,qBACA,iBAAA,CACA,oBAAA,CACA,iBACJ,CACJ,EACA,IAAA,CAAM,CACF,KAAA,CAAO,CACH,iBACA,YAAA,CACA,QAAA,CACA,oBAAA,CACA,iBAAA,CACA,qBACA,cAAA,CACA,MACJ,CAAA,CACA,OAAA,CAAS,CACL,gBAAA,CACA,cAAA,CACA,QAAA,CACA,oBAAA,CACA,kBACA,oBAAA,CACA,cAAA,CACA,MACJ,CAAA,CACA,QAAS,CACL,gBAAA,CACA,cAAA,CACA,QAAA,CACA,qBACA,iBAAA,CACA,oBAAA,CACA,cAAA,CACA,MACJ,EACA,KAAA,CAAO,CACH,gBAAA,CACA,YAAA,CACA,SACA,oBAAA,CACA,iBAAA,CACA,oBAAA,CACA,cAAA,CACA,MACJ,CAAA,CACA,OAAA,CAAS,CACL,gBAAA,CACA,SACA,QAAA,CACA,oBAAA,CACA,iBAAA,CACA,oBAAA,CACA,eACA,MACJ,CACJ,CACJ,CAAA,CAQMC,EAA6B,IAAI,OAAA,CACjCC,CAAAA,CAA6B,IAAI,QAevC,SAASC,CAAAA,CAAWC,CAAAA,CAAwCC,CAAAA,CAAqC,CAC7F,GAAI,CAACD,CAAAA,CAAM,OAAO,KAElB,IAAME,CAAAA,CAAWP,EAAYM,CAAI,CAAA,CAEjC,GAAI,OAAOD,CAAAA,EAAS,QAAA,CAChB,OACIG,IAAC,MAAA,CAAA,CAAK,SAAA,CAAU,sBAAA,CACZ,QAAA,CAAAA,IAACC,IAAAA,CAAA,CAAK,IAAA,CAAMJ,CAAAA,CAAkB,KAAME,CAAAA,CAAU,CAAA,CAClD,CAAA,CAIR,IAAMG,EAAiBL,CAAAA,CAAkC,IAAA,EAAQE,CAAAA,CAEjE,OACIC,IAAC,MAAA,CAAA,CAAK,SAAA,CAAU,sBAAA,CACZ,QAAA,CAAAA,IAACC,IAAAA,CAAA,CAAM,GAAGJ,CAAAA,CAAM,KAAMK,CAAAA,CAAc,CAAA,CACxC,CAER,CA8BO,SAASC,CAAAA,CAAOC,CAAAA,CAAgC,CACnD,GAAM,CACF,OAAA,CAAAC,CAAAA,CAAc,OAAA,CACd,KAAA,CAAAC,EAAc,OAAA,CACd,IAAA,CAAAR,CAAAA,CAAc,IAAA,CACd,UAAAS,CAAAA,CAAc,KAAA,CACd,cAAA,CAAAC,CAAAA,CAAiB,MACjB,QAAA,CAAAC,CAAAA,CAAc,KAAA,CACd,OAAA,CAAAC,EAAc,KAAA,CACd,QAAA,CAAAC,CAAAA,CACA,SAAA,CAAAC,EACA,EAAA,CAAAC,CAAAA,CAAc,QAAA,CACd,IAAA,CAAAC,EACA,QAAA,CAAAC,CAAAA,CACA,SAAA,CAAAC,CAAAA,CACA,KAAAC,CAAAA,CAAc,QAAA,CACd,OAAA,CAAAC,CAAAA,CACA,OAAAC,CAAAA,CACA,GAAGC,CACP,CAAA,CAAIhB,EAEEiB,CAAAA,CAAc,CAChB,aAAA,CACA,cAAA,CACA,iBACA,aAAA,CACA,gBAAA,CACA,cAAA,CACA,aAAA,CACA,qBACA,oBAAA,CACA,6BACJ,CAAA,CAEMC,CAAAA,CAAe,EAAC,CAAA,CAElBZ,CAAAA,EAAWD,CAAAA,GACXa,CAAAA,CAAa,KAAK,YAAA,CAAc,oBAAA,CAAsB,qBAAqB,CAAA,CAG3Ef,GACAe,CAAAA,CAAa,IAAA,CAAK,QAAQ,CAAA,CAG9B,IAAMC,CAAAA,CAAiB9B,CAAAA,CAAeY,CAAO,CAAA,CAAEC,CAAK,CAAA,CAE9CkB,CAAAA,CAAU,CACZ,GAAGH,EACH,GAAGC,CAAAA,CACH,GAAGC,CAAAA,CACHP,CACJ,CAAA,CACK,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA,CAEPS,CAAAA,CAAYpC,CAAAA,CAAeS,CAAI,CAAA,CAC/B4B,CAAAA,CAAYpC,CAAAA,CAAWQ,CAAI,EAC3B6B,CAAAA,CAAYpC,CAAAA,CAAaO,CAAI,CAAA,CAE7B8B,EAAwB,EAAC,CAEzBC,EAAQjC,CAAAA,CAAWe,CAAAA,CAAUb,CAAI,CAAA,CACjCgC,CAAAA,CAAQlC,CAAAA,CAAWgB,CAAAA,CAAWd,CAAI,CAAA,CAEpC+B,CAAAA,EACAD,CAAAA,CAAQ,IAAA,CAAKC,CAAI,CAAA,CAGrB,IAAME,CAAAA,CAAgB,OAAOjB,GAAS,QAAA,EAAYA,CAAAA,CAAK,QAAA,CAAS,GAAG,EAC7DkB,CAAAA,CAAgBjB,CAAAA,GAAagB,CAAAA,CAAgB,IAAA,CAAOjB,GAE/BkB,CAAAA,EAAU,IAAA,EAAQA,CAAAA,GAAU,EAAA,EACnDJ,EAAQ,IAAA,CACJ5B,GAAAA,CAACiC,IAAAA,CAAA,CAAK,GAAG,MAAA,CAAO,IAAA,CAAMN,CAAAA,CAAW,WAAA,CAAU,YAAY,SAAA,CAAW,CAAA,iBAAA,EAAoBnB,CAAAA,CAAiB,wBAAA,CAA2B,EAAE,CAAA,CAAA,CAC/H,QAAA,CAAAwB,CAAAA,CACL,CACJ,EAGAF,CAAAA,EACAF,CAAAA,CAAQ,IAAA,CAAKE,CAAK,EAKtB,IAAMI,CAAAA,CAFcrB,CAAAA,GAGA,QAAA,CACV,CAAE,IAAA,CAAAI,CAAK,CAAA,CACP,GAGJkB,CAAAA,CACDjB,CAAAA,EAAWC,CAAAA,CACLiB,CAAAA,EAAgC,CAC/B,GAAKA,CAAAA,GAEDlB,CAAAA,EAAW,CAACxB,EAAgB,GAAA,CAAI0C,CAAO,CAAA,GACvC1C,CAAAA,CAAgB,IAAI0C,CAAO,CAAA,CAC3BlB,CAAAA,CAAQkB,CAAO,GAGfjB,CAAAA,EAAU,CAACxB,CAAAA,CAAe,GAAA,CAAIyC,CAAO,CAAA,CAAA,CAAG,CACxCzC,CAAAA,CAAe,GAAA,CAAIyC,CAAO,CAAA,CAE1B,IAAMC,CAAAA,CAAU,IAAM,CAClBlB,CAAAA,CAAOiB,CAAO,EAClB,CAAA,CAEI,OAAO,qBAAA,EAA0B,UAAA,CACjC,qBAAA,CAAsB,IAAM,CACxB,qBAAA,CAAsBC,CAAO,EACjC,CAAC,EAED,UAAA,CAAWA,CAAAA,CAAS,CAAC,EAE7B,CACJ,CAAA,CACE,MAAA,CAEJC,CAAAA,CAAuC,CACzC,GAAAzB,CAAAA,CACA,OAAA,CAAY,aAAA,CACZ,KAAA,CAAY,SACZ,OAAA,CAAY,QAAA,CACZ,GAAA,CAAAa,CAAAA,CACA,GAAYD,CAAAA,CAAQ,EAAA,CACpB,EAAA,CAAYA,CAAAA,CAAQ,GACpB,MAAA,CAAY,IAAA,CACZ,SAAA,CAAYD,CAAAA,CACZ,GAAGU,CAAAA,CACH,GAAGd,CACP,CAAA,CAEA,OAAIe,CAAAA,GACAG,CAAAA,CAAe,GAAA,CAAMH,CAAAA,CAAAA,CAIrBnC,IAACuC,SAAAA,CAAA,CAAW,GAAID,CAAAA,CACX,QAAA,CAAAV,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 \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\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.labelFullWidth - Whether the label spans the full width of the button.\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 labelFullWidth = 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${labelFullWidth ? ' w-full justify-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\r\n const handleRef =\r\n (onMount || onLoad)\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 : 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"]}
1
+ {"version":3,"sources":["../src/kit/constants.ts","../src/kit/button.tsx"],"names":["sizePaddingMap","sizeGapMap","labelSizeMap","iconSizeMap","variantClasses","renderIcon","icon","size","iconSize","jsx","Icon","resolvedSize","Button","props","variant","color","hover","active","shadow","radius","underline","uppercase","fullWidth","labelFullWidth","disabled","loading","leftIcon","rightIcon","as","text","children","className","onClick","onMouseEnter","onMouseLeave","rest","isSemantic","isSolid","isLink","resolvedShadow","resolvedActive","resolvedHover","resolvedUnderline","resolvedRadius","baseClasses","variantStyle","content","labelSize","jsxs","e","Fragment","Text"],"mappings":"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","file":"index.js","sourcesContent":["import type { ButtonSize, ButtonVariant, ButtonColor } from '../types';\n\nexport const sizePaddingMap: Record<ButtonSize, { px: 3 | 4 | 6; py: 1 | 2 | 3 }> = {\n sm: { px: 3, py: 1 },\n md: { px: 4, py: 2 },\n lg: { px: 6, py: 3 }\n};\n\nexport const sizeGapMap: Record<ButtonSize, 1 | 2> = {\n sm: 1,\n md: 2,\n lg: 2\n};\n\nexport const labelSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\n sm: 'sm',\n md: 'md',\n lg: 'lg'\n};\n\nexport const iconSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\n sm: 'sm',\n md: 'md',\n lg: 'lg'\n};\n\nexport const variantClasses: Record<ButtonVariant, Record<ButtonColor, string[]>> = {\n solid: {\n brand: ['bg-brand', 'text-inverse', 'border', 'border-transparent', 'hover:bg-brand-hover', 'active:bg-brand-active'],\n success: ['bg-success', 'text-inverse', 'border', 'border-transparent', 'hover:bg-success-hover', 'active:bg-success-active'],\n warning: ['bg-warning', 'text-inverse', 'border', 'border-transparent', 'hover:bg-warning-hover', 'active:bg-warning-active'],\n error: ['bg-error', 'text-inverse', 'border', 'border-transparent', 'hover:bg-error-hover', 'active:bg-error-active'],\n neutral: ['bg-surface', 'text-1', 'border', 'border-1', 'hover:bg-raised', 'active:bg-tertiary'],\n info: ['bg-info', 'text-inverse', 'border', 'border-transparent', 'hover:opacity-90']\n },\n outline: {\n brand: ['bg-transparent', 'text-brand', 'border', 'border-brand', 'hover:bg-brand-subtle', 'active:bg-brand-subtle'],\n success: ['bg-transparent', 'text-success', 'border', 'border-success', 'hover:bg-success-subtle', 'active:bg-success-subtle'],\n warning: ['bg-transparent', 'text-warning', 'border', 'border-warning', 'hover:bg-warning-subtle', 'active:bg-warning-subtle'],\n error: ['bg-transparent', 'text-error', 'border', 'border-error', 'hover:bg-error-subtle', 'active:bg-error-subtle'],\n neutral: ['bg-transparent', 'text-1', 'border', 'border-1', 'hover:bg-raised', 'active:bg-tertiary'],\n info: ['bg-transparent', 'text-info', 'border', 'border-info', 'hover:opacity-90']\n },\n ghost: {\n brand: ['bg-transparent', 'text-brand', 'border', 'border-transparent', 'hover:bg-brand-subtle', 'active:bg-brand-subtle'],\n success: ['bg-transparent', 'text-success', 'border', 'border-transparent', 'hover:bg-success-subtle', 'active:bg-success-subtle'],\n warning: ['bg-transparent', 'text-warning', 'border', 'border-transparent', 'hover:bg-warning-subtle', 'active:bg-warning-subtle'],\n error: ['bg-transparent', 'text-error', 'border', 'border-transparent', 'hover:bg-error-subtle', 'active:bg-error-subtle'],\n neutral: ['bg-transparent', 'text-1', 'border', 'border-transparent', 'hover:bg-raised', 'active:bg-tertiary'],\n info: ['bg-transparent', 'text-info', 'border', 'border-transparent', 'hover:opacity-90']\n },\n link: {\n brand: ['bg-transparent', 'text-brand', 'border', 'border-transparent', 'px-1'],\n success: ['bg-transparent', 'text-success', 'border', 'border-transparent', 'px-1'],\n warning: ['bg-transparent', 'text-warning', 'border', 'border-transparent', 'px-1'],\n error: ['bg-transparent', 'text-error', 'border', 'border-transparent', 'px-1'],\n neutral: ['bg-transparent', 'text-1', 'border', 'border-transparent', 'px-1'],\n info: ['bg-transparent', 'text-info', 'border', 'border-transparent', 'px-1']\n },\n danger: {\n brand: ['bg-error', 'text-inverse', 'border', 'border-transparent'],\n success: ['bg-error', 'text-inverse', 'border', 'border-transparent'],\n warning: ['bg-error', 'text-inverse', 'border', 'border-transparent'],\n error: ['bg-error', 'text-inverse', 'border', 'border-transparent'],\n neutral: ['bg-error', 'text-inverse', 'border', 'border-transparent'],\n info: ['bg-error', 'text-inverse', 'border', 'border-transparent']\n },\n primary: {\n brand: ['bg-brand', 'text-inverse', 'border', 'border-transparent'],\n success: ['bg-brand', 'text-inverse', 'border', 'border-transparent'],\n warning: ['bg-brand', 'text-inverse', 'border', 'border-transparent'],\n error: ['bg-brand', 'text-inverse', 'border', 'border-transparent'],\n neutral: ['bg-brand', 'text-inverse', 'border', 'border-transparent'],\n info: ['bg-brand', 'text-inverse', 'border', 'border-transparent']\n },\n secondary: {\n brand: ['bg-raised', 'text-1', 'border', 'border-transparent'],\n success: ['bg-raised', 'text-1', 'border', 'border-transparent'],\n warning: ['bg-raised', 'text-1', 'border', 'border-transparent'],\n error: ['bg-raised', 'text-1', 'border', 'border-transparent'],\n neutral: ['bg-raised', 'text-1', 'border', 'border-transparent'],\n info: ['bg-raised', 'text-1', 'border', 'border-transparent']\n },\n success: {\n brand: ['bg-success', 'text-inverse', 'border', 'border-transparent'],\n success: ['bg-success', 'text-inverse', 'border', 'border-transparent'],\n warning: ['bg-success', 'text-inverse', 'border', 'border-transparent'],\n error: ['bg-success', 'text-inverse', 'border', 'border-transparent'],\n neutral: ['bg-success', 'text-inverse', 'border', 'border-transparent'],\n info: ['bg-success', 'text-inverse', 'border', 'border-transparent']\n },\n warning: {\n brand: ['bg-warning', 'text-inverse', 'border', 'border-transparent'],\n success: ['bg-warning', 'text-inverse', 'border', 'border-transparent'],\n warning: ['bg-warning', 'text-inverse', 'border', 'border-transparent'],\n error: ['bg-warning', 'text-inverse', 'border', 'border-transparent'],\n neutral: ['bg-warning', 'text-inverse', 'border', 'border-transparent'],\n info: ['bg-warning', 'text-inverse', 'border', 'border-transparent']\n },\n info: {\n brand: ['bg-info', 'text-inverse', 'border', 'border-transparent'],\n success: ['bg-info', 'text-inverse', 'border', 'border-transparent'],\n warning: ['bg-info', 'text-inverse', 'border', 'border-transparent'],\n error: ['bg-info', 'text-inverse', 'border', 'border-transparent'],\n neutral: ['bg-info', 'text-inverse', 'border', 'border-transparent'],\n info: ['bg-info', 'text-inverse', 'border', 'border-transparent']\n }\n};\n","// 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 { Text } from '@cruxkit/text';\r\n import { Icon, type IconProps, type IconName, type IconConfig } from '@cruxkit/icon';\r\n import type { ButtonProps, ButtonSize } from '../types';\r\n import {\r\n sizePaddingMap,\r\n sizeGapMap,\r\n labelSizeMap,\r\n iconSizeMap,\r\n variantClasses\r\n } from './constants';\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 * Button Component\r\n *\r\n * A versatile button component with support for variants, colors, sizes, and icons.\r\n * Now features enhanced style controllers for effects and interactions.\r\n *\r\n * @param {ButtonProps } props - The properties for the button.\r\n * @param {ButtonVariant } [props.variant='solid'] - Visual style variant.\r\n * - `solid`: Filled background (default).\r\n * - `outline`: Border with transparent background.\r\n * - `ghost`: Transparent background, hover effect.\r\n * - `link`: Looks like a text link.\r\n * - `primary`, `secondary`, `success`, `warning`, `danger`, `info`: Semantic variants.\r\n * @param {ButtonColor } [props.color='brand'] - Color theme.\r\n * - `brand`, `success`, `warning`, `error`, `neutral`, `info`.\r\n * @param {ButtonSize } [props.size='md'] - Button size.\r\n * - `sm`: Small.\r\n * - `md`: Medium.\r\n * - `lg`: Large.\r\n * @param {ButtonHoverEffect } [props.hover] - Hover effect.\r\n * - `opacity`: Reduces opacity on hover.\r\n * - `scale`: Scales up slightly on hover.\r\n * - `shadow`: Adds shadow on hover.\r\n * - `none`: No hover effect.\r\n * - Defaults depend on variant (e.g., semantic variants default to `opacity`).\r\n * @param {ButtonActiveEffect } [props.active='scale'] - Click/Active effect.\r\n * - `scale`: Scales down slightly on click.\r\n * - `none`: No active effect.\r\n * @param {string } [props.shadow] - Box shadow style (e.g., 'sm', 'md', 'lg', 'none'). Defaults based on variant.\r\n * @param {string } [props.radius='base'] - Border radius (e.g., 'none', 'sm', 'base', 'md', 'lg', 'full').\r\n * @param {ButtonUnderline } [props.underline] - Underline style for text.\r\n * - `hover`: Underline on hover.\r\n * - `always`: Always underlined.\r\n * - `none`: No underline.\r\n * @param {boolean} [props.uppercase=false] - If true, transforms text to uppercase.\r\n * @param {boolean} [props.fullWidth=false] - If true, the button takes up the full width of its container.\r\n * @param {boolean} [props.labelFullWidth=false] - If true, the label text takes up the remaining space (useful with icons).\r\n * @param {boolean} [props.disabled=false] - If true, disables interaction and applies disabled styles.\r\n * @param {boolean} [props.loading=false] - If true, shows a loading spinner and disables interaction.\r\n * @param {IconProps | IconName} [props.leftIcon] - Icon to display on the left side.\r\n * @param {IconProps | IconName} [props.rightIcon] - Icon to display on the right side.\r\n * @param {string} [props.as='button'] - The HTML element or component to render as.\r\n * @param {string | number} [props.text] - The text content of the button.\r\n * @param {JSXElement | string | number} [props.children] - Child elements (overrides text).\r\n * @param {string} [props.className] - Additional CSS classes.\r\n * @param {(e: MouseEvent) => void} [props.onClick] - Click handler.\r\n * @param {(e: MouseEvent) => void} [props.onMouseEnter] - Mouse enter handler.\r\n * @param {(e: MouseEvent) => void} [props.onMouseLeave] - Mouse leave handler.\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\r\n // Style Controllers\r\n hover,\r\n active,\r\n shadow,\r\n radius,\r\n underline,\r\n uppercase,\r\n\r\n fullWidth,\r\n labelFullWidth,\r\n disabled,\r\n loading,\r\n\r\n leftIcon,\r\n rightIcon,\r\n\r\n as = 'button',\r\n text,\r\n children,\r\n\r\n className,\r\n onClick,\r\n onMouseEnter,\r\n onMouseLeave,\r\n\r\n ...rest\r\n } = props;\r\n\r\n // 1. Resolve Defaults based on Variant\r\n const isSemantic = ['primary', 'secondary', 'success', 'warning', 'danger', 'info'].includes(variant);\r\n const isSolid = variant === 'solid';\r\n const isLink = variant === 'link';\r\n\r\n const resolvedShadow = shadow ?? ((isSemantic || isSolid) ? 'sm' : 'none');\r\n const resolvedActive = active ?? 'scale';\r\n // Legacy variants (solid/outline/ghost) have built-in color hovers, so we default to 'none' to avoid double effects\r\n // Semantic variants use opacity hover by default\r\n const resolvedHover = hover ?? (isSemantic ? 'opacity' : 'none');\r\n const resolvedUnderline = underline ?? (isLink ? 'hover' : 'none');\r\n const resolvedRadius = radius ?? 'base'; // Default to base rounded\r\n\r\n // 2. Compose Classes\r\n const baseClasses = [\r\n 'inline-flex', 'items-center', 'justify-center',\r\n 'transition-all', 'duration-200',\r\n 'focus:outline-none',\r\n 'font-medium'\r\n ];\r\n\r\n // State Classes\r\n if (disabled || loading) {\r\n baseClasses.push('opacity-50', 'cursor-not-allowed', 'pointer-events-none');\r\n } else {\r\n baseClasses.push('cursor-pointer');\r\n }\r\n\r\n // Size Classes\r\n if (fullWidth) baseClasses.push('w-full');\r\n baseClasses.push(`gap-${sizeGapMap[size]}`);\r\n baseClasses.push(`px-${sizePaddingMap[size].px}`);\r\n baseClasses.push(`py-${sizePaddingMap[size].py}`);\r\n baseClasses.push(`text-${labelSizeMap[size]}`); // Ensure text size matches button size\r\n\r\n // Variant & Color Classes (from Constants)\r\n const variantStyle = variantClasses[variant]?.[color] || [];\r\n baseClasses.push(...variantStyle);\r\n\r\n // Hover Effects\r\n if (resolvedHover === 'opacity') baseClasses.push('hover:opacity-90');\r\n if (resolvedHover === 'scale') baseClasses.push('hover:scale-105');\r\n if (resolvedHover === 'shadow') baseClasses.push('hover:shadow-md');\r\n\r\n // Active Effects\r\n if (resolvedActive === 'scale') baseClasses.push('active:scale-95');\r\n\r\n // Underline\r\n if (resolvedUnderline === 'hover') baseClasses.push('hover:underline', 'underline-offset-4', 'decoration-2');\r\n if (resolvedUnderline === 'always') baseClasses.push('underline', 'underline-offset-4', 'decoration-2');\r\n\r\n // Uppercase\r\n if (uppercase) baseClasses.push('uppercase', 'tracking-wide');\r\n\r\n // Custom ClassName\r\n if (className) baseClasses.push(className);\r\n\r\n\r\n // 3. Render\r\n const content = children || text;\r\n const labelSize = labelSizeMap[size];\r\n\r\n return (\r\n <div\r\n as={as}\r\n className={baseClasses.join(' ')}\r\n radius={resolvedRadius}\r\n shadow={resolvedShadow}\r\n onClick={(e: MouseEvent) => {\r\n if (!disabled && !loading) {\r\n onClick?.(e);\r\n }\r\n }}\r\n onMouseEnter={onMouseEnter}\r\n onMouseLeave={onMouseLeave}\r\n {...rest}\r\n >\r\n {loading && (\r\n <span className=\"animate-spin mr-2\">\r\n <Icon name='spinner' size={iconSizeMap[size]} />\r\n </span>\r\n )}\r\n\r\n {!loading ? renderIcon(leftIcon, size) : <></>}\r\n\r\n {content && (typeof content === 'string' || typeof content === 'number') ? (\r\n <Text\r\n size={labelSize}\r\n className={labelFullWidth ? 'flex-1 text-center' : ''}\r\n >\r\n {content}\r\n </Text>\r\n ) : content}\r\n\r\n {!loading ? renderIcon(rightIcon, size) : <></>}\r\n </div>\r\n );\r\n }\r\n\r\n// β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•\r\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cruxkit/button",
3
- "version": "0.2.4",
4
- "description": "Polymorphic, theme-aware button component for the Cruxkit ecosystem, built on @minejs/jsx.",
3
+ "version": "0.2.6",
4
+ "description": "A lightweight, reactive button kit, built for @cruxjs ecosystem.",
5
5
  "keywords": ["crux", "kit", "button"],
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/cruxkit-org/button#readme",
@@ -40,10 +40,9 @@
40
40
  "bun": "^1.3.3"
41
41
  },
42
42
  "dependencies": {
43
- "@cruxkit/container": "^0.1.0",
44
43
  "@cruxkit/icon": "^0.1.1",
45
44
  "@cruxkit/text": "^0.0.2",
46
- "@minejs/jsx": "^0.1.8"
45
+ "@minejs/jsx": "^0.2.5"
47
46
  },
48
47
  "devDependencies": {
49
48
  "@eslint/js": "^9.39.2",