feat(RadioGroup,CheckboxGroup): rich settings-card layout via #label slot#54
Open
IgorShevchik wants to merge 8 commits into
Open
feat(RadioGroup,CheckboxGroup): rich settings-card layout via #label slot#54IgorShevchik wants to merge 8 commits into
IgorShevchik wants to merge 8 commits into
Conversation
Add a rich radio cards example (preview image + description + link) to both the nuxt and demo playground pages, demonstrating how to compose the existing card variant with the label slot to build a settings-style selection block (responsive: image hides below sm).
Mirror the rich-card recipe from RadioGroup on CheckboxGroup: same preview image + description + link layout via the label slot, demonstrated on both nuxt and demo playground pages.
…t variants Switch the inner label element from <p> to <span> when variant is "card" or "table". The list variant still renders the reka-ui Label so clicking the label keeps activating the radio/checkbox. Why: <p> auto-closes when it encounters block-level children, which made it impossible to compose rich label slots (preview image + flex layout + inline link) without HTML parsing surprises. <span> is phrasing content and accepts span/img/a children cleanly. Also narrow the CheckboxGroup slot item type via a NormalizeItem helper, mirroring the RadioGroup approach, so the slot's "item" excludes the primitive value branch and exposes user-defined fields directly. Snapshot updates cover RadioGroup, Checkbox(Group) and Table (Table embeds a Checkbox in its row-selection column).
Add Examples sections to both component docs that show the rich card layout (preview image + title + description + "Learn more" link), backed by example components under docs/app/components/content/examples. Add a new skill recipe references/recipes/settings.md that frames the decision: when to use Switch vs Radio vs Checkbox vs PageCardGroup, plus the full code for the rich-card pattern. Register it in SKILL.md.
…-layout-6eg32 # Conflicts: # test/components/__snapshots__/Checkbox-vue.spec.ts.snap # test/components/__snapshots__/Checkbox.spec.ts.snap # test/components/__snapshots__/CheckboxGroup-vue.spec.ts.snap # test/components/__snapshots__/CheckboxGroup.spec.ts.snap # test/components/__snapshots__/RadioGroup-vue.spec.ts.snap # test/components/__snapshots__/RadioGroup.spec.ts.snap # test/components/__snapshots__/Table-vue.spec.ts.snap # test/components/__snapshots__/Table.spec.ts.snap
…n label
When the label slot is rendered as a <span> (for variant="card" / "table"),
the for= attribute is invalid HTML — it is only defined for <label> and
<output>. Browsers ignored it, but a11y linters and HTML validators flag
it. Bind :for conditionally so it stays only on the <label> in the list
variant.
Also addresses review feedback on the rest of the settings-layout PR:
- docs/examples: English copy and a locally-typed item interface to keep
autocomplete / type-checking on slot fields (RadioGroupItem widens
user-defined fields to any via [key: string]: any)
- docs/examples: alt="item.title" instead of empty alt for the
meaning-carrying preview image
- docs: Settings layout H3 uses sentence case + Soon badge + cross-link
between RadioGroup ↔ CheckboxGroup ↔ PageCardGroup
- skill recipe: full multi-select code (no "same as above" placeholder),
warning to validate item.href (reject javascript:/data: / open redirect)
when it comes from an untrusted source, mention that target="_blank"
is safe because B24Link adds rel="noopener noreferrer" automatically
- SKILL.md: routing table row reworded to avoid overlap with
card-pickers ("capability flags" was matched by both rows)
- card-pickers.md: back-link to the new settings recipe
- playgrounds: same English copy + alt + local type interface
BREAKING CHANGE: The label slot of B24RadioGroup, B24Checkbox and
B24CheckboxGroup now renders as <span> instead of <p> when variant is
"card" or "table". Selectors that targeted "p[data-slot=label]" or
relied on <p>'s default block margin inside these variants need to be
updated. For the default list variant the label is still rendered as
<label> — no change there.
…eviews
Replace the PNG preview placeholders in docs examples and playgrounds with
the in-house <Placeholder> component (diagonal-hatch SVG pattern). The
Placeholder already exists in docs/app/components/content/Placeholder.vue
and in both playgrounds — no need to ship binary assets just to demo the
card layout. Real screenshots can be wired in later by swapping
<Placeholder> back to <img :src :alt>.
- Drop the `preview: '...'` field from item interfaces (no longer needed).
- Drop the 6 PNG files (docs/public/b24ui/radio-card-*.png,
playgrounds/{nuxt,demo}/public/radio-card-*.png).
- Recipe (settings.md) keeps <img> in the code sample since users will
bring their own artwork; added a note about <Placeholder> as a stand-in
while artwork is being designed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Кратко о работе
Добавлен рецепт «жирной» карточки выбора настроек для
B24RadioGroupиB24CheckboxGroup— заголовок, описание, превью и инлайн-ссылка «Learn more» прямо внутри радио-/чекбокс-кнопки. Под этот кейс рендер слотаlabelв вариантахcardиtableпереведён с<p>на<span>, чтобы туда можно было класть flex-вёрстку с картинкой и ссылкой без HTML-парсинг сюрпризов.Что сделано
Компоненты (
src/runtime/components/)RadioGroup.vue,Checkbox.vue— слотlabelдляvariant ∈ {card, table}рендерится как<span>. Атрибут:forбиндится условно — только для<label>вlist-варианте.CheckboxGroup.vue— добавлен тип-хелперNormalizeItem<T>(симметрично с RadioGroup);itemв слоте теперь сужается до объектной формы.Документация
docs/content/docs/2.components/radio-group.md,…/checkbox-group.md— добавлены секции## Examples → ### Settings layout :badge{label="Soon"}с перекрёстными ссылками между Radio ↔ Checkbox ↔ PageCardGroup.docs/app/components/content/examples/{radio,checkbox}-group/*SettingsExample.vue— новые example-компоненты с локальным type-interface, английским текстом и<Placeholder>в качестве превью.Скилл (
skills/b24-ui-nuxt/)references/recipes/settings.md— новый рецепт: decision matrix, полный код single- и multi-select, implementation notes (валидацияitem.hrefпротивjavascript:/data:, упоминание<Placeholder>для прототипов).references/recipes/card-pickers.md— обратная ссылка на settings.SKILL.md— рецепт зарегистрирован, routing-table обновлена.Плейграунды (
playgrounds/{nuxt,demo}/app/pages/components/)radio-group.vue,checkbox-group.vue— добавлен блок «Settings layout» (английский текст,<Placeholder>вместо<img>).Тесты (
test/components/__snapshots__/)Radio/Checkbox(Group)иTable(<p data-slot="label">→<span data-slot="label">безfor).⚠ BREAKING CHANGE
Слот
labelвB24RadioGroup,B24CheckboxиB24CheckboxGroupтеперь рендерится как<span>вместо<p>, когдаvariant ∈ {card, table}. Селекторыp[data-slot="label"]и зависимости от дефолтных<p>-отступов внутри этих вариантов потребуют правки. Дляvariant="list"поведение не изменилось — там по-прежнему<label>.Чек-лист на ручную проверку
Docs
pnpm run docs→/docs/components/radio-group— секция «Settings layout» с badge Soon видна, пример рендерится, переключение работает, активная карточка имеет акцентную обводку./docs/components/checkbox-group(можно отметить обе одновременно).Playgrounds
pnpm run dev→/components/radio-groupи/components/checkbox-group— блок «Settings layout» виден, поведение совпадает с docs.pnpm run demo:dev.Поведение карточки
@click.stop).<Placeholder>скрывается (hidden sm:flex), текст занимает всю ширину.Регрессы
variant="list"для всех трёх компонентов — поведение не изменилось,<label>по-прежнему оборачивает текст, клик активирует контрол.B24Tableсо столбцом выбора строк («Select all» / per-row чекбоксы) — рендерится, выбор работает.card-вариантом — нет ошибки «for attribute is only allowed on label/output».marginот<p>в card/table.Skill
skills/b24-ui-nuxt/references/recipes/settings.md— decision matrix читается, multi-select код полный (без «same as above»), warning про URL-валидацию на месте.skills/b24-ui-nuxt/SKILL.md— рецепт перечислен в Recipes, routing-table корректно матчит запрос про «layout chooser with preview».Автоматика (уже прогнано)
pnpm run lint✓pnpm run typecheck✓pnpm vitest run— 214 файлов, 4884 passed / 6 skipped / 0 failedЧто дальше
<Placeholder>(SVG-штриховка). Когда дизайн нарисует скриншоты — заменить<Placeholder>на<img :src="item.preview" :alt="item.title">и снять badgeSoon. Поляpreviewв item уже задокументированы в рецепте.NormalizeItem<T>в общий util — сейчас тип продублирован вRadioGroup.vueиCheckboxGroup.vue. Маленький отдельный PR.descriptionс<p>на<span>(текущий рецепт не использует — оставлено как есть).https://claude.ai/code/session_01VvH54bVMmtobwj6QsVmDjC