feat(dross): avatar component (soft-eye / wisp / motes)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
20
public/components/dross_avatar.js
Normal file
20
public/components/dross_avatar.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// public/components/dross_avatar.js
|
||||
import { el } from '../dom.js';
|
||||
|
||||
// Returns a .dross-orb element rendering the chosen avatar. Colours come from
|
||||
// CSS vars (--dross*), set on the element by the caller for per-user accent.
|
||||
export function drossAvatar(variant = 'soft-eye', size = 60) {
|
||||
let inner;
|
||||
if (variant === 'wisp') {
|
||||
inner = [el('div', { class: 'b-core' }), el('div', { class: 'b-bright' })];
|
||||
} else if (variant === 'motes') {
|
||||
inner = [
|
||||
el('div', { class: 'd-ring' }, el('div', { class: 'd-mote' })),
|
||||
el('div', { class: 'd-ring r2' }, el('div', { class: 'd-mote' })),
|
||||
el('div', { class: 'd-core' })
|
||||
];
|
||||
} else { // soft-eye (default)
|
||||
inner = [el('div', { class: 'av-eye' }, el('div', { class: 'av-pupil' }))];
|
||||
}
|
||||
return el('div', { class: 'dross-orb', style: { width: size + 'px', height: size + 'px' } }, ...inner);
|
||||
}
|
||||
21
tests/views/dross_avatar.test.js
Normal file
21
tests/views/dross_avatar.test.js
Normal file
@@ -0,0 +1,21 @@
|
||||
// @vitest-environment jsdom
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { drossAvatar } from '../../public/components/dross_avatar.js';
|
||||
|
||||
describe('drossAvatar', () => {
|
||||
it('renders the requested variant class', () => {
|
||||
const eye = drossAvatar('soft-eye', 60);
|
||||
expect(eye.classList.contains('dross-orb')).toBe(true);
|
||||
expect(eye.querySelector('.av-eye')).toBeTruthy();
|
||||
expect(drossAvatar('wisp', 30).querySelector('.b-core')).toBeTruthy();
|
||||
expect(drossAvatar('motes', 30).querySelector('.d-core')).toBeTruthy();
|
||||
});
|
||||
it('falls back to soft-eye for unknown variants', () => {
|
||||
expect(drossAvatar('bogus', 60).querySelector('.av-eye')).toBeTruthy();
|
||||
});
|
||||
it('sets the pixel size', () => {
|
||||
const a = drossAvatar('wisp', 42);
|
||||
expect(a.style.width).toBe('42px');
|
||||
expect(a.style.height).toBe('42px');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user