update
This commit is contained in:
@ -69,80 +69,97 @@ export class DeesInputRadiogroup extends DeesInputBase<string | object> {
|
||||
:host {
|
||||
display: block;
|
||||
position: relative;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
.maincontainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.maincontainer.horizontal {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.radio-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 8px 0;
|
||||
gap: 10px;
|
||||
padding: 6px 0;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
user-select: none;
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.maincontainer.horizontal .radio-option {
|
||||
padding: 8px 16px 8px 0;
|
||||
padding: 6px 20px 6px 0;
|
||||
}
|
||||
|
||||
.radio-option:hover .radio-circle {
|
||||
border-color: ${cssManager.bdTheme('#0050b9', '#0084ff')};
|
||||
border-color: ${cssManager.bdTheme('hsl(215 20.2% 65.1%)', 'hsl(215 20.2% 35.1%)')};
|
||||
background: ${cssManager.bdTheme('hsl(210 40% 96.1%)', 'hsl(215 20.2% 11.8%)')};
|
||||
}
|
||||
|
||||
.radio-option:hover .radio-label {
|
||||
color: ${cssManager.bdTheme('#1a1a1a', '#ffffff')};
|
||||
color: ${cssManager.bdTheme('hsl(215.3 25% 8.8%)', 'hsl(210 40% 98%)')};
|
||||
}
|
||||
|
||||
.radio-circle {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid ${cssManager.bdTheme('#999', '#666')};
|
||||
background: ${cssManager.bdTheme('#fff', '#1a1a1a')};
|
||||
transition: all 0.2s ease;
|
||||
border: 2px solid ${cssManager.bdTheme('hsl(215 20.2% 65.1%)', 'hsl(215 20.2% 35.1%)')};
|
||||
background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(215 30% 6.8%)')};
|
||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.radio-option.selected .radio-circle {
|
||||
border-color: ${cssManager.bdTheme('#0050b9', '#0084ff')};
|
||||
background: ${cssManager.bdTheme('#0050b9', '#0084ff')};
|
||||
border-color: ${cssManager.bdTheme('hsl(217.2 91.2% 59.8%)', 'hsl(213.1 93.9% 67.8%)')};
|
||||
background: ${cssManager.bdTheme('hsl(217.2 91.2% 59.8%)', 'hsl(213.1 93.9% 67.8%)')};
|
||||
}
|
||||
|
||||
.radio-option.selected .radio-circle::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: white;
|
||||
background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(215 30% 6.8%)')};
|
||||
transform: scale(0);
|
||||
transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.radio-option.selected .radio-circle::after {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.radio-circle:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(215 30% 3.9%)')},
|
||||
0 0 0 4px ${cssManager.bdTheme('hsl(217.2 91.2% 59.8%)', 'hsl(213.1 93.9% 67.8%)')};
|
||||
}
|
||||
|
||||
.radio-label {
|
||||
font-size: 14px;
|
||||
color: ${cssManager.bdTheme('#666', '#999')};
|
||||
transition: color 0.2s ease;
|
||||
font-weight: 500;
|
||||
color: ${cssManager.bdTheme('hsl(215.3 25% 26.7%)', 'hsl(217.9 10.6% 74.9%)')};
|
||||
transition: color 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
letter-spacing: -0.006em;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.radio-option.selected .radio-label {
|
||||
color: ${cssManager.bdTheme('#1a1a1a', '#ffffff')};
|
||||
font-weight: 500;
|
||||
color: ${cssManager.bdTheme('hsl(215.3 25% 8.8%)', 'hsl(210 40% 98%)')};
|
||||
}
|
||||
|
||||
:host([disabled]) .radio-option {
|
||||
@ -151,40 +168,49 @@ export class DeesInputRadiogroup extends DeesInputBase<string | object> {
|
||||
}
|
||||
|
||||
:host([disabled]) .radio-option:hover .radio-circle {
|
||||
border-color: ${cssManager.bdTheme('#999', '#666')};
|
||||
border-color: ${cssManager.bdTheme('hsl(215 20.2% 65.1%)', 'hsl(215 20.2% 35.1%)')};
|
||||
background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(215 30% 6.8%)')};
|
||||
}
|
||||
|
||||
:host([disabled]) .radio-option:hover .radio-label {
|
||||
color: ${cssManager.bdTheme('#666', '#999')};
|
||||
color: ${cssManager.bdTheme('hsl(215.3 25% 26.7%)', 'hsl(217.9 10.6% 74.9%)')};
|
||||
}
|
||||
|
||||
.label-text {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: ${cssManager.bdTheme('#333', '#ccc')};
|
||||
margin-bottom: 8px;
|
||||
color: ${cssManager.bdTheme('hsl(215.3 25% 8.8%)', 'hsl(210 40% 98%)')};
|
||||
margin-bottom: 10px;
|
||||
letter-spacing: -0.006em;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.description-text {
|
||||
font-size: 12px;
|
||||
color: ${cssManager.bdTheme('#666', '#999')};
|
||||
margin-top: 8px;
|
||||
line-height: 1.4;
|
||||
font-size: 13px;
|
||||
color: ${cssManager.bdTheme('hsl(215.4 16.3% 56.9%)', 'hsl(215 20.2% 55.1%)')};
|
||||
margin-top: 10px;
|
||||
line-height: 1.5;
|
||||
letter-spacing: -0.003em;
|
||||
}
|
||||
|
||||
/* Validation styles */
|
||||
:host([validationState="invalid"]) .radio-circle {
|
||||
border-color: #e74c3c;
|
||||
border-color: ${cssManager.bdTheme('hsl(0 72.2% 50.6%)', 'hsl(0 62.8% 30.6%)')};
|
||||
}
|
||||
|
||||
:host([validationState="invalid"]) .radio-option.selected .radio-circle {
|
||||
border-color: ${cssManager.bdTheme('hsl(0 72.2% 50.6%)', 'hsl(0 62.8% 30.6%)')};
|
||||
background: ${cssManager.bdTheme('hsl(0 72.2% 50.6%)', 'hsl(0 62.8% 30.6%)')};
|
||||
}
|
||||
|
||||
:host([validationState="valid"]) .radio-option.selected .radio-circle {
|
||||
border-color: #27ae60;
|
||||
background: #27ae60;
|
||||
border-color: ${cssManager.bdTheme('hsl(142.1 70.6% 45.3%)', 'hsl(142.1 76.2% 36.3%)')};
|
||||
background: ${cssManager.bdTheme('hsl(142.1 70.6% 45.3%)', 'hsl(142.1 76.2% 36.3%)')};
|
||||
}
|
||||
|
||||
:host([validationState="warn"]) .radio-option.selected .radio-circle {
|
||||
border-color: #f39c12;
|
||||
background: #f39c12;
|
||||
border-color: ${cssManager.bdTheme('hsl(45.4 93.4% 47.5%)', 'hsl(45.4 93.4% 47.5%)')};
|
||||
background: ${cssManager.bdTheme('hsl(45.4 93.4% 47.5%)', 'hsl(45.4 93.4% 47.5%)')};
|
||||
}
|
||||
|
||||
/* Override base grid layout for radiogroup to prevent large gaps */
|
||||
@ -212,8 +238,15 @@ export class DeesInputRadiogroup extends DeesInputBase<string | object> {
|
||||
<div
|
||||
class="radio-option ${isSelected ? 'selected' : ''}"
|
||||
@click="${() => this.selectOption(optionKey)}"
|
||||
@keydown="${(e: KeyboardEvent) => this.handleKeydown(e, optionKey)}"
|
||||
>
|
||||
<div class="radio-circle"></div>
|
||||
<div
|
||||
class="radio-circle"
|
||||
tabindex="${this.disabled ? '-1' : '0'}"
|
||||
role="radio"
|
||||
aria-checked="${isSelected}"
|
||||
aria-label="${optionLabel}"
|
||||
></div>
|
||||
<div class="radio-label">${optionLabel}</div>
|
||||
</div>
|
||||
`;
|
||||
@ -292,4 +325,33 @@ export class DeesInputRadiogroup extends DeesInputBase<string | object> {
|
||||
this.selectedOption = this.getOptionKey(firstOption);
|
||||
}
|
||||
}
|
||||
|
||||
private handleKeydown(event: KeyboardEvent, optionKey: string) {
|
||||
if (this.disabled) return;
|
||||
|
||||
if (event.key === ' ' || event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
this.selectOption(optionKey);
|
||||
} else if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {
|
||||
event.preventDefault();
|
||||
this.focusNextOption();
|
||||
} else if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
|
||||
event.preventDefault();
|
||||
this.focusPreviousOption();
|
||||
}
|
||||
}
|
||||
|
||||
private focusNextOption() {
|
||||
const radioCircles = Array.from(this.shadowRoot.querySelectorAll('.radio-circle'));
|
||||
const currentIndex = radioCircles.findIndex(el => el === this.shadowRoot.activeElement);
|
||||
const nextIndex = (currentIndex + 1) % radioCircles.length;
|
||||
(radioCircles[nextIndex] as HTMLElement).focus();
|
||||
}
|
||||
|
||||
private focusPreviousOption() {
|
||||
const radioCircles = Array.from(this.shadowRoot.querySelectorAll('.radio-circle'));
|
||||
const currentIndex = radioCircles.findIndex(el => el === this.shadowRoot.activeElement);
|
||||
const prevIndex = currentIndex <= 0 ? radioCircles.length - 1 : currentIndex - 1;
|
||||
(radioCircles[prevIndex] as HTMLElement).focus();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user