339 lines
12 KiB
TypeScript
339 lines
12 KiB
TypeScript
import { html, css, cssManager } from '@design.estate/dees-element';
|
|
import '@design.estate/dees-wcctools/demotools';
|
|
import './dees-panel.js';
|
|
import type { DeesInputText } from './dees-input-text.js';
|
|
|
|
export const demoFunc = () => html`
|
|
<style>
|
|
${css`
|
|
.demo-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 24px;
|
|
padding: 24px;
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
dees-panel {
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
dees-panel:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.horizontal-group {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.grid-layout {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 16px;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.grid-layout {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
|
|
.interactive-section {
|
|
background: ${cssManager.bdTheme('hsl(210 40% 96.1%)', 'hsl(215 20.2% 16.8%)')};
|
|
border-radius: 8px;
|
|
padding: 16px;
|
|
margin-top: 16px;
|
|
}
|
|
|
|
.output-text {
|
|
font-family: monospace;
|
|
font-size: 13px;
|
|
color: ${cssManager.bdTheme('hsl(215.3 25% 26.7%)', 'hsl(210 40% 80%)')};
|
|
padding: 8px;
|
|
background: ${cssManager.bdTheme('hsl(210 40% 98%)', 'hsl(215 20.2% 11.8%)')};
|
|
border-radius: 4px;
|
|
min-height: 24px;
|
|
}
|
|
`}
|
|
</style>
|
|
|
|
<div class="demo-container">
|
|
<dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
|
|
// Demonstrate basic text input functionality
|
|
const inputs = elementArg.querySelectorAll('dees-input-text');
|
|
|
|
inputs.forEach((input: DeesInputText) => {
|
|
input.addEventListener('changeSubject', (event: CustomEvent) => {
|
|
console.log(`Input "${input.label}" changed to:`, input.getValue());
|
|
});
|
|
|
|
input.addEventListener('blur', () => {
|
|
console.log(`Input "${input.label}" lost focus`);
|
|
});
|
|
});
|
|
|
|
// Show password visibility toggle
|
|
const passwordInput = elementArg.querySelector('dees-input-text[key="password"]') as DeesInputText;
|
|
if (passwordInput) {
|
|
console.log('Password input includes visibility toggle');
|
|
}
|
|
}}>
|
|
<dees-panel .title=${'Basic Text Inputs'} .subtitle=${'Standard text inputs with labels and descriptions'}>
|
|
<dees-input-text
|
|
.label=${'Username'}
|
|
.value=${'johndoe'}
|
|
.key=${'username'}
|
|
></dees-input-text>
|
|
|
|
<dees-input-text
|
|
.label=${'Email Address'}
|
|
.value=${'john@example.com'}
|
|
.description=${'We will never share your email with anyone'}
|
|
.key=${'email'}
|
|
></dees-input-text>
|
|
|
|
<dees-input-text
|
|
.label=${'Password'}
|
|
.isPasswordBool=${true}
|
|
.value=${'secret123'}
|
|
.key=${'password'}
|
|
></dees-input-text>
|
|
</dees-panel>
|
|
</dees-demowrapper>
|
|
|
|
<dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
|
|
// Demonstrate horizontal layout behavior
|
|
const horizontalInputs = elementArg.querySelectorAll('dees-input-text');
|
|
|
|
// Check that inputs are properly spaced horizontally
|
|
horizontalInputs.forEach((input: DeesInputText) => {
|
|
const computedStyle = window.getComputedStyle(input);
|
|
console.log(`Horizontal input "${input.label}" display:`, computedStyle.display);
|
|
});
|
|
|
|
// Track value changes
|
|
const firstNameInput = elementArg.querySelector('dees-input-text[key="firstName"]');
|
|
const lastNameInput = elementArg.querySelector('dees-input-text[key="lastName"]');
|
|
|
|
if (firstNameInput && lastNameInput) {
|
|
const updateFullName = () => {
|
|
const firstName = (firstNameInput as DeesInputText).getValue();
|
|
const lastName = (lastNameInput as DeesInputText).getValue();
|
|
console.log(`Full name: ${firstName} ${lastName}`);
|
|
};
|
|
|
|
firstNameInput.addEventListener('changeSubject', updateFullName);
|
|
lastNameInput.addEventListener('changeSubject', updateFullName);
|
|
}
|
|
}}>
|
|
<dees-panel .title=${'Horizontal Layout'} .subtitle=${'Multiple inputs arranged horizontally for compact forms'}>
|
|
<div class="horizontal-group">
|
|
<dees-input-text
|
|
.label=${'First Name'}
|
|
.value=${'John'}
|
|
.layoutMode=${'horizontal'}
|
|
.key=${'firstName'}
|
|
></dees-input-text>
|
|
|
|
<dees-input-text
|
|
.label=${'Last Name'}
|
|
.value=${'Doe'}
|
|
.layoutMode=${'horizontal'}
|
|
.key=${'lastName'}
|
|
></dees-input-text>
|
|
|
|
<dees-input-text
|
|
.label=${'Age'}
|
|
.value=${'28'}
|
|
.layoutMode=${'horizontal'}
|
|
.key=${'age'}
|
|
></dees-input-text>
|
|
</div>
|
|
</dees-panel>
|
|
</dees-demowrapper>
|
|
|
|
<dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
|
|
// Demonstrate different label positions
|
|
const inputs = elementArg.querySelectorAll('dees-input-text');
|
|
|
|
inputs.forEach((input: DeesInputText) => {
|
|
const position = input.labelPosition;
|
|
console.log(`Input "${input.label}" has label position: ${position}`);
|
|
});
|
|
|
|
// Show how label position affects layout
|
|
const leftLabelInputs = elementArg.querySelectorAll('dees-input-text[labelPosition="left"]');
|
|
if (leftLabelInputs.length > 0) {
|
|
console.log(`${leftLabelInputs.length} inputs have left-aligned labels for inline layout`);
|
|
}
|
|
}}>
|
|
<dees-panel .title=${'Label Positions'} .subtitle=${'Different label positioning options for various layouts'}>
|
|
<dees-input-text
|
|
.label=${'Label on Top (Default)'}
|
|
.value=${'Standard layout'}
|
|
.labelPosition=${'top'}
|
|
></dees-input-text>
|
|
|
|
<dees-input-text
|
|
.label=${'Label on Left'}
|
|
.value=${'Inline label'}
|
|
.labelPosition=${'left'}
|
|
></dees-input-text>
|
|
|
|
<div class="grid-layout">
|
|
<dees-input-text
|
|
.label=${'City'}
|
|
.value=${'New York'}
|
|
.labelPosition=${'left'}
|
|
></dees-input-text>
|
|
|
|
<dees-input-text
|
|
.label=${'ZIP Code'}
|
|
.value=${'10001'}
|
|
.labelPosition=${'left'}
|
|
></dees-input-text>
|
|
</div>
|
|
</dees-panel>
|
|
</dees-demowrapper>
|
|
|
|
<dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
|
|
// Demonstrate validation states
|
|
const requiredInput = elementArg.querySelector('dees-input-text[required]') as DeesInputText;
|
|
const disabledInput = elementArg.querySelector('dees-input-text[disabled]') as DeesInputText;
|
|
const errorInput = elementArg.querySelector('dees-input-text[validationState="invalid"]') as DeesInputText;
|
|
|
|
if (requiredInput) {
|
|
// Show validation on blur for empty required field
|
|
requiredInput.addEventListener('blur', () => {
|
|
if (!requiredInput.getValue()) {
|
|
console.log('Required field is empty!');
|
|
}
|
|
});
|
|
}
|
|
|
|
if (disabledInput) {
|
|
console.log('Disabled input cannot be edited');
|
|
}
|
|
|
|
if (errorInput) {
|
|
console.log('Error input shows validation message:', errorInput.validationText);
|
|
|
|
// Simulate fixing the error
|
|
errorInput.addEventListener('changeSubject', () => {
|
|
const value = errorInput.getValue();
|
|
if (value.includes('@') && value.includes('.')) {
|
|
errorInput.validationState = 'valid';
|
|
errorInput.validationText = '';
|
|
console.log('Email validation passed!');
|
|
}
|
|
});
|
|
}
|
|
}}>
|
|
<dees-panel .title=${'Validation & States'} .subtitle=${'Different validation states and input configurations'}>
|
|
<dees-input-text
|
|
.label=${'Required Field'}
|
|
.required=${true}
|
|
.key=${'requiredField'}
|
|
></dees-input-text>
|
|
|
|
<dees-input-text
|
|
.label=${'Disabled Field'}
|
|
.value=${'Cannot edit this'}
|
|
.disabled=${true}
|
|
></dees-input-text>
|
|
|
|
<dees-input-text
|
|
.label=${'Field with Error'}
|
|
.value=${'invalid@'}
|
|
.validationText=${'Please enter a valid email address'}
|
|
.validationState=${'invalid'}
|
|
></dees-input-text>
|
|
</dees-panel>
|
|
</dees-demowrapper>
|
|
|
|
<dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
|
|
// Track password visibility toggles
|
|
const passwordInputs = elementArg.querySelectorAll('dees-input-text[isPasswordBool]');
|
|
|
|
passwordInputs.forEach((input: DeesInputText) => {
|
|
// Monitor for toggle button clicks within shadow DOM
|
|
const checkToggle = () => {
|
|
const inputEl = input.shadowRoot?.querySelector('input');
|
|
if (inputEl) {
|
|
console.log(`Password field "${input.label}" type:`, inputEl.type);
|
|
}
|
|
};
|
|
|
|
// Use MutationObserver to detect changes
|
|
if (input.shadowRoot) {
|
|
const observer = new MutationObserver(checkToggle);
|
|
const inputEl = input.shadowRoot.querySelector('input');
|
|
if (inputEl) {
|
|
observer.observe(inputEl, { attributes: true, attributeFilter: ['type'] });
|
|
}
|
|
}
|
|
});
|
|
}}>
|
|
<dees-panel .title=${'Advanced Features'} .subtitle=${'Password visibility toggle and other advanced features'}>
|
|
<dees-input-text
|
|
.label=${'Password with Toggle'}
|
|
.isPasswordBool=${true}
|
|
.value=${'mySecurePassword123'}
|
|
.description=${'Click the eye icon to show/hide password'}
|
|
></dees-input-text>
|
|
|
|
<dees-input-text
|
|
.label=${'API Key'}
|
|
.isPasswordBool=${true}
|
|
.value=${'sk-1234567890abcdef'}
|
|
.description=${'Keep this key secure and never share it'}
|
|
></dees-input-text>
|
|
</dees-panel>
|
|
</dees-demowrapper>
|
|
|
|
<dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
|
|
// Set up interactive example
|
|
const dynamicInput = elementArg.querySelector('dees-input-text');
|
|
const output = elementArg.querySelector('#text-input-output');
|
|
|
|
if (dynamicInput && output) {
|
|
// Update output on every change
|
|
dynamicInput.addEventListener('changeSubject', (event: CustomEvent) => {
|
|
const value = (event.detail as DeesInputText).getValue();
|
|
output.textContent = `Current value: "${value}"`;
|
|
});
|
|
|
|
// Also track focus/blur events
|
|
dynamicInput.addEventListener('focus', () => {
|
|
console.log('Input focused');
|
|
});
|
|
|
|
dynamicInput.addEventListener('blur', () => {
|
|
console.log('Input blurred');
|
|
});
|
|
|
|
// Track keypress events
|
|
let keypressCount = 0;
|
|
dynamicInput.addEventListener('keydown', () => {
|
|
keypressCount++;
|
|
console.log(`Keypress count: ${keypressCount}`);
|
|
});
|
|
}
|
|
}}>
|
|
<dees-panel .title=${'Interactive Example'} .subtitle=${'Try typing in the inputs to see real-time value changes'}>
|
|
<dees-input-text
|
|
.label=${'Dynamic Input'}
|
|
.placeholder=${'Type something here...'}
|
|
></dees-input-text>
|
|
|
|
<div class="interactive-section">
|
|
<div id="text-input-output" class="output-text">Current value: ""</div>
|
|
</div>
|
|
</dees-panel>
|
|
</dees-demowrapper>
|
|
</div>
|
|
`; |