feat(form-inputs): Improve form input consistency and auto spacing across inputs and buttons
This commit is contained in:
@ -1,6 +1,42 @@
|
||||
import { html } from '@design.estate/dees-element';
|
||||
import { html, css } from '@design.estate/dees-element';
|
||||
|
||||
export const demoFunc = () => html`
|
||||
<style>
|
||||
${css`
|
||||
h3 {
|
||||
margin-top: 32px;
|
||||
margin-bottom: 16px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
h3 {
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
.form-demo {
|
||||
background: #f5f5f5;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.form-demo {
|
||||
background: #1a1a1a;
|
||||
}
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
|
||||
<h3>Button Types</h3>
|
||||
<dees-button>This is a slotted Text</dees-button>
|
||||
<p>
|
||||
<dees-button text="Highlighted: This text shows" type="highlighted">Highlighted</dees-button>
|
||||
@ -8,8 +44,34 @@ export const demoFunc = () => html`
|
||||
<p><dees-button type="discreet">This is discreete button</dees-button></p>
|
||||
<p><dees-button disabled>This is a disabled button</dees-button></p>
|
||||
<p><dees-button type="big">This is a slotted Text</dees-button></p>
|
||||
|
||||
<h3>Button States</h3>
|
||||
<p><dees-button status="normal">Normal Status</dees-button></p>
|
||||
<p><dees-button disabled status="pending">Pending Status</dees-button></p>
|
||||
<p><dees-button disabled status="success">Success Status</dees-button></p>
|
||||
<p><dees-button disabled status="error">Error Status</dees-button></p>
|
||||
|
||||
<h3>Buttons in Forms (Auto-spacing)</h3>
|
||||
<div class="form-demo">
|
||||
<dees-form>
|
||||
<dees-input-text label="Name" key="name"></dees-input-text>
|
||||
<dees-input-text label="Email" key="email"></dees-input-text>
|
||||
<dees-button>Save Draft</dees-button>
|
||||
<dees-button type="highlighted">Save and Continue</dees-button>
|
||||
<dees-form-submit>Submit Form</dees-form-submit>
|
||||
</dees-form>
|
||||
</div>
|
||||
|
||||
<h3>Buttons Outside Forms (No auto-spacing)</h3>
|
||||
<div class="button-group">
|
||||
<dees-button>Button 1</dees-button>
|
||||
<dees-button>Button 2</dees-button>
|
||||
<dees-button>Button 3</dees-button>
|
||||
</div>
|
||||
|
||||
<h3>Manual Form Spacing</h3>
|
||||
<div>
|
||||
<dees-button inside-form="true">Manually spaced button 1</dees-button>
|
||||
<dees-button inside-form="true">Manually spaced button 2</dees-button>
|
||||
</div>
|
||||
`;
|
||||
|
@ -55,10 +55,24 @@ export class DeesButton extends DeesElement {
|
||||
})
|
||||
public status: 'normal' | 'pending' | 'success' | 'error' = 'normal';
|
||||
|
||||
@property({
|
||||
type: Boolean,
|
||||
reflect: true
|
||||
})
|
||||
public insideForm: boolean = false;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public async connectedCallback() {
|
||||
await super.connectedCallback();
|
||||
// Auto-detect if inside a form
|
||||
if (!this.insideForm && this.closest('dees-form')) {
|
||||
this.insideForm = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static styles = [
|
||||
cssManager.defaultStyles,
|
||||
css`
|
||||
@ -71,6 +85,27 @@ export class DeesButton extends DeesElement {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Form spacing styles */
|
||||
/* Default vertical form layout */
|
||||
:host([inside-form]) {
|
||||
margin-bottom: 16px; /* Using standard 16px like inputs */
|
||||
}
|
||||
|
||||
:host([inside-form]:last-child) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Horizontal form layout - auto-detected via parent */
|
||||
dees-form[horizontal-layout] :host([inside-form]) {
|
||||
display: inline-block;
|
||||
margin-right: 16px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dees-form[horizontal-layout] :host([inside-form]:last-child) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.button {
|
||||
transition: all 0.1s , color 0s;
|
||||
position: relative;
|
||||
|
@ -15,234 +15,173 @@ export const demoFunc = () => html`
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.demo-section {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
dees-panel {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.demo-section {
|
||||
background: #1a1a1a;
|
||||
}
|
||||
}
|
||||
|
||||
.demo-section h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
color: #0069f2;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.demo-section p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.demo-section p {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.form-container {
|
||||
background: #fff;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.form-container {
|
||||
background: #222;
|
||||
border-color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.horizontal-form {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
dees-panel:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
|
||||
<div class="demo-container">
|
||||
<div class="demo-section">
|
||||
<h3>Complete Form Example</h3>
|
||||
<p>A comprehensive form with various input types, validation, and form submission handling</p>
|
||||
|
||||
<div class="form-container">
|
||||
<dees-form
|
||||
@formData=${async (eventArg) => {
|
||||
const form: DeesForm = eventArg.currentTarget;
|
||||
form.setStatus('pending', 'Processing...');
|
||||
await domtools.plugins.smartdelay.delayFor(2000);
|
||||
form.setStatus('success', 'Form submitted successfully!');
|
||||
await domtools.plugins.smartdelay.delayFor(2000);
|
||||
form.reset();
|
||||
}}
|
||||
>
|
||||
<dees-input-text
|
||||
.required=${true}
|
||||
key="firstName"
|
||||
label="First Name"
|
||||
.description=${'Your given name'}
|
||||
></dees-input-text>
|
||||
|
||||
<dees-input-text
|
||||
.required=${true}
|
||||
key="lastName"
|
||||
label="Last Name"
|
||||
></dees-input-text>
|
||||
|
||||
<dees-input-text
|
||||
.required=${true}
|
||||
key="email"
|
||||
label="Email Address"
|
||||
.description=${'We will use this to contact you'}
|
||||
></dees-input-text>
|
||||
|
||||
<dees-input-dropdown
|
||||
.required=${true}
|
||||
key="country"
|
||||
.label=${'Country'}
|
||||
.options=${[
|
||||
{ option: 'United States', key: 'us' },
|
||||
{ option: 'Canada', key: 'ca' },
|
||||
{ option: 'Germany', key: 'de' },
|
||||
{ option: 'France', key: 'fr' },
|
||||
{ option: 'United Kingdom', key: 'uk' },
|
||||
]}
|
||||
></dees-input-dropdown>
|
||||
|
||||
<dees-input-text
|
||||
.required=${true}
|
||||
key="password"
|
||||
label="Password"
|
||||
isPasswordBool
|
||||
.description=${'Minimum 8 characters'}
|
||||
></dees-input-text>
|
||||
|
||||
<dees-input-checkbox
|
||||
.required=${true}
|
||||
key="terms"
|
||||
label="I agree to the Terms and Conditions"
|
||||
></dees-input-checkbox>
|
||||
|
||||
<dees-input-checkbox
|
||||
key="newsletter"
|
||||
label="Send me promotional emails"
|
||||
.value=${true}
|
||||
></dees-input-checkbox>
|
||||
|
||||
<dees-form-submit>Create Account</dees-form-submit>
|
||||
</dees-form>
|
||||
</div>
|
||||
</div>
|
||||
<dees-panel .heading="Complete Form Example" .description="A comprehensive form with various input types, validation, and form submission handling">
|
||||
<dees-form
|
||||
@formData=${async (eventArg) => {
|
||||
const form: DeesForm = eventArg.currentTarget;
|
||||
form.setStatus('pending', 'Processing...');
|
||||
await domtools.plugins.smartdelay.delayFor(2000);
|
||||
form.setStatus('success', 'Form submitted successfully!');
|
||||
await domtools.plugins.smartdelay.delayFor(2000);
|
||||
form.reset();
|
||||
}}
|
||||
>
|
||||
<dees-input-text
|
||||
.required=${true}
|
||||
key="firstName"
|
||||
label="First Name"
|
||||
.description=${'Your given name'}
|
||||
></dees-input-text>
|
||||
|
||||
<dees-input-text
|
||||
.required=${true}
|
||||
key="lastName"
|
||||
label="Last Name"
|
||||
></dees-input-text>
|
||||
|
||||
<dees-input-text
|
||||
.required=${true}
|
||||
key="email"
|
||||
label="Email Address"
|
||||
.description=${'We will use this to contact you'}
|
||||
></dees-input-text>
|
||||
|
||||
<dees-input-dropdown
|
||||
.required=${true}
|
||||
key="country"
|
||||
.label=${'Country'}
|
||||
.options=${[
|
||||
{ option: 'United States', key: 'us' },
|
||||
{ option: 'Canada', key: 'ca' },
|
||||
{ option: 'Germany', key: 'de' },
|
||||
{ option: 'France', key: 'fr' },
|
||||
{ option: 'United Kingdom', key: 'uk' },
|
||||
]}
|
||||
></dees-input-dropdown>
|
||||
|
||||
<dees-input-text
|
||||
.required=${true}
|
||||
key="password"
|
||||
label="Password"
|
||||
isPasswordBool
|
||||
.description=${'Minimum 8 characters'}
|
||||
></dees-input-text>
|
||||
|
||||
<dees-input-checkbox
|
||||
.required=${true}
|
||||
key="terms"
|
||||
label="I agree to the Terms and Conditions"
|
||||
></dees-input-checkbox>
|
||||
|
||||
<dees-input-checkbox
|
||||
key="newsletter"
|
||||
label="Send me promotional emails"
|
||||
.value=${true}
|
||||
></dees-input-checkbox>
|
||||
|
||||
<dees-form-submit>Create Account</dees-form-submit>
|
||||
</dees-form>
|
||||
</dees-panel>
|
||||
|
||||
<div class="demo-section">
|
||||
<h3>Horizontal Form Layout</h3>
|
||||
<p>Compact form with inputs arranged horizontally - perfect for filters and quick forms</p>
|
||||
|
||||
<div class="form-container">
|
||||
<dees-form horizontal-layout>
|
||||
<dees-input-text
|
||||
key="search"
|
||||
label="Search"
|
||||
></dees-input-text>
|
||||
|
||||
<dees-input-dropdown
|
||||
key="category"
|
||||
.label=${'Category'}
|
||||
.enableSearch=${false}
|
||||
.options=${[
|
||||
{ option: 'All', key: 'all' },
|
||||
{ option: 'Products', key: 'products' },
|
||||
{ option: 'Services', key: 'services' },
|
||||
{ option: 'Support', key: 'support' },
|
||||
]}
|
||||
></dees-input-dropdown>
|
||||
|
||||
<dees-input-dropdown
|
||||
key="sort"
|
||||
.label=${'Sort By'}
|
||||
.enableSearch=${false}
|
||||
.options=${[
|
||||
{ option: 'Newest', key: 'newest' },
|
||||
{ option: 'Popular', key: 'popular' },
|
||||
{ option: 'Price: Low to High', key: 'price_asc' },
|
||||
{ option: 'Price: High to Low', key: 'price_desc' },
|
||||
]}
|
||||
></dees-input-dropdown>
|
||||
|
||||
<dees-input-checkbox
|
||||
key="inStock"
|
||||
label="In Stock Only"
|
||||
.value=${true}
|
||||
></dees-input-checkbox>
|
||||
</dees-form>
|
||||
</div>
|
||||
</div>
|
||||
<dees-panel .heading="Horizontal Form Layout" .description="Compact form with inputs arranged horizontally - perfect for filters and quick forms">
|
||||
<dees-form horizontal-layout>
|
||||
<dees-input-text
|
||||
key="search"
|
||||
label="Search"
|
||||
></dees-input-text>
|
||||
|
||||
<dees-input-dropdown
|
||||
key="category"
|
||||
.label=${'Category'}
|
||||
.enableSearch=${false}
|
||||
.options=${[
|
||||
{ option: 'All', key: 'all' },
|
||||
{ option: 'Products', key: 'products' },
|
||||
{ option: 'Services', key: 'services' },
|
||||
{ option: 'Support', key: 'support' },
|
||||
]}
|
||||
></dees-input-dropdown>
|
||||
|
||||
<dees-input-dropdown
|
||||
key="sort"
|
||||
.label=${'Sort By'}
|
||||
.enableSearch=${false}
|
||||
.options=${[
|
||||
{ option: 'Newest', key: 'newest' },
|
||||
{ option: 'Popular', key: 'popular' },
|
||||
{ option: 'Price: Low to High', key: 'price_asc' },
|
||||
{ option: 'Price: High to Low', key: 'price_desc' },
|
||||
]}
|
||||
></dees-input-dropdown>
|
||||
|
||||
<dees-input-checkbox
|
||||
key="inStock"
|
||||
label="In Stock Only"
|
||||
.value=${true}
|
||||
></dees-input-checkbox>
|
||||
</dees-form>
|
||||
</dees-panel>
|
||||
|
||||
<div class="demo-section">
|
||||
<h3>Advanced Form Features</h3>
|
||||
<p>Form with specialized input types and complex validation</p>
|
||||
|
||||
<div class="form-container">
|
||||
<dees-form
|
||||
@formData=${async (eventArg) => {
|
||||
const form: DeesForm = eventArg.currentTarget;
|
||||
const data = eventArg.detail.data;
|
||||
console.log('Form data:', data);
|
||||
form.setStatus('success', 'Data logged to console!');
|
||||
}}
|
||||
>
|
||||
<dees-input-iban
|
||||
key="iban"
|
||||
label="IBAN"
|
||||
.required=${true}
|
||||
></dees-input-iban>
|
||||
|
||||
<dees-input-phone
|
||||
key="phone"
|
||||
label="Phone Number"
|
||||
.required=${true}
|
||||
></dees-input-phone>
|
||||
|
||||
<dees-input-multitoggle
|
||||
key="preferences"
|
||||
.label=${'Notification Preferences'}
|
||||
.options=${['Email', 'SMS', 'Push', 'In-App']}
|
||||
.selectedOption=${'Email'}
|
||||
></dees-input-multitoggle>
|
||||
|
||||
<dees-input-multiselect
|
||||
key="interests"
|
||||
.label=${'Areas of Interest'}
|
||||
.options=${[
|
||||
{ option: 'Technology', key: 'tech' },
|
||||
{ option: 'Design', key: 'design' },
|
||||
{ option: 'Business', key: 'business' },
|
||||
{ option: 'Marketing', key: 'marketing' },
|
||||
{ option: 'Sales', key: 'sales' },
|
||||
]}
|
||||
></dees-input-multiselect>
|
||||
|
||||
<dees-input-fileupload
|
||||
key="documents"
|
||||
.label=${'Upload Documents'}
|
||||
.description=${'PDF, DOC, or DOCX files up to 10MB'}
|
||||
></dees-input-fileupload>
|
||||
|
||||
<dees-form-submit>Submit Application</dees-form-submit>
|
||||
</dees-form>
|
||||
</div>
|
||||
</div>
|
||||
<dees-panel .heading="Advanced Form Features" .description="Form with specialized input types and complex validation">
|
||||
<dees-form
|
||||
@formData=${async (eventArg) => {
|
||||
const form: DeesForm = eventArg.currentTarget;
|
||||
const data = eventArg.detail.data;
|
||||
console.log('Form data:', data);
|
||||
form.setStatus('success', 'Data logged to console!');
|
||||
}}
|
||||
>
|
||||
<dees-input-iban
|
||||
key="iban"
|
||||
label="IBAN"
|
||||
.required=${true}
|
||||
></dees-input-iban>
|
||||
|
||||
<dees-input-phone
|
||||
key="phone"
|
||||
label="Phone Number"
|
||||
.required=${true}
|
||||
></dees-input-phone>
|
||||
|
||||
<dees-input-multitoggle
|
||||
key="preferences"
|
||||
.label=${'Notification Preferences'}
|
||||
.options=${['Email', 'SMS', 'Push', 'In-App']}
|
||||
.selectedOption=${'Email'}
|
||||
></dees-input-multitoggle>
|
||||
|
||||
<dees-input-multiselect
|
||||
key="interests"
|
||||
.label=${'Areas of Interest'}
|
||||
.options=${[
|
||||
{ option: 'Technology', key: 'tech' },
|
||||
{ option: 'Design', key: 'design' },
|
||||
{ option: 'Business', key: 'business' },
|
||||
{ option: 'Marketing', key: 'marketing' },
|
||||
{ option: 'Sales', key: 'sales' },
|
||||
]}
|
||||
></dees-input-multiselect>
|
||||
|
||||
<dees-input-fileupload
|
||||
key="documents"
|
||||
.label=${'Upload Documents'}
|
||||
.description=${'PDF, DOC, or DOCX files up to 10MB'}
|
||||
></dees-input-fileupload>
|
||||
|
||||
<dees-form-submit>Submit Application</dees-form-submit>
|
||||
</dees-form>
|
||||
</dees-panel>
|
||||
</div>
|
||||
</dees-demowrapper>
|
||||
`;
|
||||
`;
|
@ -132,12 +132,31 @@ export class DeesForm extends DeesElement {
|
||||
public async collectFormData() {
|
||||
const children = this.getFormElements();
|
||||
const valueObject: { [key: string]: string | number | boolean | any[] | File[] | { option: string; key: string; payload?: any } } = {};
|
||||
const radioGroups = new Map<string, DeesInputRadio[]>();
|
||||
|
||||
for (const child of children) {
|
||||
if (!child.key) {
|
||||
console.log(`form element with label "${child.label}" has no key. skipping.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle radio buttons specially
|
||||
if (child instanceof DeesInputRadio && child.name) {
|
||||
if (!radioGroups.has(child.name)) {
|
||||
radioGroups.set(child.name, []);
|
||||
}
|
||||
radioGroups.get(child.name).push(child);
|
||||
} else {
|
||||
valueObject[child.key] = child.value;
|
||||
}
|
||||
valueObject[child.key] = child.value;
|
||||
}
|
||||
|
||||
// Process radio groups - use the name as key and selected radio's key as value
|
||||
for (const [groupName, radios] of radioGroups) {
|
||||
const selectedRadio = radios.find(radio => radio.value === true);
|
||||
valueObject[groupName] = selectedRadio ? selectedRadio.key : null;
|
||||
}
|
||||
|
||||
return valueObject;
|
||||
}
|
||||
|
||||
|
@ -3,33 +3,7 @@ import '@design.estate/dees-wcctools/demotools';
|
||||
import type { DeesInputRadio } from './dees-input-radio.js';
|
||||
|
||||
export const demoFunc = () => html`
|
||||
<dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
|
||||
// Implement radio group behavior
|
||||
const radioGroups = new Map<string, DeesInputRadio[]>();
|
||||
|
||||
// Group radios by their container
|
||||
const radioContainers = elementArg.querySelectorAll('.radio-group');
|
||||
radioContainers.forEach((container) => {
|
||||
const radios = Array.from(container.querySelectorAll('dees-input-radio')) as DeesInputRadio[];
|
||||
const groupName = container.getAttribute('data-group') || 'default';
|
||||
radioGroups.set(groupName, radios);
|
||||
|
||||
// Add click handlers for radio group behavior
|
||||
radios.forEach((radio) => {
|
||||
radio.addEventListener('click', () => {
|
||||
if (!radio.disabled && !radio.value) {
|
||||
// Uncheck all other radios in the group
|
||||
radios.forEach((r) => {
|
||||
if (r !== radio) {
|
||||
r.value = false;
|
||||
}
|
||||
});
|
||||
radio.value = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}}>
|
||||
<dees-demowrapper>
|
||||
<style>
|
||||
${css`
|
||||
.demo-container {
|
||||
@ -121,37 +95,43 @@ export const demoFunc = () => html`
|
||||
<h3>Basic Radio Groups</h3>
|
||||
<p>Radio buttons for single-choice selections</p>
|
||||
|
||||
<div class="radio-group" data-group="plan">
|
||||
<div class="radio-group">
|
||||
<div class="radio-group-title">Select your subscription plan:</div>
|
||||
<dees-input-radio
|
||||
.label=${'Basic Plan - $9/month'}
|
||||
.value=${true}
|
||||
.key=${'plan-basic'}
|
||||
.name=${'plan'}
|
||||
></dees-input-radio>
|
||||
<dees-input-radio
|
||||
.label=${'Pro Plan - $29/month'}
|
||||
.key=${'plan-pro'}
|
||||
.name=${'plan'}
|
||||
></dees-input-radio>
|
||||
<dees-input-radio
|
||||
.label=${'Enterprise Plan - $99/month'}
|
||||
.key=${'plan-enterprise'}
|
||||
.name=${'plan'}
|
||||
></dees-input-radio>
|
||||
</div>
|
||||
|
||||
<div class="radio-group" data-group="priority">
|
||||
<div class="radio-group">
|
||||
<div class="radio-group-title">Task Priority:</div>
|
||||
<dees-input-radio
|
||||
.label=${'High Priority'}
|
||||
.key=${'priority-high'}
|
||||
.name=${'priority'}
|
||||
></dees-input-radio>
|
||||
<dees-input-radio
|
||||
.label=${'Medium Priority'}
|
||||
.value=${true}
|
||||
.key=${'priority-medium'}
|
||||
.name=${'priority'}
|
||||
></dees-input-radio>
|
||||
<dees-input-radio
|
||||
.label=${'Low Priority'}
|
||||
.key=${'priority-low'}
|
||||
.name=${'priority'}
|
||||
></dees-input-radio>
|
||||
</div>
|
||||
</div>
|
||||
@ -160,43 +140,49 @@ export const demoFunc = () => html`
|
||||
<h3>Horizontal Layout</h3>
|
||||
<p>Radio buttons arranged horizontally for yes/no questions</p>
|
||||
|
||||
<div class="radio-group" data-group="agreement" style="flex-direction: row;">
|
||||
<div class="radio-group" style="flex-direction: row;">
|
||||
<div style="margin-right: 16px;">Do you agree?</div>
|
||||
<dees-input-radio
|
||||
.label=${'Yes'}
|
||||
.layoutMode=${'horizontal'}
|
||||
.value=${true}
|
||||
.key=${'agree-yes'}
|
||||
.name=${'agreement'}
|
||||
></dees-input-radio>
|
||||
<dees-input-radio
|
||||
.label=${'No'}
|
||||
.layoutMode=${'horizontal'}
|
||||
.key=${'agree-no'}
|
||||
.name=${'agreement'}
|
||||
></dees-input-radio>
|
||||
<dees-input-radio
|
||||
.label=${'Maybe'}
|
||||
.layoutMode=${'horizontal'}
|
||||
.key=${'agree-maybe'}
|
||||
.name=${'agreement'}
|
||||
></dees-input-radio>
|
||||
</div>
|
||||
|
||||
<div class="radio-group" data-group="experience" style="flex-direction: row;">
|
||||
<div class="radio-group" style="flex-direction: row;">
|
||||
<div style="margin-right: 16px;">Experience Level:</div>
|
||||
<dees-input-radio
|
||||
.label=${'Beginner'}
|
||||
.layoutMode=${'horizontal'}
|
||||
.key=${'exp-beginner'}
|
||||
.name=${'experience'}
|
||||
></dees-input-radio>
|
||||
<dees-input-radio
|
||||
.label=${'Intermediate'}
|
||||
.layoutMode=${'horizontal'}
|
||||
.value=${true}
|
||||
.key=${'exp-intermediate'}
|
||||
.name=${'experience'}
|
||||
></dees-input-radio>
|
||||
<dees-input-radio
|
||||
.label=${'Expert'}
|
||||
.layoutMode=${'horizontal'}
|
||||
.key=${'exp-expert'}
|
||||
.name=${'experience'}
|
||||
></dees-input-radio>
|
||||
</div>
|
||||
</div>
|
||||
@ -206,22 +192,22 @@ export const demoFunc = () => html`
|
||||
<p>Multiple radio groups in a survey format</p>
|
||||
|
||||
<div class="grid-layout">
|
||||
<div class="radio-group" data-group="satisfaction">
|
||||
<div class="radio-group">
|
||||
<div class="radio-group-title">How satisfied are you?</div>
|
||||
<dees-input-radio .label=${'Very Satisfied'} .key=${'sat-very'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Satisfied'} .value=${true} .key=${'sat-normal'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Neutral'} .key=${'sat-neutral'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Dissatisfied'} .key=${'sat-dis'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Very Dissatisfied'} .key=${'sat-verydis'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Very Satisfied'} .key=${'sat-very'} .name=${'satisfaction'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Satisfied'} .value=${true} .key=${'sat-normal'} .name=${'satisfaction'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Neutral'} .key=${'sat-neutral'} .name=${'satisfaction'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Dissatisfied'} .key=${'sat-dis'} .name=${'satisfaction'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Very Dissatisfied'} .key=${'sat-verydis'} .name=${'satisfaction'}></dees-input-radio>
|
||||
</div>
|
||||
|
||||
<div class="radio-group" data-group="recommend">
|
||||
<div class="radio-group">
|
||||
<div class="radio-group-title">Would you recommend us?</div>
|
||||
<dees-input-radio .label=${'Definitely'} .key=${'rec-def'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Probably'} .value=${true} .key=${'rec-prob'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Not Sure'} .key=${'rec-unsure'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Probably Not'} .key=${'rec-probnot'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Definitely Not'} .key=${'rec-defnot'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Definitely'} .key=${'rec-def'} .name=${'recommend'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Probably'} .value=${true} .key=${'rec-prob'} .name=${'recommend'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Not Sure'} .key=${'rec-unsure'} .name=${'recommend'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Probably Not'} .key=${'rec-probnot'} .name=${'recommend'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Definitely Not'} .key=${'rec-defnot'} .name=${'recommend'}></dees-input-radio>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -230,26 +216,30 @@ export const demoFunc = () => html`
|
||||
<h3>States</h3>
|
||||
<p>Different radio button states</p>
|
||||
|
||||
<div class="radio-group" data-group="states">
|
||||
<div class="radio-group">
|
||||
<dees-input-radio
|
||||
.label=${'Normal Radio'}
|
||||
.key=${'state-normal'}
|
||||
.name=${'states'}
|
||||
></dees-input-radio>
|
||||
<dees-input-radio
|
||||
.label=${'Selected Radio'}
|
||||
.value=${true}
|
||||
.key=${'state-selected'}
|
||||
.name=${'states'}
|
||||
></dees-input-radio>
|
||||
<dees-input-radio
|
||||
.label=${'Disabled Unchecked'}
|
||||
.disabled=${true}
|
||||
.key=${'state-disabled1'}
|
||||
.name=${'states2'}
|
||||
></dees-input-radio>
|
||||
<dees-input-radio
|
||||
.label=${'Disabled Checked'}
|
||||
.disabled=${true}
|
||||
.value=${true}
|
||||
.key=${'state-disabled2'}
|
||||
.name=${'states2'}
|
||||
></dees-input-radio>
|
||||
</div>
|
||||
</div>
|
||||
@ -258,18 +248,18 @@ export const demoFunc = () => html`
|
||||
<h3>Settings Example</h3>
|
||||
<p>Common radio button patterns in settings</p>
|
||||
|
||||
<div class="radio-group" data-group="theme">
|
||||
<div class="radio-group">
|
||||
<div class="radio-group-title">Theme Preference:</div>
|
||||
<dees-input-radio .label=${'Light Theme'} .key=${'theme-light'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Dark Theme'} .value=${true} .key=${'theme-dark'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'System Default'} .key=${'theme-system'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Light Theme'} .key=${'theme-light'} .name=${'theme'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Dark Theme'} .value=${true} .key=${'theme-dark'} .name=${'theme'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'System Default'} .key=${'theme-system'} .name=${'theme'}></dees-input-radio>
|
||||
</div>
|
||||
|
||||
<div class="radio-group" data-group="notifications">
|
||||
<div class="radio-group">
|
||||
<div class="radio-group-title">Notification Frequency:</div>
|
||||
<dees-input-radio .label=${'All Notifications'} .key=${'notif-all'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Important Only'} .value=${true} .key=${'notif-important'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'None'} .key=${'notif-none'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'All Notifications'} .key=${'notif-all'} .name=${'notifications'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'Important Only'} .value=${true} .key=${'notif-important'} .name=${'notifications'}></dees-input-radio>
|
||||
<dees-input-radio .label=${'None'} .key=${'notif-none'} .name=${'notifications'}></dees-input-radio>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,6 +17,8 @@ export class DeesInputRadio extends DeesInputBase<DeesInputRadio> {
|
||||
@property()
|
||||
public value: boolean = false;
|
||||
|
||||
@property({ type: String })
|
||||
public name: string = '';
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@ -95,7 +97,27 @@ export class DeesInputRadio extends DeesInputBase<DeesInputRadio> {
|
||||
}
|
||||
|
||||
public async toggleSelected () {
|
||||
this.value = !this.value;
|
||||
// Radio buttons can only be selected, not deselected by clicking
|
||||
if (this.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If this radio has a name, find and deselect other radios in the same group
|
||||
if (this.name) {
|
||||
// Try to find a form container first, then fall back to document
|
||||
const container = this.closest('dees-form') ||
|
||||
this.closest('dees-demowrapper') ||
|
||||
this.closest('.radio-group')?.parentElement ||
|
||||
document;
|
||||
const allRadios = container.querySelectorAll(`dees-input-radio[name="${this.name}"]`);
|
||||
allRadios.forEach((radio: DeesInputRadio) => {
|
||||
if (radio !== this && radio.value) {
|
||||
radio.value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.value = true;
|
||||
this.dispatchEvent(new CustomEvent('newValue', {
|
||||
detail: this.value,
|
||||
bubbles: true
|
||||
|
@ -100,7 +100,8 @@ export class DeesInputText extends DeesInputBase {
|
||||
|
||||
input:focus {
|
||||
outline: none;
|
||||
border-bottom: 1px solid ${cssManager.bdTheme( colors.bright.blueActive, colors.dark.blueActive)};
|
||||
border-bottom: 1px solid
|
||||
${cssManager.bdTheme(colors.bright.blueActive, colors.dark.blueActive)};
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
@ -117,6 +118,7 @@ export class DeesInputText extends DeesInputBase {
|
||||
padding: 4px 0px;
|
||||
width: 40px;
|
||||
z-index: 3;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.showPassword:hover {
|
||||
@ -146,18 +148,20 @@ export class DeesInputText extends DeesInputBase {
|
||||
letter-spacing: ${this.isPasswordBool ? '1px' : 'normal'};
|
||||
color: ${this.goBright ? '#333' : '#ccc'};
|
||||
}
|
||||
${this.validationText ? css`
|
||||
.validationContainer {
|
||||
height: 22px;
|
||||
opacity: 1;
|
||||
}
|
||||
` : css`
|
||||
.validationContainer {
|
||||
height: 4px;
|
||||
padding: 2px !important;
|
||||
opacity: 0;
|
||||
}
|
||||
`}
|
||||
${this.validationText
|
||||
? css`
|
||||
.validationContainer {
|
||||
height: 22px;
|
||||
opacity: 1;
|
||||
}
|
||||
`
|
||||
: css`
|
||||
.validationContainer {
|
||||
height: 4px;
|
||||
padding: 2px !important;
|
||||
opacity: 0;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<div class="input-wrapper">
|
||||
<dees-label .label=${this.label} .description=${this.description}></dees-label>
|
||||
@ -168,9 +172,7 @@ export class DeesInputText extends DeesInputBase {
|
||||
@input="${this.updateValue}"
|
||||
.disabled=${this.disabled}
|
||||
/>
|
||||
<div class="validationContainer">
|
||||
${this.validationText}
|
||||
</div>
|
||||
<div class="validationContainer">${this.validationText}</div>
|
||||
${this.isPasswordBool
|
||||
? html`
|
||||
<div class="showPassword" @click=${this.togglePasswordView}>
|
||||
|
Reference in New Issue
Block a user