ഉള്ളടക്കത്തിലേക്ക് പോകുക
ബീറ്റ · പരീക്ഷണാത്മകംReact 19പിയർ ഡിപൻഡൻസികളില്ല

ബട്ടൺ

മൂന്ന് സൈസുകളിൽ പ്രൈമറി, സെക്കൻഡറി, ഔട്ട്‌ലൈൻ, ഗോസ്റ്റ്, ഡേഞ്ചർ, ലിങ്ക് ബട്ടണുകൾ, സ്വയം കൈകാര്യം ചെയ്യുന്ന ഒരു ലോഡിംഗ് സ്റ്റേറ്റോടുകൂടി.

ബീറ്റ കമ്പോണന്റുകൾ മാറാൻ സാധ്യതയുണ്ട്; അവ നിങ്ങളുടെ കോഡ് തകരാറിലാക്കിയേക്കാം. സ്വന്തം ഉത്തരവാദിത്തത്തിൽ ഉപയോഗിക്കുക, ബഗ് ട്രാക്കർ വഴി അഭിപ്രായം അറിയിക്കുക.

ഈ പേജിൽ

ഇൻസ്റ്റലേഷൻ

bash
npx gbs-add-block@latest -a Button -beta

എല്ലാ കമ്പോണന്റുകളും ഇംപോർട്ട് ചെയ്യുന്ന ചെറിയ shared ഫോൾഡറിനൊപ്പം, button ഫോൾഡർ ഈ ബ്ലോക്ക് നിങ്ങളുടെ പ്രോജക്ടിലേക്ക് കോപ്പി ചെയ്യുന്നു. കോഡ് നിങ്ങളുടേതാണ്, സ്വതന്ത്രമായി മാറ്റം വരുത്താം. React അല്ലാതെ peer dependencies ഒന്നും ഇല്ല.

ആവശ്യകതകൾ

  • React 19-ഉം @types/react 19-ഉം
  • TypeScript ടാർഗെറ്റ് ES2022 അല്ലെങ്കിൽ അതിനു ശേഷമുള്ളത്, "jsx": "react-jsx" എന്നതോടെ
  • 2024-നു ശേഷമുള്ള ബ്രൗസറുകൾ (സ്റ്റൈലുകൾ light-dark(), color-mix() ഉപയോഗിക്കുന്നു)

സ്റ്റൈൽഷീറ്റ് ഒരു തവണ ഇംപോർട്ട് ചെയ്യുക, ഉദാഹരണത്തിന് നിങ്ങളുടെ ഗ്ലോബൽ CSS-ൽ:

css
@import "../components/button/styles.css";

അല്ലെങ്കിൽ നിങ്ങളുടെ റൂട്ട് ലേഔട്ട് / എൻട്രി ഫയലിൽ:

ts
import "@/components/button/styles.css";

ദൈനംദിന ഓരോ പ്രവർത്തനവും ബട്ടൺ ഉൾക്കൊള്ളുന്നു: പ്രൈമറിയും സെക്കൻഡറിയും പ്രവർത്തനങ്ങൾ, ഔട്ട്‌ലൈനുകൾ, ശാന്തമായ ഗോസ്റ്റ് ബട്ടണുകൾ, വിനാശകരമായ (destructive) പ്രവർത്തനങ്ങൾ, ലിങ്ക്-സ്റ്റൈൽ ബട്ടണുകൾ, മൂന്ന് സൈസുകളിൽ, ഐക്കണുകളോടുകൂടി. അതിന്റെ ലോഡിംഗ് സ്റ്റേറ്റ് സ്വയം കൈകാര്യം ചെയ്യുന്നു: onClick-ൽ നിന്ന് ഒരു പ്രോമിസ് (promise) റിട്ടേൺ ചെയ്യുക, അല്ലെങ്കിൽ ഒരു Server Action ഉപയോഗിച്ച് ഫോം സമർപ്പിക്കുക, ജോലി പൂർത്തിയാകുന്നതുവരെ ബട്ടൺ ഒരു സ്പിന്നർ കാണിക്കും. ഇതിനിടയിൽ അതിന്റെ വീതിയും കീബോർഡ് ഫോക്കസും നിലനിർത്തുന്നു. ഒരു റൗട്ടർ ലിങ്ക് പോലുള്ള മറ്റൊരു എലമെന്റ് ആയും, അതേ രൂപത്തോടെ, ഇത് റെൻഡർ ചെയ്യാൻ കഴിയും.

എല്ലാ കമ്പോണന്റുകളും ഒരുമിച്ച് തീം ചെയ്യാൻ :root-ൽ --gbs-* വേരിയബിളുകൾ സെറ്റ് ചെയ്യുക, ഗ്രിഡ് ഉൾപ്പെടെ. ഓരോ കമ്പോണന്റിന്റെയും സ്വന്തം വേരിയബിളുകൾ ഇവയിലേക്കും, പിന്നീട് ബിൽറ്റ്-ഇൻ പാലറ്റിലേക്കും ഫാൾബാക്ക് ചെയ്യുന്നു, അതിനാൽ ഡിഫോൾട്ടായി കമ്പോണന്റുകൾ ഒരേ പോലെ കാണപ്പെടുന്നു.

ഡിഫോൾട്ട്

Live preview

ക്വിക്ക് സ്റ്റാർട്ട്

tsx
"use client";
 
import { Button } from "@/components/button";
 
export function SaveBar({ onSave }: { onSave(): Promise<void> }) {
  return (
    <div>
      <Button variant="outline">Cancel</Button>
      <Button onClick={onSave}>Save changes</Button>
    </div>
  );
}

onSave ഒരു പ്രോമിസ് റിട്ടേൺ ചെയ്യുന്നു, അതിനാൽ Save ബട്ടൺ ഒരു സ്പിന്നർ കാണിക്കുകയും, അത് ഫലം കാണിക്കുന്നതുവരെ കൂടുതൽ ക്ലിക്കുകൾ അവഗണിക്കുകയും ചെയ്യുന്നു.

ഡിഫോൾട്ട് ടൈപ്പ് 'button' ആണ്, ബ്രൗസറിന്റെ 'submit' അല്ല, അതിനാൽ ഒരു ഫോമിനുള്ളിലെ ബട്ടൺ അബദ്ധത്തിൽ അത് സമർപ്പിക്കുന്നില്ല. അങ്ങനെ ചെയ്യേണ്ട ബട്ടണിന് type='submit' നൽകുക.

പ്രോപ്സ് ടേബിൾ

എല്ലാ <button> ആട്രിബ്യൂട്ടുകളും, കൂടാതെ:

PropTypeDefaultDescription
variant"primary" | "secondary" | "outline" | "ghost" | "danger" | "link""primary"ദൃശ്യപരമായ ഭാരം (visual weight).
size"sm" | "md" | "lg""md"ഉയരം 30 / 36 / 44 px.
type"button" | "submit" | "reset""button"നേറ്റീവ് ബട്ടൺ ടൈപ്പ്.
loadingbooleanfalseബിസി സ്റ്റേറ്റ്: സ്പിന്നർ, aria-busy, ക്ലിക്കുകൾ അവഗണിക്കപ്പെടുന്നു.
loadingTextReactNodeബിസി ആയിരിക്കുമ്പോൾ ലേബലിനു പകരം സ്പിന്നറിനടുത്തുള്ള ടെക്സ്റ്റ്.
leadingReactNodeലേബലിനു മുമ്പുള്ള ഐക്കൺ.
trailingReactNodeലേബലിനു ശേഷമുള്ള ഐക്കൺ.
iconReactNodeഒരു സ്ക്വയർ ഐക്കൺ-മാത്രം ബട്ടൺ ഉണ്ടാക്കുന്നു. എപ്പോഴും aria-label ചേർക്കുക.
fullWidthbooleanfalseകണ്ടെയ്നറിന്റെ വീതി നിറയ്ക്കുക.
disabledbooleanfalseനേറ്റീവായി ഡിസേബിൾ ചെയ്തത്.
onClick(event) => unknownഫലം കാണുന്നതുവരെ ലോഡിംഗ് കാണിക്കാൻ ഒരു പ്രോമിസ് റിട്ടേൺ ചെയ്യുക.
render(props: ButtonRenderProps) => ReactElementബട്ടണിന്റെ രൂപത്തോടെ മറ്റൊരു എലമെന്റ് റെൻഡർ ചെയ്യുക. Links കാണുക.
classNamestringബട്ടണിനുള്ള ക്ലാസ്.
classNamesPartial<Record<ButtonSlot, string>>സ്ലോട്ടുകൾ: root, content, spinner, icon.
localeTextPartial<ButtonLocaleText>ഇംഗ്ലീഷ്Locale Text കാണുക.
refRef<HTMLButtonElement><button> എലമെന്റ്.

വേരിയന്റുകൾ

tsx
<Button>Primary</Button>                     {/* the main action on a screen */}
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>       {/* toolbars, tables, low-emphasis actions */}
<Button variant="danger">Delete</Button>     {/* destructive actions */}
<Button variant="link">Learn more</Button>   {/* looks like a link, behaves like a button */}

ഐക്കണുകൾ

tsx
<Button leading={<PlusIcon />}>New invoice</Button>
<Button variant="outline" trailing={<ArrowRightIcon />}>Next</Button>
<Button variant="ghost" icon={<TrashIcon />} aria-label="Delete row" />

ഐക്കണുകൾ ടെക്സ്റ്റിന് അനുസൃതമായ വലുപ്പത്തിലാണ് (1.15 em). leading, trailing ഐക്കണുകൾ സ്ക്രീൻ റീഡറുകളിൽ നിന്ന് മറച്ചിരിക്കുന്നു, കാരണം ലേബൽ ബട്ടൺ എന്താണ് ചെയ്യുന്നതെന്ന് പറയുന്നു. ഒരു ഐക്കൺ-മാത്രം ബട്ടണിന് ദൃശ്യമായ ടെക്സ്റ്റ് ഇല്ല, അതിനാൽ അതിന്റെ aria-label മാത്രമാണ് അതിന്റെ പേര്.

ലോഡിംഗ്

ലോഡിംഗ് സ്റ്റേറ്റിന് മൂന്ന് സ്രോതസ്സുകളുണ്ട്:

SourceHow
ഏസിൻക് onClickഒരു പ്രോമിസ് റിട്ടേൺ ചെയ്യുക: onClick={async () => { await save(); }}
ഫോം സമർപ്പണം<form action={serverAction}>-നുള്ളിലെ ഒരു type="submit" ബട്ടൺ, ആക്ഷൻ പ്രവർത്തിക്കുമ്പോൾ ബിസി ആണ് (React 19 useFormStatus).
മാനുവൽloading={isPending}
tsx
<form action={createInvoice}>
  <Input name="customer" label="Customer" required />
  <Button type="submit">Create invoice</Button>
</form>
  • ഫോക്കസ് ചെയ്യാവുന്നതായി തുടരുന്നു: ബിസി ആയിരിക്കുമ്പോൾ, ബട്ടൺ disabled-ന് പകരം aria-disabled ഉപയോഗിക്കുന്നു, അതിനാൽ കീബോർഡ് ഫോക്കസ് മറ്റെവിടെയും പോകുന്നില്ല.
  • സ്ഥാനം മാറ്റുന്നില്ല: ലേബൽ മറഞ്ഞിരിക്കുന്നു, പക്ഷേ അതിന്റെ സ്ഥലം നിലനിർത്തുന്നു, അതിനാൽ ബട്ടണിന്റെ വീതി മാറുന്നില്ല. loadingText ലേബലിന് പകരം ടെക്സ്റ്റ് വെക്കുന്നു, അപ്പോൾ വീതി മാറാം.
  • ആവർത്തനങ്ങൾ അവഗണിക്കുന്നു: ജോലി പൂർത്തിയാകുന്നതുവരെ കൂടുതൽ ക്ലിക്കുകളും ഫോം സമർപ്പണങ്ങളും തടയപ്പെടുന്നു.
  • പിശകുകൾ ദൃശ്യമായി നിലനിർത്തുന്നു: പ്രോമിസ് നിരസിക്കപ്പെട്ടാൽ (reject), ലോഡിംഗ് സ്റ്റേറ്റ് അവസാനിക്കുകയും, പിശക് ഒരു കൈകാര്യം ചെയ്യപ്പെടാത്ത റിജക്ഷനായി ഇപ്പോഴും ഉയർന്നുവരികയും ചെയ്യുന്നു. ഒരു സന്ദേശം കാണിക്കാൻ നിങ്ങളുടെ ഹാൻഡ്‌ലറിൽ അത് പിടിക്കുക (catch).

ലിങ്കുകളും മറ്റ് എലമെന്റുകളും

ഒരു ലിങ്കിനെ ബട്ടൺ പോലെ കാണിക്കാൻ, render ഉപയോഗിക്കുക. ഇതിന് ബട്ടണിന്റെ ക്ലാസ് നെയിമുകൾ, ഡാറ്റ ആട്രിബ്യൂട്ടുകൾ, ക്ലിക്ക് ഹാൻഡ്‌ലിംഗ്, കണ്ടന്റ് എന്നിവ ലഭിക്കുന്നു:

tsx
import Link from "next/link";
 
<Button
  variant="outline"
  render={(props) => <Link href="/billing" {...props} />}
>
  Go to billing
</Button>;
tsx
<Button
  variant="link"
  render={(props) => (
    <a href="/docs" target="_blank" rel="noreferrer" {...props} />
  )}
>
  Documentation
</Button>

ബട്ടൺ-മാത്രമായ ആട്രിബ്യൂട്ടുകൾ (type, form, name, value) റെൻഡർ ചെയ്ത എലമെന്റിൽ നിന്ന് ഒഴിവാക്കപ്പെടുന്നു. ഡിസേബിൾ ചെയ്തതോ ബിസി ആയതോ ആയ ഒരു ലിങ്കിന് aria-disabled ലഭിക്കുകയും ക്ലിക്കുകൾ അവഗണിക്കുകയും ചെയ്യുന്നു.

കീബോർഡ്

KeysAction
Enter / Spaceബട്ടൺ ആക്ടിവേറ്റ് ചെയ്യുക.
Tabഅടുത്ത കൺട്രോളിലേക്ക് നീങ്ങുക; ബിസി ബട്ടണുകൾ ടാബ് ഓർഡറിൽ തുടരുന്നു.

ആക്സസിബിലിറ്റി: ഡിഫോൾട്ടായി ഒരു യഥാർത്ഥ <button>. ബിസി ആയിരിക്കുമ്പോൾ, ഇതിന് aria-busy="true" ഉണ്ട്, കൂടാതെ ദൃശ്യപരമായി മറച്ച ടെക്സ്റ്റിലൂടെ "Loading" അറിയിക്കുന്നു. leading, trailing ഐക്കണുകൾ aria-hidden ആണ്. കീബോർഡ് ഫോക്കസിൽ മാത്രം (:focus-visible) ഫോക്കസ് 2 px റിംഗായി കാണിക്കുന്നു.

സ്റ്റൈലിംഗും തീമിംഗും

എല്ലാ റൂളുകളും CSS components ലെയറിലാണ്, അതിനാൽ className / classNames വഴി കടന്നുപോകുന്ന യൂട്ടിലിറ്റി ക്ലാസുകൾ അവയെ ഓവർറൈഡ് ചെയ്യുന്നു.

tsx
<Button className="rounded-full px-6" />

CSS വേരിയബിളുകൾ

.bt-root-ലോ, :root-ലോ, അല്ലെങ്കിൽ style-ലൂടെയോ ഇവ ഓവർറൈഡ് ചെയ്യുക. ഓരോ വേരിയബിളും അതേ പേരിലുള്ള ഷെയേർഡ് --gbs-*-ലേക്ക് ഫാൾബാക്ക് ചെയ്യുന്നു, പിന്നീട് ആ സ്റ്റൈൽഷീറ്റ് ലോഡ് ചെയ്തിട്ടുണ്ടെങ്കിൽ DataGrid-ന്റെ --dg-*-ലേക്കും, അവസാനം ബിൽറ്റ്-ഇൻ പാലറ്റിലേക്കും.

VariableUsed for
--bt-height, --bt-px, --bt-gap, --bt-font-sizeസൈസ് (size സെറ്റ് ചെയ്യുന്നത്).
--bt-fill, --bt-fill-hover, --bt-ink, --bt-lineബാക്ക്ഗ്രൗണ്ട്, ഹോവർ ബാക്ക്ഗ്രൗണ്ട്, ടെക്സ്റ്റ്, ബോർഡർ (variant സെറ്റ് ചെയ്യുന്നത്).
--bt-accent, --bt-accent-fgprimary വേരിയന്റും link ടെക്സ്റ്റും.
--bt-danger, --bt-danger-fgdanger വേരിയന്റ്.
--bt-subtlesecondary ബാക്ക്ഗ്രൗണ്ട്.
--bt-border, --bt-hoveroutline ബോർഡറും ഹോവർ ബാക്ക്ഗ്രൗണ്ടും.
--bt-focusഫോക്കസ് റിംഗ്.
--bt-radiusകോർണർ റേഡിയസ്.
css
/* A brand variant, without touching the component */
.bt-root.brand {
  --bt-fill: #7c3aed;
  --bt-fill-hover: #6d28d9;
  --bt-line: #7c3aed;
  --bt-ink: white;
}

ഡാറ്റ ആട്രിബ്യൂട്ടുകൾ

ElementAttributes
Root (.bt-root)data-variant, data-size, data-busy, data-icon-only, data-full-width, aria-busy, aria-disabled

ലോക്കൽ ടെക്സ്റ്റ്

tsx
<Button localeText={{ loading: "Wird geladen" }} />
KeyDefault
loading"Loading" — ബിസി ആയിരിക്കുമ്പോൾ അറിയിക്കപ്പെടുന്നു, loadingText നൽകിയിട്ടില്ലെങ്കിൽ

ഹെഡ്‌ലെസ് ഉപയോഗം

ExportDescription
buttonState({ disabled, loading, pending })ബട്ടൺ ബിസി ആണോ, ആക്ടിവേഷൻ അവഗണിക്കുന്നുണ്ടോ, നേറ്റീവ് disabled ഉപയോഗിക്കുന്നുണ്ടോ എന്ന്.
isPromiseLike(value)ഒരു ഏസിൻക് ക്ലിക്ക് ഹാൻഡ്‌ലറിന്റെ ഫലം കണ്ടെത്തുന്നു.

Next.js

ബട്ടൺ ഒരു ക്ലയന്റ് കമ്പോണന്റ് ആണ്, അതിന്റെ ഫയലിന്റെ മുകളിൽ "use client" ഉള്ളത്.

  • Server Components-ൽ: ഫംഗ്ഷൻ പ്രോപ്‌സ് ഒന്നും കൈമാറാത്തിടത്തോളം ഇത് പ്രവർത്തിക്കും. <form action={serverAction}>-നുള്ളിലെ ഒരു type="submit" ബട്ടണിന് അതൊന്നും ആവശ്യമില്ല, കൂടാതെ അത് സ്വയം പുരോഗതി കാണിക്കുന്നു, അതിനാൽ ഇത് ഒരു Server Component പേജിൽ പ്രവർത്തിക്കും.
  • onClick അല്ലെങ്കിൽ render ഉപയോഗിച്ച്: ഇവ ഫംഗ്ഷനുകളാണ്, ഒരു Server Component-ന് ഒരു ക്ലയന്റ് കമ്പോണന്റിലേക്ക് ഇവ കൈമാറാൻ കഴിയില്ല. ഒരു ക്ലയന്റ് കമ്പോണന്റിനുള്ളിൽ ഇവ ഉപയോഗിക്കുക, ഉദാഹരണത്തിന് render ഉപയോഗിച്ച് next/link റാപ്പ് ചെയ്യാൻ.

മുമ്പത്തെ കസ്റ്റം ബട്ടണിൽ നിന്ന് മൈഗ്രേറ്റ് ചെയ്യുന്നത്

മുമ്പത്തേത്പുതിയത്
CustomBtnButton
value="Submit" (ലേബൽ)children: <Button>Submit</Button>
id, name, className, disabled, onClickഅതേ പേരുകൾ
type (ബ്രൗസറിൽ ഡിഫോൾട്ട് submit)type, ഇപ്പോൾ ഡിഫോൾട്ടായി button; ആവശ്യമുള്ളിടത്ത് type="submit" നൽകുക
globalStyle.ts-ൽ നിന്നുള്ള buttonStyles (primary, secondary, outline, ghost, danger; sm, md, lg)അതേ പേരുകളിലുള്ള variant-ഉം size-ഉം, കൂടാതെ link
പുതിയത്: loading, ഏസിൻക് onClick, ഫോം-ആക്ഷൻ പെൻഡിംഗ് സ്റ്റേറ്റ്, ഐക്കണുകൾ, fullWidth, render

കുറിപ്പുകൾ

  • ഐക്കൺ-മാത്രം ബട്ടണുകൾക്ക് ഒരു aria-label ആവശ്യമാണ്; ഒരു ഐക്കണിൽ നിന്ന് കമ്പോണന്റിന് ഒന്ന് ഊഹിക്കാൻ കഴിയില്ല.
  • render, അതിന് ലഭിക്കുന്ന പ്രോപ്‌സ് എലമെന്റിൽ സ്പ്രെഡ് ചെയ്യണം, അല്ലെങ്കിൽ രൂപവും ക്ലിക്ക് ഹാൻഡ്‌ലിംഗും നഷ്ടപ്പെടും.