Skip to main content

syncfusion-blazor-toolkit-buttons

Implement Syncfusion Blazor Toolkit button components — SfButton, SfButtonGroup, and inner Button. USE FOR: primary/secondary clickable buttons, icon-only buttons, toggle buttons, button groups (single/multi selection), event handlers, and accessibility (keyboard, ARIA, focus). DO NOT USE FOR: form input fields (use syncfusion-blazor-toolkit-inputs), navigation menu UI (use SfMenu / SfToolbar — not in this skill), icon-only controls that should suppress focus (use a styled syncfusion-blazor-toolkit-notifications spinner instead).

소스 정보

저장소
syncfusion/blazor-toolkit
최근 소스 활동
2026년 10월 14일 08:53
감지된 SKILL.md 언어
영어
스타
20
포크
13

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
6 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
license
MIT
name
syncfusion-blazor-toolkit-buttons
description
Implement Syncfusion Blazor Toolkit button components — SfButton, SfButtonGroup, and inner Button. USE FOR: primary/secondary clickable buttons, icon-only buttons, toggle buttons, button groups (single/multi selection), event handlers, and accessibility (keyboard, ARIA, focus). DO NOT USE FOR: form input fields (use syncfusion-blazor-toolkit-inputs), navigation menu UI (use SfMenu / SfToolbar — not in this skill), icon-only controls that should suppress focus (use a styled syncfusion-blazor-toolkit-notifications spinner instead).
compatibility
.NET 8+, render-modes: Static SSR, Server, WebAssembly, Auto
metadata
{"author":"Syncfusion Inc","version":"1.0.0"}
# Syncfusion Blazor Toolkit Buttons > ✅ **Render mode:** Works in **all** render modes — `SfButton` is usable in Static SSR; only event handlers (`OnClick`) require interactivity. Read `AGENTS.md` to determine the project's interactivity mode before wiring event handlers. ## Core Rules 1. **`SfButton` does not render a `<form>` wrapper.** Add `<EditForm>` or `<form>` yourself if you need form-scoped submission. 2. **`IsPrimary="true"` is presentational only.** It applies the active-theme primary CSS class — pair with theme CSS to control actual visual weight. 3. **`OnClick` is `EventCallback<MouseEventArgs>`**, fired after click; not cancellable. Use the `Created` lifecycle event for initialization, not `OnClick`. 4. **`Disabled` is one-way.** The component does not auto-clear it after a click; toggle the bound flag manually in your `@code` block. 5. **`IconCss` accepts a Syncfusion icon class pair** (e.g. `e-icons e-add`). Bare-prefix classes won't render. 6. **`SfButtonGroup Mode="SelectionMode.Multiple"` allows empty selection.** If you need mandatory selection, validate in code. 7. **Inner `Button` components inside `SfButtonGroup` do not inherit `CssClass`.** Re-apply at the inner level. 8. **Keyboard activation is `Enter` and `Space`.** Don't override or you'll break accessibility. 9. **`HtmlAttributes` captures arbitrary HTML attributes** (id, data-*, role) without exposing every one as a property. ## Don'ts | Anti-pattern | Symptom | Fix | |---|---|---| | `async void OnClick = …` | Exceptions silently escape the dispatcher; spinner "sticks" with no error | `async Task OnClick(MouseEventArgs e)` — let Blazor handle re-rendering | | `<SfButton>` inside `<a>` | Two interactive roles; click intercepted; ARIA mis-announcement | Use `<SfButton>` with `CssClass="e-link"` instead, or a true `<a>` | | `Disabled="@(bool?)flag"` | Nullable binding throws on toggle; component treats as always-false | Bind to a `bool`, never `bool?` | | Override `:focus` without `:focus-visible` replacement | WCAG 2.4.7 violation; keyboard users lose focus visibility | Define `:focus-visible { outline: 2px solid var(--brand) }` | | `OnClick` for form submit with no surrounding `<EditForm>` | Validation skipped; data posted without `DataAnnotationsValidator` | Wrap in `<EditForm Model="…"><DataAnnotationsValidator/>` then call `OnValidSubmit` | ## Anti-Pattern Workflows These are the four most common mistakes agents make; the workflow below each says exactly what to do instead. ### Workflow 1 — Agent wants to wire `OnClick="@Save"` **Bad:** ```razor <SfButton OnClick="@Save">Save</SfButton> @code { private async void Save(MouseEventArgs _) { /* ... */ } } ``` **Why it fails:** `async void` says "I will never await me" — Blazor's dispatcher can't catch exceptions, so the unhappy path dumps to console. Re-rendering also fights the awaited continuations. > This is a general Blazor rule across all click handlers (`SfButton`, > `<button @onclick>`, etc.) — see the > [`author-component`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-blazor/skills/author-component/SKILL.md) > upstream skill for the broader rule set. **Correct:** ```razor @using Syncfusion.Blazor.Toolkit <SfButton OnClick="@SaveAsync">Save</SfButton> @code { private bool _busy; private async Task SaveAsync(MouseEventArgs _) { if (_busy) return; _busy = true; try { await SaveService.SaveAsync(model); } finally { _busy = false; } } } ``` ### Workflow 2 — Agent nests `SfButtonGroup` inside `<EditForm>` expecting `Disabled` to clear **Bad:** ```razor <SfButtonGroup Mode="@SelectionMode.Multiple"> <Button>Bold</Button> <Button>Italic</Button> </SfButtonGroup> ``` **Why it fails:** empty selection is valid `Multiple` mode. Form-validation won't catch "user selected nothing" unless you write a custom validator. **Correct:** ```razor @using Syncfusion.Blazor.Toolkit @using System.ComponentModel.DataAnnotations <EditForm Model="editor"> <DataAnnotationsValidator/> <ValidationMessage For="@(() => editor.Selection)"/> <SfButtonGroup Mode="@SelectionMode.Multiple" SelectedChanged="@SelectionChanged"> <Button>Bold</Button> <Button>Italic</Button> </SfButtonGroup> </EditForm> @code { private void SelectionChanged(Syncfusion.Blazor.Toolkit.SelectedItemsChangedEventArgs e) { editor.Selection = e.SelectedIndexes; // not empty after a click } public class EditorModel { [Required] public int[] Selection { get; set; } = Array.Empty<int>(); } } ``` ### Workflow 3 — Agent places `<SfButton>` inside a `<a>` to make a card link **Bad:** ```razor <a href="/detail/42"> <SfButton Content="Open" OnClick="OpenDetail" /> <!-- both click handlers fire --> </a> ``` **Why it fails:** clicking the button bubbles to the parent anchor and fires two navigations. ARIA reports two controls on one element. **Correct:** ```razor @using Syncfusion.Blazor.Toolkit <a href="/detail/42" role="link"> <SfButton Content="Open" CssClass="e-link" HtmlAttributes="@(new Dictionary<string, object> { ["aria-label"] = "Open detail 42" })"/> </a> ``` `CssClass="e-link"` re-skins the button as a link, removing the button semantics; the anchor remains the real interactive role. ### Workflow 4 — Agent assumes `Disabled="@isProcessing"` clears via the button click **Bad:** ```razor <SfButton Disabled="@_isProcessing" OnClick="SubmitAsync">Submit</SfButton> @code { private async Task SubmitAsync(MouseEventArgs _) { _isProcessing = true; await DoWork(); } // submit fires but `_isProcessing` is never set back to false ⇒ permanent lock } ``` **Why it fails:** `Disabled` is one-way; the click handler must clear the flag itself. **Correct:** ```razor @using Syncfusion.Blazor.Toolkit <SfButton Disabled="@_isProcessing" OnClick="SubmitAsync">Submit</SfButton> @code { private bool _isProcessing; private async Task SubmitAsync(MouseEventArgs _) { if (_isProcessing) return; _isProcessing = true; try { await DoWork(); } finally { _isProcessing = false; } // mandatory clear } } ``` **Or:** simpler, rely on the framework's `IsBusy`/`ButtonState` pattern or a wrapping `<SfSpinner>` overlay (see [syncfusion-blazor-toolkit-notifications](../syncfusion-blazor-toolkit-notifications/SKILL.md)). ## Minimal Example ```razor @using Syncfusion.Blazor.Toolkit <SfButton Content="Save" IsPrimary="true" OnClick="@SaveAsync" /> @code { private async Task SaveAsync(MouseEventArgs _) { // your async work; see Workflow 1 for the busy-flag pattern } } ``` --- ## Documentation and Navigation Guide | Need | Read | |---|---| | First button / project setup | [references/getting-started.md](references/getting-started.md) | | Styling, `Disabled`, `CssClass` | [references/button-fundamentals.md](references/button-fundamentals.md) | | Icons, `Content` vs `ChildContent` | [references/icons-and-content.md](references/icons-and-content.md) | | Events, `EventCallback`, async patterns | [references/events-and-callbacks.md](references/events-and-callbacks.md) | | `SfButtonGroup`, selection modes | [references/button-group.md](references/button-group.md) | > Full property reference for `SfButton`, `SfButtonGroup`, and inner `Button` lives in `references/button-fundamentals.md` and `references/button-group.md`. --- ## Next Steps 1. **Start Simple:** Read [references/getting-started.md](references/getting-started.md) 2. **Style and Configure:** Explore [references/button-fundamentals.md](references/button-fundamentals.md) 3. **Add Interactivity:** Learn [references/events-and-callbacks.md](references/events-and-callbacks.md) 4. **Expand:** Grouping in [references/button-group.md](references/button-group.md) **Demo:** https://blazor.syncfusion.com/demos/toolkit/buttons/button
GitHub에서 보기