@cruxkit/button 0.0.6 → 0.0.8

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.0.6-black"/>
11
+ <img src="https://img.shields.io/badge/v-0.0.8-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-100%25-brightgreen" alt="Test Coverage" />
14
+ <img src="https://img.shields.io/badge/coverage-98.12%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>
@@ -70,15 +70,13 @@
70
70
  Save
71
71
  </Button>
72
72
 
73
- <Button icon={Icon('plus')} variant="ghost" />
74
-
75
73
  <Button
76
74
  variant="outline"
77
75
  color="success"
78
76
  size="sm"
79
77
  fullWidth
80
- leftIcon={Icon('check')}
81
- rightIcon={Icon('arrow-right')}
78
+ leftIcon="check"
79
+ rightIcon={{ name: 'arrow-right' }}
82
80
  >
83
81
  Continue
84
82
  </Button>
@@ -126,9 +124,8 @@
126
124
  disabled? : boolean;
127
125
  loading? : boolean;
128
126
 
129
- leftIcon? : JSXElement;
130
- rightIcon? : JSXElement;
131
- icon? : JSXElement;
127
+ leftIcon? : IconProps | IconName;
128
+ rightIcon? : IconProps | IconName;
132
129
 
133
130
  as? : ContainerAs;
134
131
 
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var container=require('@cruxkit/container'),text=require('@cruxkit/text'),client=require('@cruxjs/client'),jsxRuntime=require('@minejs/jsx/jsx-runtime');var K={sm:{px:3,py:1},md:{px:4,py:2},lg:{px:6,py:3}},Q={sm:1,md:2,lg:2},U={sm:"sm",md:"md",lg:"lg"};var Z={solid:{brand:["bg-brand","text-inverse","border","border-transparent","hover:bg-brand-hover","active:bg-brand-active","active:scale-95","shadow-sm","hover:shadow-md"],success:["bg-success","text-inverse","border","border-transparent","hover:bg-success-hover","active:bg-success-active","active:scale-95","shadow-sm","hover:shadow-md"],warning:["bg-warning","text-inverse","border","border-transparent","hover:bg-warning-hover","active:bg-warning-active","active:scale-95","shadow-sm","hover:shadow-md"],error:["bg-error","text-inverse","border","border-transparent","hover:bg-error-hover","active:bg-error-active","active:scale-95","shadow-sm","hover:shadow-md"],neutral:["bg-surface","text-1","border","border-1","hover:bg-raised","active:bg-tertiary","active:scale-95","shadow-sm","hover:shadow-md"]},outline:{brand:["bg-transparent","text-brand","border","border-brand","hover:bg-brand-subtle","active:bg-brand-subtle","active:scale-95"],success:["bg-transparent","text-success","border","border-success","hover:bg-success-subtle","active:bg-success-subtle","active:scale-95"],warning:["bg-transparent","text-warning","border","border-warning","hover:bg-warning-subtle","active:bg-warning-subtle","active:scale-95"],error:["bg-transparent","text-error","border","border-error","hover:bg-error-subtle","active:bg-error-subtle","active:scale-95"],neutral:["bg-transparent","text-1","border","border-1","hover:bg-raised","active:bg-tertiary","active:scale-95"]},ghost:{brand:["bg-transparent","text-brand","border","border-transparent","hover:bg-brand-subtle","active:bg-brand-subtle","active:scale-95"],success:["bg-transparent","text-success","border","border-transparent","hover:bg-success-subtle","active:bg-success-subtle","active:scale-95"],warning:["bg-transparent","text-warning","border","border-transparent","hover:bg-warning-subtle","active:bg-warning-subtle","active:scale-95"],error:["bg-transparent","text-error","border","border-transparent","hover:bg-error-subtle","active:bg-error-subtle","active:scale-95"],neutral:["bg-transparent","text-1","border","border-transparent","hover:bg-raised","active:bg-tertiary","active:scale-95"]},link:{brand:["bg-transparent","text-brand","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],success:["bg-transparent","text-success","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],warning:["bg-transparent","text-warning","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],error:["bg-transparent","text-error","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],neutral:["bg-transparent","text-1","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"]}},z=new WeakSet,R=new WeakSet,L=new WeakSet,$=5,ee=100;function p(a,v){return a?jsxRuntime.jsx("span",{className:"inline-flex shrink-0",children:a}):null}function ae(a){let{variant:v="solid",color:k="brand",size:r="md",fullWidth:C=false,disabled:A=false,loading:N=false,leftIcon:P,rightIcon:q,icon:m,as:f="button",text:t,children:H,className:I,type:X="button",onMount:c,onLoad:d,...J}=a,_=["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"],l=[];(N||A)&&l.push("opacity-50","cursor-not-allowed","pointer-events-none"),C&&l.push("w-full");let W=Z[v][k],j=[..._,...l,...W,I].filter(Boolean).join(" "),b=K[r],F=Q[r],O=U[r],n=[],h=p(P),x=p(q),w=p(m);h&&n.push(h),w&&n.push(w);let y=typeof t=="string"&&t.includes("."),o=H??(y?"--":t);o!=null&&o!==""&&n.push(jsxRuntime.jsx(text.Text,{as:"span",size:O,"data-role":"btn-label",className:"flex items-center",children:o})),x&&n.push(x);let V=f==="button"?{type:X}:{},T=y,S=c||d||T?e=>{if(e){if(c&&!z.has(e)&&(z.add(e),c(e)),d&&!R.has(e)){R.add(e);let i=()=>{d(e);};typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>{requestAnimationFrame(i);}):setTimeout(i,0);}if(T&&!L.has(e)){let i=s=>{typeof queueMicrotask=="function"?queueMicrotask(s):setTimeout(s,0);},B=s=>{let M=e.querySelector('[data-role="btn-label"]');if(!M||typeof t!="string")return;let u=client.t(t,void 0,"--");if(u!==t&&u!=="--"||s>=$){M.textContent=String(u),L.add(e);return}setTimeout(()=>{B(s+1);},ee);};i(()=>{B(0);});}}}:void 0,E={as:f,display:"inline-flex",align:"center",justify:"center",gap:F,px:m?b.py:b.px,py:b.py,radius:"md",className:j,...V,...J};return S&&(E.ref=S),jsxRuntime.jsx(container.Container,{...E,children:n})}exports.Button=ae;//# sourceMappingURL=index.cjs.map
1
+ 'use strict';var container=require('@cruxkit/container'),text=require('@cruxkit/text'),icon=require('@cruxkit/icon'),client=require('@cruxjs/client'),jsxRuntime=require('@minejs/jsx/jsx-runtime');var G={sm:{px:3,py:1},md:{px:4,py:2},lg:{px:6,py:3}},K={sm:1,md:2,lg:2},Q={sm:"sm",md:"md",lg:"lg"},U={sm:"sm",md:"md",lg:"lg"},Z={solid:{brand:["bg-brand","text-inverse","border","border-transparent","hover:bg-brand-hover","active:bg-brand-active","active:scale-95","shadow-sm","hover:shadow-md"],success:["bg-success","text-inverse","border","border-transparent","hover:bg-success-hover","active:bg-success-active","active:scale-95","shadow-sm","hover:shadow-md"],warning:["bg-warning","text-inverse","border","border-transparent","hover:bg-warning-hover","active:bg-warning-active","active:scale-95","shadow-sm","hover:shadow-md"],error:["bg-error","text-inverse","border","border-transparent","hover:bg-error-hover","active:bg-error-active","active:scale-95","shadow-sm","hover:shadow-md"],neutral:["bg-surface","text-1","border","border-1","hover:bg-raised","active:bg-tertiary","active:scale-95","shadow-sm","hover:shadow-md"]},outline:{brand:["bg-transparent","text-brand","border","border-brand","hover:bg-brand-subtle","active:bg-brand-subtle","active:scale-95"],success:["bg-transparent","text-success","border","border-success","hover:bg-success-subtle","active:bg-success-subtle","active:scale-95"],warning:["bg-transparent","text-warning","border","border-warning","hover:bg-warning-subtle","active:bg-warning-subtle","active:scale-95"],error:["bg-transparent","text-error","border","border-error","hover:bg-error-subtle","active:bg-error-subtle","active:scale-95"],neutral:["bg-transparent","text-1","border","border-1","hover:bg-raised","active:bg-tertiary","active:scale-95"]},ghost:{brand:["bg-transparent","text-brand","border","border-transparent","hover:bg-brand-subtle","active:bg-brand-subtle","active:scale-95"],success:["bg-transparent","text-success","border","border-transparent","hover:bg-success-subtle","active:bg-success-subtle","active:scale-95"],warning:["bg-transparent","text-warning","border","border-transparent","hover:bg-warning-subtle","active:bg-warning-subtle","active:scale-95"],error:["bg-transparent","text-error","border","border-transparent","hover:bg-error-subtle","active:bg-error-subtle","active:scale-95"],neutral:["bg-transparent","text-1","border","border-transparent","hover:bg-raised","active:bg-tertiary","active:scale-95"]},link:{brand:["bg-transparent","text-brand","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],success:["bg-transparent","text-success","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],warning:["bg-transparent","text-warning","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],error:["bg-transparent","text-error","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],neutral:["bg-transparent","text-1","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"]}},E=new WeakSet,M=new WeakSet,I=new WeakSet,$=5,ee=100;function N(r,l){if(!r)return null;let o=U[l];if(typeof r=="string")return jsxRuntime.jsx("span",{className:"inline-flex shrink-0",children:jsxRuntime.jsx(icon.Icon,{name:r,size:o})});let t=r.size??o;return jsxRuntime.jsx("span",{className:"inline-flex shrink-0",children:jsxRuntime.jsx(icon.Icon,{...r,size:t})})}function oe(r){let{variant:l="solid",color:o="brand",size:t="md",fullWidth:C=false,disabled:R=false,loading:k=false,leftIcon:L,rightIcon:P,as:m="button",text:n,children:A,className:q,type:H="button",onMount:b,onLoad:u,...X}=r,_=["inline-flex","items-center","justify-center","font-medium","transition-all","duration-150","select-none","focus:outline-none","focus-visible:ring","focus-visible:ring-offset-2"],p=[];(k||R)&&p.push("opacity-50","cursor-not-allowed","pointer-events-none"),C&&p.push("w-full");let J=Z[l][o],W=[..._,...p,...J,q].filter(Boolean).join(" "),v=G[t],j=K[t],F=Q[t],i=[],f=N(L,t),h=N(P,t);f&&i.push(f);let x=typeof n=="string"&&n.includes("."),c=A??(x?"--":n);c!=null&&c!==""&&i.push(jsxRuntime.jsx(text.Text,{as:"span",size:F,"data-role":"btn-label",className:"flex items-center",children:c})),h&&i.push(h);let O=m==="button"?{type:H}:{},y=x,w=b||u||y?e=>{if(e){if(b&&!E.has(e)&&(E.add(e),b(e)),u&&!M.has(e)){M.add(e);let d=()=>{u(e);};typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>{requestAnimationFrame(d);}):setTimeout(d,0);}if(y&&!I.has(e)){let d=a=>{typeof queueMicrotask=="function"?queueMicrotask(a):setTimeout(a,0);},S=a=>{let z=e.querySelector('[data-role="btn-label"]');if(!z||typeof n!="string")return;let g=client.t(n,void 0,"--");if(g!==n&&g!=="--"||a>=$){z.textContent=String(g),I.add(e);return}setTimeout(()=>{S(a+1);},ee);};d(()=>{S(0);});}}}:void 0,T={as:m,display:"inline-flex",align:"center",justify:"center",gap:j,px:v.px,py:v.py,radius:"md",className:W,...O,...X};return w&&(T.ref=w),jsxRuntime.jsx(container.Container,{...T,children:i})}exports.Button=oe;//# sourceMappingURL=index.cjs.map
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/kit/button.tsx"],"names":["sizePaddingMap","sizeGapMap","labelSizeMap","variantClasses","mountedElements","loadedElements","translatedElements","MAX_TRANSLATION_ATTEMPTS","TRANSLATION_RETRY_DELAY_MS","renderIcon","icon","size","jsx","Button","props","variant","color","fullWidth","disabled","loading","leftIcon","rightIcon","as","text","children","className","type","onMount","onLoad","restProps","baseClasses","stateClasses","paletteClasses","classes","padding","gap","labelSize","content","left","right","centerIcon","isKeyLikeText","label","Text","elementTypeProps","shouldTranslate","handleRef","element","runLoad","schedule","fn","attemptTranslate","attempt","labelNode","translated","t","containerProps","Container"],"mappings":"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","file":"index.cjs","sourcesContent":["// src/kit/button.tsx\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import type { JSXElement } from '@minejs/jsx';\r\n import { Container } from '@cruxkit/container';\r\n import { Text } from '@cruxkit/text';\r\n import type { ButtonProps, ButtonSize, ButtonColor, ButtonVariant } from '../types';\r\n import { t } from '@cruxjs/client';\r\n \r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ INIT ════════════════════════════════════════╗\r\n\r\n const sizePaddingMap: Record<ButtonSize, { px: 3 | 4 | 6; py: 1 | 2 | 3 }> = {\r\n sm: { px: 3, py: 1 },\r\n md: { px: 4, py: 2 },\r\n lg: { px: 6, py: 3 }\r\n };\r\n\r\n const sizeGapMap: Record<ButtonSize, 1 | 2> = {\r\n sm: 1,\r\n md: 2,\r\n lg: 2\r\n };\r\n\r\n const labelSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const iconSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const variantClasses: Record<ButtonVariant, Record<ButtonColor, string[]>> = {\r\n solid: {\r\n brand: [\r\n 'bg-brand',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-hover',\r\n 'active:bg-brand-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n success: [\r\n 'bg-success',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-hover',\r\n 'active:bg-success-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n warning: [\r\n 'bg-warning',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-hover',\r\n 'active:bg-warning-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n error: [\r\n 'bg-error',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-hover',\r\n 'active:bg-error-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n neutral: [\r\n 'bg-surface',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ]\r\n },\r\n outline: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-brand',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-success',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-warning',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-error',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n ghost: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n link: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ]\r\n }\r\n };\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n const mountedElements = new WeakSet<HTMLElement>();\r\n const loadedElements = new WeakSet<HTMLElement>();\r\n const translatedElements = new WeakSet<HTMLElement>();\r\n const MAX_TRANSLATION_ATTEMPTS = 5;\r\n const TRANSLATION_RETRY_DELAY_MS = 100;\r\n\r\n type ButtonContainerProps = {\r\n as?: unknown;\r\n display?: string;\r\n align?: string;\r\n justify?: string;\r\n gap?: number;\r\n px?: number;\r\n py?: number;\r\n radius?: string;\r\n className?: string;\r\n ref?: (element: HTMLElement | null) => void;\r\n } & Record<string, unknown>;\r\n\r\n function renderIcon(icon: JSXElement | undefined, size: ButtonSize): JSXElement | null {\r\n if (!icon) return null;\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n {icon}\r\n </span>\r\n );\r\n }\r\n\r\n /**\r\n * A polymorphic button component that supports multiple variants, colors, sizes, and states.\r\n *\r\n * @param props - The properties for the Button component.\r\n * @param props.variant - Visual style variant: `'solid' | 'outline' | 'ghost' | 'link'`.\r\n * @param props.color - Color theme: `'brand' | 'success' | 'warning' | 'error' | 'neutral'`.\r\n * @param props.size - Size scale: `'sm' | 'md' | 'lg'`.\r\n * @param props.fullWidth - Whether the button spans the full width of its container.\r\n * @param props.disabled - Whether the button is disabled.\r\n * @param props.loading - Whether the button is in a loading state (disables interaction).\r\n * @param props.leftIcon - Optional icon placed to the left of the label (string name or IconProps).\r\n * @param props.rightIcon - Optional icon placed to the right of the label (string name or IconProps).\r\n * @param props.as - Element type to render: `'button' | 'a' | any polymorphic component`.\r\n * @param props.children - Button label content.\r\n * @param props.className - Additional CSS classes appended to the built-in styles.\r\n * @param props.type - HTML button type attribute (only applied when `as=\"button\"`).\r\n * @param props.restProps - Any other props are forwarded to the underlying element.\r\n *\r\n * @returns A JSX element representing the styled button.\r\n *\r\n * @example\r\n * ```tsx\r\n * <Button variant=\"solid\" color=\"brand\" size=\"md\" onClick={handleClick}>\r\n * Save\r\n * </Button>\r\n * ```\r\n */\r\n export function Button(props: ButtonProps): JSXElement {\r\n const {\r\n variant = 'solid',\r\n color = 'brand',\r\n size = 'md',\r\n fullWidth = false,\r\n disabled = false,\r\n loading = false,\r\n leftIcon,\r\n rightIcon,\r\n icon,\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 const centerIcon = renderIcon(icon, size);\r\n\r\n if (left) {\r\n content.push(left);\r\n }\r\n\r\n if (centerIcon) {\r\n content.push(centerIcon);\r\n }\r\n\r\n const isKeyLikeText = typeof text === 'string' && text.includes('.');\r\n const label = children ?? (isKeyLikeText ? '--' : text);\r\n\r\n if (label !== undefined && label !== null && label !== '') {\r\n content.push(\r\n <Text as=\"span\" size={labelSize} data-role=\"btn-label\" className='flex items-center'>\r\n {label}\r\n </Text>\r\n );\r\n }\r\n\r\n if (right) {\r\n content.push(right);\r\n }\r\n\r\n const elementType = as;\r\n\r\n const elementTypeProps =\r\n elementType === 'button'\r\n ? { type }\r\n : {};\r\n\r\n const shouldTranslate = isKeyLikeText;\r\n\r\n const handleRef =\r\n (onMount || onLoad || shouldTranslate)\r\n ? (element: HTMLElement | null) => {\r\n if (!element) return;\r\n\r\n if (onMount && !mountedElements.has(element)) {\r\n mountedElements.add(element);\r\n onMount(element);\r\n }\r\n\r\n if (onLoad && !loadedElements.has(element)) {\r\n loadedElements.add(element);\r\n\r\n const runLoad = () => {\r\n onLoad(element);\r\n };\r\n\r\n if (typeof requestAnimationFrame === 'function') {\r\n requestAnimationFrame(() => {\r\n requestAnimationFrame(runLoad);\r\n });\r\n } else {\r\n setTimeout(runLoad, 0);\r\n }\r\n }\r\n\r\n if (shouldTranslate && !translatedElements.has(element)) {\r\n const schedule = (fn: () => void) => {\r\n if (typeof queueMicrotask === 'function') {\r\n queueMicrotask(fn);\r\n } else {\r\n setTimeout(fn, 0);\r\n }\r\n };\r\n\r\n const attemptTranslate = (attempt: number) => {\r\n const labelNode = element.querySelector('[data-role=\\\"btn-label\\\"]');\r\n\r\n if (!labelNode || typeof text !== 'string') return;\r\n\r\n let translated = t(text as string, undefined, '--');\r\n\r\n if (translated !== text && translated !== '--' || attempt >= MAX_TRANSLATION_ATTEMPTS) {\r\n (labelNode as HTMLElement).textContent = String(translated);\r\n translatedElements.add(element);\r\n return;\r\n }\r\n\r\n setTimeout(\r\n () => {\r\n attemptTranslate(attempt + 1);\r\n },\r\n TRANSLATION_RETRY_DELAY_MS\r\n );\r\n };\r\n\r\n schedule(() => {\r\n attemptTranslate(0);\r\n });\r\n }\r\n }\r\n : undefined;\r\n\r\n const containerProps: ButtonContainerProps = {\r\n as,\r\n display : 'inline-flex',\r\n align : 'center',\r\n justify : 'center',\r\n gap,\r\n px : icon ? padding.py : 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/button.tsx"],"names":["sizePaddingMap","sizeGapMap","labelSizeMap","iconSizeMap","variantClasses","mountedElements","loadedElements","translatedElements","MAX_TRANSLATION_ATTEMPTS","TRANSLATION_RETRY_DELAY_MS","renderIcon","icon","size","iconSize","jsx","Icon","resolvedSize","Button","props","variant","color","fullWidth","disabled","loading","leftIcon","rightIcon","as","text","children","className","type","onMount","onLoad","restProps","baseClasses","stateClasses","paletteClasses","classes","padding","gap","labelSize","content","left","right","isKeyLikeText","label","Text","elementTypeProps","shouldTranslate","handleRef","element","runLoad","schedule","fn","attemptTranslate","attempt","labelNode","translated","t","containerProps","Container"],"mappings":"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","file":"index.cjs","sourcesContent":["// src/kit/button.tsx\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import type { JSXElement } from '@minejs/jsx';\r\n import { Container } from '@cruxkit/container';\r\n import { Text } from '@cruxkit/text';\r\n import { Icon, type IconProps, type IconName, type IconConfig } from '@cruxkit/icon';\r\n import type { ButtonProps, ButtonSize, ButtonColor, ButtonVariant } from '../types';\r\n import { t } from '@cruxjs/client';\r\n \r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ INIT ════════════════════════════════════════╗\r\n\r\n const sizePaddingMap: Record<ButtonSize, { px: 3 | 4 | 6; py: 1 | 2 | 3 }> = {\r\n sm: { px: 3, py: 1 },\r\n md: { px: 4, py: 2 },\r\n lg: { px: 6, py: 3 }\r\n };\r\n\r\n const sizeGapMap: Record<ButtonSize, 1 | 2> = {\r\n sm: 1,\r\n md: 2,\r\n lg: 2\r\n };\r\n\r\n const labelSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const iconSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const variantClasses: Record<ButtonVariant, Record<ButtonColor, string[]>> = {\r\n solid: {\r\n brand: [\r\n 'bg-brand',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-hover',\r\n 'active:bg-brand-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n success: [\r\n 'bg-success',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-hover',\r\n 'active:bg-success-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n warning: [\r\n 'bg-warning',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-hover',\r\n 'active:bg-warning-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n error: [\r\n 'bg-error',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-hover',\r\n 'active:bg-error-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n neutral: [\r\n 'bg-surface',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ]\r\n },\r\n outline: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-brand',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-success',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-warning',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-error',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n ghost: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n link: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ]\r\n }\r\n };\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n const mountedElements = new WeakSet<HTMLElement>();\r\n const loadedElements = new WeakSet<HTMLElement>();\r\n const translatedElements = new WeakSet<HTMLElement>();\r\n const MAX_TRANSLATION_ATTEMPTS = 5;\r\n const TRANSLATION_RETRY_DELAY_MS = 100;\r\n\r\n type ButtonContainerProps = {\r\n as?: unknown;\r\n display?: string;\r\n align?: string;\r\n justify?: string;\r\n gap?: number;\r\n px?: number;\r\n py?: number;\r\n radius?: string;\r\n className?: string;\r\n ref?: (element: HTMLElement | null) => void;\r\n } & Record<string, unknown>;\r\n\r\n function renderIcon(icon: IconProps | IconName | undefined, size: ButtonSize): JSXElement | null {\r\n if (!icon) return null;\r\n\r\n const iconSize = iconSizeMap[size];\r\n\r\n if (typeof icon === 'string') {\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n <Icon name={icon as IconName} size={iconSize} />\r\n </span>\r\n );\r\n }\r\n\r\n const resolvedSize = ((icon as IconProps) as IconConfig).size ?? iconSize;\r\n\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n <Icon {...icon} size={resolvedSize} />\r\n </span>\r\n );\r\n }\r\n\r\n /**\r\n * A polymorphic button component that supports multiple variants, colors, sizes, and states.\r\n *\r\n * @param props - The properties for the Button component.\r\n * @param props.variant - Visual style variant: `'solid' | 'outline' | 'ghost' | 'link'`.\r\n * @param props.color - Color theme: `'brand' | 'success' | 'warning' | 'error' | 'neutral'`.\r\n * @param props.size - Size scale: `'sm' | 'md' | 'lg'`.\r\n * @param props.fullWidth - Whether the button spans the full width of its container.\r\n * @param props.disabled - Whether the button is disabled.\r\n * @param props.loading - Whether the button is in a loading state (disables interaction).\r\n * @param props.leftIcon - Optional icon placed to the left of the label (string name or IconProps).\r\n * @param props.rightIcon - Optional icon placed to the right of the label (string name or IconProps).\r\n * @param props.as - Element type to render: `'button' | 'a' | any polymorphic component`.\r\n * @param props.children - Button label content.\r\n * @param props.className - Additional CSS classes appended to the built-in styles.\r\n * @param props.type - HTML button type attribute (only applied when `as=\"button\"`).\r\n * @param props.restProps - Any other props are forwarded to the underlying element.\r\n *\r\n * @returns A JSX element representing the styled button.\r\n *\r\n * @example\r\n * ```tsx\r\n * <Button variant=\"solid\" color=\"brand\" size=\"md\" onClick={handleClick}>\r\n * Save\r\n * </Button>\r\n * ```\r\n */\r\n export function Button(props: ButtonProps): JSXElement {\r\n const {\r\n variant = 'solid',\r\n color = 'brand',\r\n size = 'md',\r\n fullWidth = false,\r\n disabled = false,\r\n loading = false,\r\n leftIcon,\r\n rightIcon,\r\n as = 'button',\r\n text,\r\n children,\r\n className,\r\n type = 'button',\r\n onMount,\r\n onLoad,\r\n ...restProps\r\n } = props;\r\n\r\n const baseClasses = [\r\n 'inline-flex',\r\n 'items-center',\r\n 'justify-center',\r\n 'font-medium',\r\n 'transition-all',\r\n 'duration-150',\r\n 'select-none',\r\n 'focus:outline-none',\r\n 'focus-visible:ring',\r\n 'focus-visible:ring-offset-2'\r\n ];\r\n\r\n const stateClasses = [];\r\n\r\n if (loading || disabled) {\r\n stateClasses.push('opacity-50', 'cursor-not-allowed', 'pointer-events-none');\r\n }\r\n\r\n if (fullWidth) {\r\n stateClasses.push('w-full');\r\n }\r\n\r\n const paletteClasses = variantClasses[variant][color];\r\n\r\n const classes = [\r\n ...baseClasses,\r\n ...stateClasses,\r\n ...paletteClasses,\r\n className\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n const padding = sizePaddingMap[size];\r\n const gap = sizeGapMap[size];\r\n const labelSize = labelSizeMap[size];\r\n\r\n const content: JSXElement[] = [];\r\n\r\n const left = renderIcon(leftIcon, size);\r\n const right = renderIcon(rightIcon, size);\r\n\r\n if (left) {\r\n content.push(left);\r\n }\r\n\r\n const isKeyLikeText = typeof text === 'string' && text.includes('.');\r\n const label = children ?? (isKeyLikeText ? '--' : text);\r\n\r\n if (label !== undefined && label !== null && label !== '') {\r\n content.push(\r\n <Text as=\"span\" size={labelSize} data-role=\"btn-label\" className='flex items-center'>\r\n {label}\r\n </Text>\r\n );\r\n }\r\n\r\n if (right) {\r\n content.push(right);\r\n }\r\n\r\n const elementType = as;\r\n\r\n const elementTypeProps =\r\n elementType === 'button'\r\n ? { type }\r\n : {};\r\n\r\n const shouldTranslate = isKeyLikeText;\r\n\r\n const handleRef =\r\n (onMount || onLoad || shouldTranslate)\r\n ? (element: HTMLElement | null) => {\r\n if (!element) return;\r\n\r\n if (onMount && !mountedElements.has(element)) {\r\n mountedElements.add(element);\r\n onMount(element);\r\n }\r\n\r\n if (onLoad && !loadedElements.has(element)) {\r\n loadedElements.add(element);\r\n\r\n const runLoad = () => {\r\n onLoad(element);\r\n };\r\n\r\n if (typeof requestAnimationFrame === 'function') {\r\n requestAnimationFrame(() => {\r\n requestAnimationFrame(runLoad);\r\n });\r\n } else {\r\n setTimeout(runLoad, 0);\r\n }\r\n }\r\n\r\n if (shouldTranslate && !translatedElements.has(element)) {\r\n const schedule = (fn: () => void) => {\r\n if (typeof queueMicrotask === 'function') {\r\n queueMicrotask(fn);\r\n } else {\r\n setTimeout(fn, 0);\r\n }\r\n };\r\n\r\n const attemptTranslate = (attempt: number) => {\r\n const labelNode = element.querySelector('[data-role=\\\"btn-label\\\"]');\r\n\r\n if (!labelNode || typeof text !== 'string') return;\r\n\r\n let translated = t(text as string, undefined, '--');\r\n\r\n if (translated !== text && translated !== '--' || attempt >= MAX_TRANSLATION_ATTEMPTS) {\r\n (labelNode as HTMLElement).textContent = String(translated);\r\n translatedElements.add(element);\r\n return;\r\n }\r\n\r\n setTimeout(\r\n () => {\r\n attemptTranslate(attempt + 1);\r\n },\r\n TRANSLATION_RETRY_DELAY_MS\r\n );\r\n };\r\n\r\n schedule(() => {\r\n attemptTranslate(0);\r\n });\r\n }\r\n }\r\n : undefined;\r\n\r\n const containerProps: ButtonContainerProps = {\r\n as,\r\n display : 'inline-flex',\r\n align : 'center',\r\n justify : 'center',\r\n gap,\r\n px : padding.px,\r\n py : padding.py,\r\n radius : 'md',\r\n className : classes,\r\n ...elementTypeProps,\r\n ...restProps\r\n };\r\n\r\n if (handleRef) {\r\n containerProps.ref = handleRef;\r\n }\r\n\r\n return (\r\n <Container {...(containerProps as Record<string, unknown>)}>\r\n {content}\r\n </Container>\r\n );\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { JSXElement } from '@minejs/jsx';
2
2
  import { ContainerAs } from '@cruxkit/container';
3
+ import { IconProps, IconName } from '@cruxkit/icon';
3
4
 
4
5
  type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'link';
5
6
  type ButtonColor = 'brand' | 'success' | 'warning' | 'error' | 'neutral';
@@ -11,9 +12,8 @@ interface ButtonProps {
11
12
  fullWidth?: boolean;
12
13
  disabled?: boolean;
13
14
  loading?: boolean;
14
- leftIcon?: JSXElement;
15
- rightIcon?: JSXElement;
16
- icon?: JSXElement;
15
+ leftIcon?: IconProps | IconName;
16
+ rightIcon?: IconProps | IconName;
17
17
  as?: ContainerAs;
18
18
  text?: string | number;
19
19
  children?: JSXElement | string | number;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { JSXElement } from '@minejs/jsx';
2
2
  import { ContainerAs } from '@cruxkit/container';
3
+ import { IconProps, IconName } from '@cruxkit/icon';
3
4
 
4
5
  type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'link';
5
6
  type ButtonColor = 'brand' | 'success' | 'warning' | 'error' | 'neutral';
@@ -11,9 +12,8 @@ interface ButtonProps {
11
12
  fullWidth?: boolean;
12
13
  disabled?: boolean;
13
14
  loading?: boolean;
14
- leftIcon?: JSXElement;
15
- rightIcon?: JSXElement;
16
- icon?: JSXElement;
15
+ leftIcon?: IconProps | IconName;
16
+ rightIcon?: IconProps | IconName;
17
17
  as?: ContainerAs;
18
18
  text?: string | number;
19
19
  children?: JSXElement | string | number;
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import {Container}from'@cruxkit/container';import {Text}from'@cruxkit/text';import {t}from'@cruxjs/client';import {jsx}from'@minejs/jsx/jsx-runtime';var K={sm:{px:3,py:1},md:{px:4,py:2},lg:{px:6,py:3}},Q={sm:1,md:2,lg:2},U={sm:"sm",md:"md",lg:"lg"};var Z={solid:{brand:["bg-brand","text-inverse","border","border-transparent","hover:bg-brand-hover","active:bg-brand-active","active:scale-95","shadow-sm","hover:shadow-md"],success:["bg-success","text-inverse","border","border-transparent","hover:bg-success-hover","active:bg-success-active","active:scale-95","shadow-sm","hover:shadow-md"],warning:["bg-warning","text-inverse","border","border-transparent","hover:bg-warning-hover","active:bg-warning-active","active:scale-95","shadow-sm","hover:shadow-md"],error:["bg-error","text-inverse","border","border-transparent","hover:bg-error-hover","active:bg-error-active","active:scale-95","shadow-sm","hover:shadow-md"],neutral:["bg-surface","text-1","border","border-1","hover:bg-raised","active:bg-tertiary","active:scale-95","shadow-sm","hover:shadow-md"]},outline:{brand:["bg-transparent","text-brand","border","border-brand","hover:bg-brand-subtle","active:bg-brand-subtle","active:scale-95"],success:["bg-transparent","text-success","border","border-success","hover:bg-success-subtle","active:bg-success-subtle","active:scale-95"],warning:["bg-transparent","text-warning","border","border-warning","hover:bg-warning-subtle","active:bg-warning-subtle","active:scale-95"],error:["bg-transparent","text-error","border","border-error","hover:bg-error-subtle","active:bg-error-subtle","active:scale-95"],neutral:["bg-transparent","text-1","border","border-1","hover:bg-raised","active:bg-tertiary","active:scale-95"]},ghost:{brand:["bg-transparent","text-brand","border","border-transparent","hover:bg-brand-subtle","active:bg-brand-subtle","active:scale-95"],success:["bg-transparent","text-success","border","border-transparent","hover:bg-success-subtle","active:bg-success-subtle","active:scale-95"],warning:["bg-transparent","text-warning","border","border-transparent","hover:bg-warning-subtle","active:bg-warning-subtle","active:scale-95"],error:["bg-transparent","text-error","border","border-transparent","hover:bg-error-subtle","active:bg-error-subtle","active:scale-95"],neutral:["bg-transparent","text-1","border","border-transparent","hover:bg-raised","active:bg-tertiary","active:scale-95"]},link:{brand:["bg-transparent","text-brand","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],success:["bg-transparent","text-success","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],warning:["bg-transparent","text-warning","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],error:["bg-transparent","text-error","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],neutral:["bg-transparent","text-1","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"]}},z=new WeakSet,R=new WeakSet,L=new WeakSet,$=5,ee=100;function p(a,v){return a?jsx("span",{className:"inline-flex shrink-0",children:a}):null}function ae(a){let{variant:v="solid",color:k="brand",size:r="md",fullWidth:C=false,disabled:A=false,loading:N=false,leftIcon:P,rightIcon:q,icon:m,as:f="button",text:t$1,children:H,className:I,type:X="button",onMount:c,onLoad:d,...J}=a,_=["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"],l=[];(N||A)&&l.push("opacity-50","cursor-not-allowed","pointer-events-none"),C&&l.push("w-full");let W=Z[v][k],j=[..._,...l,...W,I].filter(Boolean).join(" "),b=K[r],F=Q[r],O=U[r],n=[],h=p(P),x=p(q),w=p(m);h&&n.push(h),w&&n.push(w);let y=typeof t$1=="string"&&t$1.includes("."),o=H??(y?"--":t$1);o!=null&&o!==""&&n.push(jsx(Text,{as:"span",size:O,"data-role":"btn-label",className:"flex items-center",children:o})),x&&n.push(x);let V=f==="button"?{type:X}:{},T=y,S=c||d||T?e=>{if(e){if(c&&!z.has(e)&&(z.add(e),c(e)),d&&!R.has(e)){R.add(e);let i=()=>{d(e);};typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>{requestAnimationFrame(i);}):setTimeout(i,0);}if(T&&!L.has(e)){let i=s=>{typeof queueMicrotask=="function"?queueMicrotask(s):setTimeout(s,0);},B=s=>{let M=e.querySelector('[data-role="btn-label"]');if(!M||typeof t$1!="string")return;let u=t(t$1,void 0,"--");if(u!==t$1&&u!=="--"||s>=$){M.textContent=String(u),L.add(e);return}setTimeout(()=>{B(s+1);},ee);};i(()=>{B(0);});}}}:void 0,E={as:f,display:"inline-flex",align:"center",justify:"center",gap:F,px:m?b.py:b.px,py:b.py,radius:"md",className:j,...V,...J};return S&&(E.ref=S),jsx(Container,{...E,children:n})}export{ae as Button};//# sourceMappingURL=index.js.map
1
+ import {Container}from'@cruxkit/container';import {Text}from'@cruxkit/text';import {Icon}from'@cruxkit/icon';import {t}from'@cruxjs/client';import {jsx}from'@minejs/jsx/jsx-runtime';var G={sm:{px:3,py:1},md:{px:4,py:2},lg:{px:6,py:3}},K={sm:1,md:2,lg:2},Q={sm:"sm",md:"md",lg:"lg"},U={sm:"sm",md:"md",lg:"lg"},Z={solid:{brand:["bg-brand","text-inverse","border","border-transparent","hover:bg-brand-hover","active:bg-brand-active","active:scale-95","shadow-sm","hover:shadow-md"],success:["bg-success","text-inverse","border","border-transparent","hover:bg-success-hover","active:bg-success-active","active:scale-95","shadow-sm","hover:shadow-md"],warning:["bg-warning","text-inverse","border","border-transparent","hover:bg-warning-hover","active:bg-warning-active","active:scale-95","shadow-sm","hover:shadow-md"],error:["bg-error","text-inverse","border","border-transparent","hover:bg-error-hover","active:bg-error-active","active:scale-95","shadow-sm","hover:shadow-md"],neutral:["bg-surface","text-1","border","border-1","hover:bg-raised","active:bg-tertiary","active:scale-95","shadow-sm","hover:shadow-md"]},outline:{brand:["bg-transparent","text-brand","border","border-brand","hover:bg-brand-subtle","active:bg-brand-subtle","active:scale-95"],success:["bg-transparent","text-success","border","border-success","hover:bg-success-subtle","active:bg-success-subtle","active:scale-95"],warning:["bg-transparent","text-warning","border","border-warning","hover:bg-warning-subtle","active:bg-warning-subtle","active:scale-95"],error:["bg-transparent","text-error","border","border-error","hover:bg-error-subtle","active:bg-error-subtle","active:scale-95"],neutral:["bg-transparent","text-1","border","border-1","hover:bg-raised","active:bg-tertiary","active:scale-95"]},ghost:{brand:["bg-transparent","text-brand","border","border-transparent","hover:bg-brand-subtle","active:bg-brand-subtle","active:scale-95"],success:["bg-transparent","text-success","border","border-transparent","hover:bg-success-subtle","active:bg-success-subtle","active:scale-95"],warning:["bg-transparent","text-warning","border","border-transparent","hover:bg-warning-subtle","active:bg-warning-subtle","active:scale-95"],error:["bg-transparent","text-error","border","border-transparent","hover:bg-error-subtle","active:bg-error-subtle","active:scale-95"],neutral:["bg-transparent","text-1","border","border-transparent","hover:bg-raised","active:bg-tertiary","active:scale-95"]},link:{brand:["bg-transparent","text-brand","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],success:["bg-transparent","text-success","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],warning:["bg-transparent","text-warning","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],error:["bg-transparent","text-error","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"],neutral:["bg-transparent","text-1","border","border-transparent","hover:underline","underline-offset-4","decoration-2","px-1"]}},E=new WeakSet,M=new WeakSet,I=new WeakSet,$=5,ee=100;function N(r,l){if(!r)return null;let o=U[l];if(typeof r=="string")return jsx("span",{className:"inline-flex shrink-0",children:jsx(Icon,{name:r,size:o})});let t=r.size??o;return jsx("span",{className:"inline-flex shrink-0",children:jsx(Icon,{...r,size:t})})}function oe(r){let{variant:l="solid",color:o="brand",size:t$1="md",fullWidth:C=false,disabled:R=false,loading:k=false,leftIcon:L,rightIcon:P,as:m="button",text:n,children:A,className:q,type:H="button",onMount:b,onLoad:u,...X}=r,_=["inline-flex","items-center","justify-center","font-medium","transition-all","duration-150","select-none","focus:outline-none","focus-visible:ring","focus-visible:ring-offset-2"],p=[];(k||R)&&p.push("opacity-50","cursor-not-allowed","pointer-events-none"),C&&p.push("w-full");let J=Z[l][o],W=[..._,...p,...J,q].filter(Boolean).join(" "),v=G[t$1],j=K[t$1],F=Q[t$1],i=[],f=N(L,t$1),h=N(P,t$1);f&&i.push(f);let x=typeof n=="string"&&n.includes("."),c=A??(x?"--":n);c!=null&&c!==""&&i.push(jsx(Text,{as:"span",size:F,"data-role":"btn-label",className:"flex items-center",children:c})),h&&i.push(h);let O=m==="button"?{type:H}:{},y=x,w=b||u||y?e=>{if(e){if(b&&!E.has(e)&&(E.add(e),b(e)),u&&!M.has(e)){M.add(e);let d=()=>{u(e);};typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>{requestAnimationFrame(d);}):setTimeout(d,0);}if(y&&!I.has(e)){let d=a=>{typeof queueMicrotask=="function"?queueMicrotask(a):setTimeout(a,0);},S=a=>{let z=e.querySelector('[data-role="btn-label"]');if(!z||typeof n!="string")return;let g=t(n,void 0,"--");if(g!==n&&g!=="--"||a>=$){z.textContent=String(g),I.add(e);return}setTimeout(()=>{S(a+1);},ee);};d(()=>{S(0);});}}}:void 0,T={as:m,display:"inline-flex",align:"center",justify:"center",gap:j,px:v.px,py:v.py,radius:"md",className:W,...O,...X};return w&&(T.ref=w),jsx(Container,{...T,children:i})}export{oe as Button};//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/kit/button.tsx"],"names":["sizePaddingMap","sizeGapMap","labelSizeMap","variantClasses","mountedElements","loadedElements","translatedElements","MAX_TRANSLATION_ATTEMPTS","TRANSLATION_RETRY_DELAY_MS","renderIcon","icon","size","jsx","Button","props","variant","color","fullWidth","disabled","loading","leftIcon","rightIcon","as","text","children","className","type","onMount","onLoad","restProps","baseClasses","stateClasses","paletteClasses","classes","padding","gap","labelSize","content","left","right","centerIcon","isKeyLikeText","label","Text","elementTypeProps","shouldTranslate","handleRef","element","runLoad","schedule","fn","attemptTranslate","attempt","labelNode","translated","t","containerProps","Container"],"mappings":"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","file":"index.js","sourcesContent":["// src/kit/button.tsx\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import type { JSXElement } from '@minejs/jsx';\r\n import { Container } from '@cruxkit/container';\r\n import { Text } from '@cruxkit/text';\r\n import type { ButtonProps, ButtonSize, ButtonColor, ButtonVariant } from '../types';\r\n import { t } from '@cruxjs/client';\r\n \r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ INIT ════════════════════════════════════════╗\r\n\r\n const sizePaddingMap: Record<ButtonSize, { px: 3 | 4 | 6; py: 1 | 2 | 3 }> = {\r\n sm: { px: 3, py: 1 },\r\n md: { px: 4, py: 2 },\r\n lg: { px: 6, py: 3 }\r\n };\r\n\r\n const sizeGapMap: Record<ButtonSize, 1 | 2> = {\r\n sm: 1,\r\n md: 2,\r\n lg: 2\r\n };\r\n\r\n const labelSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const iconSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const variantClasses: Record<ButtonVariant, Record<ButtonColor, string[]>> = {\r\n solid: {\r\n brand: [\r\n 'bg-brand',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-hover',\r\n 'active:bg-brand-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n success: [\r\n 'bg-success',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-hover',\r\n 'active:bg-success-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n warning: [\r\n 'bg-warning',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-hover',\r\n 'active:bg-warning-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n error: [\r\n 'bg-error',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-hover',\r\n 'active:bg-error-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n neutral: [\r\n 'bg-surface',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ]\r\n },\r\n outline: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-brand',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-success',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-warning',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-error',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n ghost: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n link: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ]\r\n }\r\n };\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n const mountedElements = new WeakSet<HTMLElement>();\r\n const loadedElements = new WeakSet<HTMLElement>();\r\n const translatedElements = new WeakSet<HTMLElement>();\r\n const MAX_TRANSLATION_ATTEMPTS = 5;\r\n const TRANSLATION_RETRY_DELAY_MS = 100;\r\n\r\n type ButtonContainerProps = {\r\n as?: unknown;\r\n display?: string;\r\n align?: string;\r\n justify?: string;\r\n gap?: number;\r\n px?: number;\r\n py?: number;\r\n radius?: string;\r\n className?: string;\r\n ref?: (element: HTMLElement | null) => void;\r\n } & Record<string, unknown>;\r\n\r\n function renderIcon(icon: JSXElement | undefined, size: ButtonSize): JSXElement | null {\r\n if (!icon) return null;\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n {icon}\r\n </span>\r\n );\r\n }\r\n\r\n /**\r\n * A polymorphic button component that supports multiple variants, colors, sizes, and states.\r\n *\r\n * @param props - The properties for the Button component.\r\n * @param props.variant - Visual style variant: `'solid' | 'outline' | 'ghost' | 'link'`.\r\n * @param props.color - Color theme: `'brand' | 'success' | 'warning' | 'error' | 'neutral'`.\r\n * @param props.size - Size scale: `'sm' | 'md' | 'lg'`.\r\n * @param props.fullWidth - Whether the button spans the full width of its container.\r\n * @param props.disabled - Whether the button is disabled.\r\n * @param props.loading - Whether the button is in a loading state (disables interaction).\r\n * @param props.leftIcon - Optional icon placed to the left of the label (string name or IconProps).\r\n * @param props.rightIcon - Optional icon placed to the right of the label (string name or IconProps).\r\n * @param props.as - Element type to render: `'button' | 'a' | any polymorphic component`.\r\n * @param props.children - Button label content.\r\n * @param props.className - Additional CSS classes appended to the built-in styles.\r\n * @param props.type - HTML button type attribute (only applied when `as=\"button\"`).\r\n * @param props.restProps - Any other props are forwarded to the underlying element.\r\n *\r\n * @returns A JSX element representing the styled button.\r\n *\r\n * @example\r\n * ```tsx\r\n * <Button variant=\"solid\" color=\"brand\" size=\"md\" onClick={handleClick}>\r\n * Save\r\n * </Button>\r\n * ```\r\n */\r\n export function Button(props: ButtonProps): JSXElement {\r\n const {\r\n variant = 'solid',\r\n color = 'brand',\r\n size = 'md',\r\n fullWidth = false,\r\n disabled = false,\r\n loading = false,\r\n leftIcon,\r\n rightIcon,\r\n icon,\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 const centerIcon = renderIcon(icon, size);\r\n\r\n if (left) {\r\n content.push(left);\r\n }\r\n\r\n if (centerIcon) {\r\n content.push(centerIcon);\r\n }\r\n\r\n const isKeyLikeText = typeof text === 'string' && text.includes('.');\r\n const label = children ?? (isKeyLikeText ? '--' : text);\r\n\r\n if (label !== undefined && label !== null && label !== '') {\r\n content.push(\r\n <Text as=\"span\" size={labelSize} data-role=\"btn-label\" className='flex items-center'>\r\n {label}\r\n </Text>\r\n );\r\n }\r\n\r\n if (right) {\r\n content.push(right);\r\n }\r\n\r\n const elementType = as;\r\n\r\n const elementTypeProps =\r\n elementType === 'button'\r\n ? { type }\r\n : {};\r\n\r\n const shouldTranslate = isKeyLikeText;\r\n\r\n const handleRef =\r\n (onMount || onLoad || shouldTranslate)\r\n ? (element: HTMLElement | null) => {\r\n if (!element) return;\r\n\r\n if (onMount && !mountedElements.has(element)) {\r\n mountedElements.add(element);\r\n onMount(element);\r\n }\r\n\r\n if (onLoad && !loadedElements.has(element)) {\r\n loadedElements.add(element);\r\n\r\n const runLoad = () => {\r\n onLoad(element);\r\n };\r\n\r\n if (typeof requestAnimationFrame === 'function') {\r\n requestAnimationFrame(() => {\r\n requestAnimationFrame(runLoad);\r\n });\r\n } else {\r\n setTimeout(runLoad, 0);\r\n }\r\n }\r\n\r\n if (shouldTranslate && !translatedElements.has(element)) {\r\n const schedule = (fn: () => void) => {\r\n if (typeof queueMicrotask === 'function') {\r\n queueMicrotask(fn);\r\n } else {\r\n setTimeout(fn, 0);\r\n }\r\n };\r\n\r\n const attemptTranslate = (attempt: number) => {\r\n const labelNode = element.querySelector('[data-role=\\\"btn-label\\\"]');\r\n\r\n if (!labelNode || typeof text !== 'string') return;\r\n\r\n let translated = t(text as string, undefined, '--');\r\n\r\n if (translated !== text && translated !== '--' || attempt >= MAX_TRANSLATION_ATTEMPTS) {\r\n (labelNode as HTMLElement).textContent = String(translated);\r\n translatedElements.add(element);\r\n return;\r\n }\r\n\r\n setTimeout(\r\n () => {\r\n attemptTranslate(attempt + 1);\r\n },\r\n TRANSLATION_RETRY_DELAY_MS\r\n );\r\n };\r\n\r\n schedule(() => {\r\n attemptTranslate(0);\r\n });\r\n }\r\n }\r\n : undefined;\r\n\r\n const containerProps: ButtonContainerProps = {\r\n as,\r\n display : 'inline-flex',\r\n align : 'center',\r\n justify : 'center',\r\n gap,\r\n px : icon ? padding.py : 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/button.tsx"],"names":["sizePaddingMap","sizeGapMap","labelSizeMap","iconSizeMap","variantClasses","mountedElements","loadedElements","translatedElements","MAX_TRANSLATION_ATTEMPTS","TRANSLATION_RETRY_DELAY_MS","renderIcon","icon","size","iconSize","jsx","Icon","resolvedSize","Button","props","variant","color","fullWidth","disabled","loading","leftIcon","rightIcon","as","text","children","className","type","onMount","onLoad","restProps","baseClasses","stateClasses","paletteClasses","classes","padding","gap","labelSize","content","left","right","isKeyLikeText","label","Text","elementTypeProps","shouldTranslate","handleRef","element","runLoad","schedule","fn","attemptTranslate","attempt","labelNode","translated","t","containerProps","Container"],"mappings":"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","file":"index.js","sourcesContent":["// src/kit/button.tsx\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import type { JSXElement } from '@minejs/jsx';\r\n import { Container } from '@cruxkit/container';\r\n import { Text } from '@cruxkit/text';\r\n import { Icon, type IconProps, type IconName, type IconConfig } from '@cruxkit/icon';\r\n import type { ButtonProps, ButtonSize, ButtonColor, ButtonVariant } from '../types';\r\n import { t } from '@cruxjs/client';\r\n \r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ INIT ════════════════════════════════════════╗\r\n\r\n const sizePaddingMap: Record<ButtonSize, { px: 3 | 4 | 6; py: 1 | 2 | 3 }> = {\r\n sm: { px: 3, py: 1 },\r\n md: { px: 4, py: 2 },\r\n lg: { px: 6, py: 3 }\r\n };\r\n\r\n const sizeGapMap: Record<ButtonSize, 1 | 2> = {\r\n sm: 1,\r\n md: 2,\r\n lg: 2\r\n };\r\n\r\n const labelSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const iconSizeMap: Record<ButtonSize, 'sm' | 'md' | 'lg'> = {\r\n sm: 'sm',\r\n md: 'md',\r\n lg: 'lg'\r\n };\r\n\r\n const variantClasses: Record<ButtonVariant, Record<ButtonColor, string[]>> = {\r\n solid: {\r\n brand: [\r\n 'bg-brand',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-hover',\r\n 'active:bg-brand-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n success: [\r\n 'bg-success',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-hover',\r\n 'active:bg-success-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n warning: [\r\n 'bg-warning',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-hover',\r\n 'active:bg-warning-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n error: [\r\n 'bg-error',\r\n 'text-inverse',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-hover',\r\n 'active:bg-error-active',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ],\r\n neutral: [\r\n 'bg-surface',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95',\r\n 'shadow-sm',\r\n 'hover:shadow-md'\r\n ]\r\n },\r\n outline: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-brand',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-success',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-warning',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-error',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-1',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n ghost: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-brand-subtle',\r\n 'active:bg-brand-subtle',\r\n 'active:scale-95'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-success-subtle',\r\n 'active:bg-success-subtle',\r\n 'active:scale-95'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-warning-subtle',\r\n 'active:bg-warning-subtle',\r\n 'active:scale-95'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-error-subtle',\r\n 'active:bg-error-subtle',\r\n 'active:scale-95'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:bg-raised',\r\n 'active:bg-tertiary',\r\n 'active:scale-95'\r\n ]\r\n },\r\n link: {\r\n brand: [\r\n 'bg-transparent',\r\n 'text-brand',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n success: [\r\n 'bg-transparent',\r\n 'text-success',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n warning: [\r\n 'bg-transparent',\r\n 'text-warning',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n error: [\r\n 'bg-transparent',\r\n 'text-error',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ],\r\n neutral: [\r\n 'bg-transparent',\r\n 'text-1',\r\n 'border',\r\n 'border-transparent',\r\n 'hover:underline',\r\n 'underline-offset-4',\r\n 'decoration-2',\r\n 'px-1'\r\n ]\r\n }\r\n };\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n const mountedElements = new WeakSet<HTMLElement>();\r\n const loadedElements = new WeakSet<HTMLElement>();\r\n const translatedElements = new WeakSet<HTMLElement>();\r\n const MAX_TRANSLATION_ATTEMPTS = 5;\r\n const TRANSLATION_RETRY_DELAY_MS = 100;\r\n\r\n type ButtonContainerProps = {\r\n as?: unknown;\r\n display?: string;\r\n align?: string;\r\n justify?: string;\r\n gap?: number;\r\n px?: number;\r\n py?: number;\r\n radius?: string;\r\n className?: string;\r\n ref?: (element: HTMLElement | null) => void;\r\n } & Record<string, unknown>;\r\n\r\n function renderIcon(icon: IconProps | IconName | undefined, size: ButtonSize): JSXElement | null {\r\n if (!icon) return null;\r\n\r\n const iconSize = iconSizeMap[size];\r\n\r\n if (typeof icon === 'string') {\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n <Icon name={icon as IconName} size={iconSize} />\r\n </span>\r\n );\r\n }\r\n\r\n const resolvedSize = ((icon as IconProps) as IconConfig).size ?? iconSize;\r\n\r\n return (\r\n <span className=\"inline-flex shrink-0\">\r\n <Icon {...icon} size={resolvedSize} />\r\n </span>\r\n );\r\n }\r\n\r\n /**\r\n * A polymorphic button component that supports multiple variants, colors, sizes, and states.\r\n *\r\n * @param props - The properties for the Button component.\r\n * @param props.variant - Visual style variant: `'solid' | 'outline' | 'ghost' | 'link'`.\r\n * @param props.color - Color theme: `'brand' | 'success' | 'warning' | 'error' | 'neutral'`.\r\n * @param props.size - Size scale: `'sm' | 'md' | 'lg'`.\r\n * @param props.fullWidth - Whether the button spans the full width of its container.\r\n * @param props.disabled - Whether the button is disabled.\r\n * @param props.loading - Whether the button is in a loading state (disables interaction).\r\n * @param props.leftIcon - Optional icon placed to the left of the label (string name or IconProps).\r\n * @param props.rightIcon - Optional icon placed to the right of the label (string name or IconProps).\r\n * @param props.as - Element type to render: `'button' | 'a' | any polymorphic component`.\r\n * @param props.children - Button label content.\r\n * @param props.className - Additional CSS classes appended to the built-in styles.\r\n * @param props.type - HTML button type attribute (only applied when `as=\"button\"`).\r\n * @param props.restProps - Any other props are forwarded to the underlying element.\r\n *\r\n * @returns A JSX element representing the styled button.\r\n *\r\n * @example\r\n * ```tsx\r\n * <Button variant=\"solid\" color=\"brand\" size=\"md\" onClick={handleClick}>\r\n * Save\r\n * </Button>\r\n * ```\r\n */\r\n export function Button(props: ButtonProps): JSXElement {\r\n const {\r\n variant = 'solid',\r\n color = 'brand',\r\n size = 'md',\r\n fullWidth = false,\r\n disabled = false,\r\n loading = false,\r\n leftIcon,\r\n rightIcon,\r\n as = 'button',\r\n text,\r\n children,\r\n className,\r\n type = 'button',\r\n onMount,\r\n onLoad,\r\n ...restProps\r\n } = props;\r\n\r\n const baseClasses = [\r\n 'inline-flex',\r\n 'items-center',\r\n 'justify-center',\r\n 'font-medium',\r\n 'transition-all',\r\n 'duration-150',\r\n 'select-none',\r\n 'focus:outline-none',\r\n 'focus-visible:ring',\r\n 'focus-visible:ring-offset-2'\r\n ];\r\n\r\n const stateClasses = [];\r\n\r\n if (loading || disabled) {\r\n stateClasses.push('opacity-50', 'cursor-not-allowed', 'pointer-events-none');\r\n }\r\n\r\n if (fullWidth) {\r\n stateClasses.push('w-full');\r\n }\r\n\r\n const paletteClasses = variantClasses[variant][color];\r\n\r\n const classes = [\r\n ...baseClasses,\r\n ...stateClasses,\r\n ...paletteClasses,\r\n className\r\n ]\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n const padding = sizePaddingMap[size];\r\n const gap = sizeGapMap[size];\r\n const labelSize = labelSizeMap[size];\r\n\r\n const content: JSXElement[] = [];\r\n\r\n const left = renderIcon(leftIcon, size);\r\n const right = renderIcon(rightIcon, size);\r\n\r\n if (left) {\r\n content.push(left);\r\n }\r\n\r\n const isKeyLikeText = typeof text === 'string' && text.includes('.');\r\n const label = children ?? (isKeyLikeText ? '--' : text);\r\n\r\n if (label !== undefined && label !== null && label !== '') {\r\n content.push(\r\n <Text as=\"span\" size={labelSize} data-role=\"btn-label\" className='flex items-center'>\r\n {label}\r\n </Text>\r\n );\r\n }\r\n\r\n if (right) {\r\n content.push(right);\r\n }\r\n\r\n const elementType = as;\r\n\r\n const elementTypeProps =\r\n elementType === 'button'\r\n ? { type }\r\n : {};\r\n\r\n const shouldTranslate = isKeyLikeText;\r\n\r\n const handleRef =\r\n (onMount || onLoad || shouldTranslate)\r\n ? (element: HTMLElement | null) => {\r\n if (!element) return;\r\n\r\n if (onMount && !mountedElements.has(element)) {\r\n mountedElements.add(element);\r\n onMount(element);\r\n }\r\n\r\n if (onLoad && !loadedElements.has(element)) {\r\n loadedElements.add(element);\r\n\r\n const runLoad = () => {\r\n onLoad(element);\r\n };\r\n\r\n if (typeof requestAnimationFrame === 'function') {\r\n requestAnimationFrame(() => {\r\n requestAnimationFrame(runLoad);\r\n });\r\n } else {\r\n setTimeout(runLoad, 0);\r\n }\r\n }\r\n\r\n if (shouldTranslate && !translatedElements.has(element)) {\r\n const schedule = (fn: () => void) => {\r\n if (typeof queueMicrotask === 'function') {\r\n queueMicrotask(fn);\r\n } else {\r\n setTimeout(fn, 0);\r\n }\r\n };\r\n\r\n const attemptTranslate = (attempt: number) => {\r\n const labelNode = element.querySelector('[data-role=\\\"btn-label\\\"]');\r\n\r\n if (!labelNode || typeof text !== 'string') return;\r\n\r\n let translated = t(text as string, undefined, '--');\r\n\r\n if (translated !== text && translated !== '--' || attempt >= MAX_TRANSLATION_ATTEMPTS) {\r\n (labelNode as HTMLElement).textContent = String(translated);\r\n translatedElements.add(element);\r\n return;\r\n }\r\n\r\n setTimeout(\r\n () => {\r\n attemptTranslate(attempt + 1);\r\n },\r\n TRANSLATION_RETRY_DELAY_MS\r\n );\r\n };\r\n\r\n schedule(() => {\r\n attemptTranslate(0);\r\n });\r\n }\r\n }\r\n : undefined;\r\n\r\n const containerProps: ButtonContainerProps = {\r\n as,\r\n display : 'inline-flex',\r\n align : 'center',\r\n justify : 'center',\r\n gap,\r\n px : padding.px,\r\n py : padding.py,\r\n radius : 'md',\r\n className : classes,\r\n ...elementTypeProps,\r\n ...restProps\r\n };\r\n\r\n if (handleRef) {\r\n containerProps.ref = handleRef;\r\n }\r\n\r\n return (\r\n <Container {...(containerProps as Record<string, unknown>)}>\r\n {content}\r\n </Container>\r\n );\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cruxkit/button",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Polymorphic, theme-aware button component for the Cruxkit ecosystem, built on @minejs/jsx.",
5
5
  "keywords": ["crux", "kit", "button"],
6
6
  "license": "MIT",
@@ -43,10 +43,10 @@
43
43
  "@cruxjs/client": "^0.2.2",
44
44
  "@cruxkit/container": "^0.0.2",
45
45
  "@cruxkit/text": "^0.0.2",
46
- "@minejs/jsx": "^0.1.4"
46
+ "@minejs/jsx": "^0.1.4",
47
+ "@cruxkit/icon": "^0.0.6"
47
48
  },
48
49
  "devDependencies": {
49
- "@cruxkit/icon": "^0.0.5",
50
50
  "@eslint/js": "^9.39.2",
51
51
  "@stylistic/eslint-plugin": "^5.7.0",
52
52
  "@types/bun": "^1.3.6",