feat(catalog): add admin dashboard components
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
import { DeesElement, html, property, customElement, css, type TemplateResult } from '@design.estate/dees-element';
|
||||
import { idpElementStyles } from './tokens.js';
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'idp-checkbox': IdpCheckbox;
|
||||
}
|
||||
}
|
||||
|
||||
@customElement('idp-checkbox')
|
||||
export class IdpCheckbox extends DeesElement {
|
||||
public static demo = () => html`<idp-checkbox label="I agree to the terms" required></idp-checkbox>`;
|
||||
public static demoGroups = ['idp.global v3 primitives'];
|
||||
|
||||
@property({ type: String })
|
||||
public accessor label = '';
|
||||
|
||||
@property({ type: String })
|
||||
public accessor name = '';
|
||||
|
||||
@property({ type: String })
|
||||
public accessor key = '';
|
||||
|
||||
@property({ type: String })
|
||||
public accessor value = 'on';
|
||||
|
||||
@property({ type: String })
|
||||
public accessor hint = '';
|
||||
|
||||
@property({ type: String })
|
||||
public accessor error = '';
|
||||
|
||||
@property({ type: Boolean, reflect: true })
|
||||
public accessor checked = false;
|
||||
|
||||
@property({ type: Boolean, reflect: true })
|
||||
public accessor required = false;
|
||||
|
||||
@property({ type: Boolean, reflect: true })
|
||||
public accessor disabled = false;
|
||||
|
||||
public static styles = [
|
||||
...idpElementStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
label {
|
||||
display: grid;
|
||||
grid-template-columns: 18px 1fr;
|
||||
gap: 10px;
|
||||
align-items: start;
|
||||
color: var(--idp-fg);
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
cursor: pointer;
|
||||
}
|
||||
input {
|
||||
appearance: none;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin: 0;
|
||||
border: 1px solid var(--idp-border);
|
||||
border-radius: 5px;
|
||||
background: var(--idp-card);
|
||||
cursor: pointer;
|
||||
transition: background 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
|
||||
}
|
||||
input:checked {
|
||||
border-color: var(--idp-accent);
|
||||
background: var(--idp-accent);
|
||||
box-shadow: inset 0 0 0 3px var(--idp-card);
|
||||
}
|
||||
input:focus-visible {
|
||||
outline: 2px solid color-mix(in srgb, var(--idp-accent), transparent 68%);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
input[aria-invalid='true'] {
|
||||
border-color: var(--idp-destructive);
|
||||
}
|
||||
input:disabled,
|
||||
:host([disabled]) label {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.55;
|
||||
}
|
||||
.copy {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
}
|
||||
.hint,
|
||||
.error {
|
||||
color: var(--idp-muted-fg);
|
||||
font-size: 12px;
|
||||
}
|
||||
.error {
|
||||
color: var(--idp-destructive);
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
public validate() {
|
||||
if (this.required && !this.checked) {
|
||||
this.error = `${this.label || this.name || 'This field'} is required.`;
|
||||
return false;
|
||||
}
|
||||
|
||||
this.error = '';
|
||||
return true;
|
||||
}
|
||||
|
||||
private handleChange(eventArg: Event) {
|
||||
this.checked = (eventArg.target as HTMLInputElement).checked;
|
||||
if (this.error) {
|
||||
this.validate();
|
||||
}
|
||||
this.dispatchEvent(new CustomEvent('idp-checkbox-change', {
|
||||
detail: { name: this.name || this.key, key: this.key || this.name, checked: this.checked, value: this.value },
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
}));
|
||||
}
|
||||
|
||||
public render(): TemplateResult {
|
||||
return html`
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name=${this.name || this.key}
|
||||
value=${this.value}
|
||||
?checked=${this.checked}
|
||||
?required=${this.required}
|
||||
?disabled=${this.disabled}
|
||||
aria-invalid=${this.error ? 'true' : 'false'}
|
||||
@change=${this.handleChange}
|
||||
/>
|
||||
<span class="copy">
|
||||
<span>${this.label}</span>
|
||||
${this.error ? html`<span class="error">${this.error}</span>` : this.hint ? html`<span class="hint">${this.hint}</span>` : html``}
|
||||
</span>
|
||||
</label>
|
||||
`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user