mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 17:43:47 +00:00
fix(a11y): label associations for AdminNewsCreate fields
- htmlFor/id pairs for title, slug, read-time, excerpt and featured-image inputs - add an ariaLabel prop to ColoredItemCombobox (applied to the trigger button) and pass the category/tag labels so the comboboxes have an accessible name (WCAG 1.3.1/4.1.2)
This commit is contained in:
@@ -27,6 +27,7 @@ interface ColoredItemComboboxProps {
|
|||||||
onCreateNew: (name: string, color: string) => Promise<ColoredItem>;
|
onCreateNew: (name: string, color: string) => Promise<ColoredItem>;
|
||||||
onDelete?: (item: ColoredItem) => Promise<void>;
|
onDelete?: (item: ColoredItem) => Promise<void>;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
|
ariaLabel?: string;
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
colors?: string[];
|
colors?: string[];
|
||||||
className?: string;
|
className?: string;
|
||||||
@@ -39,6 +40,7 @@ export function ColoredItemCombobox({
|
|||||||
onCreateNew,
|
onCreateNew,
|
||||||
onDelete,
|
onDelete,
|
||||||
placeholder,
|
placeholder,
|
||||||
|
ariaLabel,
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
colors = DEFAULT_COLORS,
|
colors = DEFAULT_COLORS,
|
||||||
className,
|
className,
|
||||||
@@ -190,6 +192,7 @@ export function ColoredItemCombobox({
|
|||||||
isOpen ? 'border-accent-500/50' : 'border-dark-700 hover:border-dark-600',
|
isOpen ? 'border-accent-500/50' : 'border-dark-700 hover:border-dark-600',
|
||||||
isLoading && 'animate-pulse',
|
isLoading && 'animate-pulse',
|
||||||
)}
|
)}
|
||||||
|
aria-label={ariaLabel}
|
||||||
aria-expanded={isOpen}
|
aria-expanded={isOpen}
|
||||||
aria-haspopup="listbox"
|
aria-haspopup="listbox"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -652,8 +652,11 @@ export default function AdminNewsCreate() {
|
|||||||
<div className="space-y-5">
|
<div className="space-y-5">
|
||||||
{/* Title */}
|
{/* Title */}
|
||||||
<div>
|
<div>
|
||||||
<label className="label">{t('news.admin.titleLabel')}</label>
|
<label htmlFor="news-title" className="label">
|
||||||
|
{t('news.admin.titleLabel')}
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
|
id="news-title"
|
||||||
type="text"
|
type="text"
|
||||||
value={title}
|
value={title}
|
||||||
onChange={(e) => setTitle(e.target.value)}
|
onChange={(e) => setTitle(e.target.value)}
|
||||||
@@ -664,8 +667,11 @@ export default function AdminNewsCreate() {
|
|||||||
|
|
||||||
{/* Slug */}
|
{/* Slug */}
|
||||||
<div>
|
<div>
|
||||||
<label className="label">{t('news.admin.slugLabel')}</label>
|
<label htmlFor="news-slug" className="label">
|
||||||
|
{t('news.admin.slugLabel')}
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
|
id="news-slug"
|
||||||
type="text"
|
type="text"
|
||||||
value={slug}
|
value={slug}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
@@ -688,6 +694,7 @@ export default function AdminNewsCreate() {
|
|||||||
onCreateNew={handleCreateCategory}
|
onCreateNew={handleCreateCategory}
|
||||||
onDelete={handleDeleteCategory}
|
onDelete={handleDeleteCategory}
|
||||||
placeholder={t('news.admin.combobox.selectCategory')}
|
placeholder={t('news.admin.combobox.selectCategory')}
|
||||||
|
ariaLabel={t('news.admin.categoryLabel')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -699,14 +706,18 @@ export default function AdminNewsCreate() {
|
|||||||
onCreateNew={handleCreateTag}
|
onCreateNew={handleCreateTag}
|
||||||
onDelete={handleDeleteTag}
|
onDelete={handleDeleteTag}
|
||||||
placeholder={t('news.admin.combobox.selectTag')}
|
placeholder={t('news.admin.combobox.selectTag')}
|
||||||
|
ariaLabel={t('news.admin.tagLabel')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Read time */}
|
{/* Read time */}
|
||||||
<div>
|
<div>
|
||||||
<label className="label">{t('news.admin.readTimeLabel')}</label>
|
<label htmlFor="news-readtime" className="label">
|
||||||
|
{t('news.admin.readTimeLabel')}
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
|
id="news-readtime"
|
||||||
type="number"
|
type="number"
|
||||||
value={readTimeMinutes}
|
value={readTimeMinutes}
|
||||||
onChange={(e) => setReadTimeMinutes(Number(e.target.value) || 1)}
|
onChange={(e) => setReadTimeMinutes(Number(e.target.value) || 1)}
|
||||||
@@ -718,8 +729,11 @@ export default function AdminNewsCreate() {
|
|||||||
|
|
||||||
{/* Excerpt */}
|
{/* Excerpt */}
|
||||||
<div>
|
<div>
|
||||||
<label className="label">{t('news.admin.excerptLabel')}</label>
|
<label htmlFor="news-excerpt" className="label">
|
||||||
|
{t('news.admin.excerptLabel')}
|
||||||
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
|
id="news-excerpt"
|
||||||
value={excerpt}
|
value={excerpt}
|
||||||
onChange={(e) => setExcerpt(e.target.value)}
|
onChange={(e) => setExcerpt(e.target.value)}
|
||||||
className="input min-h-[80px] resize-y"
|
className="input min-h-[80px] resize-y"
|
||||||
@@ -729,9 +743,12 @@ export default function AdminNewsCreate() {
|
|||||||
|
|
||||||
{/* Featured Image URL */}
|
{/* Featured Image URL */}
|
||||||
<div>
|
<div>
|
||||||
<label className="label">{t('news.admin.imageLabel')}</label>
|
<label htmlFor="news-image" className="label">
|
||||||
|
{t('news.admin.imageLabel')}
|
||||||
|
</label>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<input
|
<input
|
||||||
|
id="news-image"
|
||||||
type="text"
|
type="text"
|
||||||
value={featuredImageUrl}
|
value={featuredImageUrl}
|
||||||
onChange={(e) => setFeaturedImageUrl(e.target.value)}
|
onChange={(e) => setFeaturedImageUrl(e.target.value)}
|
||||||
|
|||||||
Reference in New Issue
Block a user