feat: Reinitialize frontend with SvelteKit and TypeScript

- Delete old Vite+Svelte frontend
- Initialize new SvelteKit project with TypeScript
- Configure Tailwind CSS v4 + DaisyUI
- Implement JWT authentication with auto-refresh
- Create login page with form validation (Zod)
- Add protected route guards
- Update Docker configuration for single-stage build
- Add E2E tests with Playwright (6/11 passing)
- Fix Svelte 5 reactivity with $state() runes

Known issues:
- 5 E2E tests failing (timing/async issues)
- Token refresh implementation needs debugging
- Validation error display timing
This commit is contained in:
2026-02-17 16:19:59 -05:00
parent 54df6018f5
commit de2d83092e
28274 changed files with 3816354 additions and 90 deletions

View File

@@ -0,0 +1,319 @@
import Event from '../../event/Event.js';
import * as PropertySymbol from '../../PropertySymbol.js';
import HTMLElement from '../html-element/HTMLElement.js';
import HTMLFormElement from '../html-form-element/HTMLFormElement.js';
import HTMLInputElementSelectionModeEnum from '../html-input-element/HTMLInputElementSelectionModeEnum.js';
import ValidityState from '../../validity-state/ValidityState.js';
import HTMLLabelElement from '../html-label-element/HTMLLabelElement.js';
import NodeList from '../node/NodeList.js';
/**
* HTML Text Area Element.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLTextAreaElement.
*/
export default class HTMLTextAreaElement extends HTMLElement {
#private;
cloneNode: (deep?: boolean) => HTMLTextAreaElement;
readonly type = "textarea";
[PropertySymbol.validationMessage]: string;
[PropertySymbol.validity]: ValidityState;
[PropertySymbol.value]: any;
[PropertySymbol.textAreaNode]: this;
[PropertySymbol.formNode]: HTMLFormElement | null;
get oninput(): ((event: Event) => void) | null;
set oninput(value: ((event: Event) => void) | null);
get onselectionchange(): ((event: Event) => void) | null;
set onselectionchange(value: ((event: Event) => void) | null);
/**
* Returns validation message.
*
* @returns Validation message.
*/
get validationMessage(): string;
/**
* Returns validity.
*
* @returns Validity.
*/
get validity(): ValidityState;
/**
* Returns the default value.
*
* @returns Default value.
*/
get defaultValue(): string;
/**
* Sets the default value.
*
* @param defaultValue Default value.
*/
set defaultValue(defaultValue: string);
/**
* Returns minlength.
*
* @returns Min length.
*/
get minLength(): number;
/**
* Sets minlength.
*
* @param minLength Min length.
*/
set minLength(minlength: number);
/**
* Returns maxlength.
*
* @returns Max length.
*/
get maxLength(): number;
/**
* Sets maxlength.
*
* @param maxlength Max length.
*/
set maxLength(maxLength: number);
/**
* Returns name.
*
* @returns Name.
*/
get name(): string;
/**
* Sets name.
*
* @param name Name.
*/
set name(name: string);
/**
* Returns placeholder.
*
* @returns Placeholder.
*/
get placeholder(): string;
/**
* Sets placeholder.
*
* @param placeholder Placeholder.
*/
set placeholder(placeholder: string);
/**
* Returns inputmode.
*
* @returns Inputmode.
*/
get inputMode(): string;
/**
* Sets inputmode.
*
* @param inputmode Inputmode.
*/
set inputMode(inputmode: string);
/**
* Returns cols.
*
* @returns Cols.
*/
get cols(): string;
/**
* Sets cols.
*
* @param cols Cols.
*/
set cols(cols: string);
/**
* Returns rows.
*
* @returns Rows.
*/
get rows(): string;
/**
* Sets rows.
*
* @param rows Rows.
*/
set rows(rows: string);
/**
* Returns autocomplete.
*
* @returns Autocomplete.
*/
get autocomplete(): string;
/**
* Sets autocomplete.
*
* @param autocomplete Autocomplete.
*/
set autocomplete(autocomplete: string);
/**
* Returns readOnly.
*
* @returns ReadOnly.
*/
get readOnly(): boolean;
/**
* Sets readOnly.
*
* @param readOnly ReadOnly.
*/
set readOnly(readOnly: boolean);
/**
* Returns disabled.
*
* @returns Disabled.
*/
get disabled(): boolean;
/**
* Sets disabled.
*
* @param disabled Disabled.
*/
set disabled(disabled: boolean);
/**
* Returns autofocus.
*
* @returns Autofocus.
*/
get autofocus(): boolean;
/**
* Sets autofocus.
*
* @param autofocus Autofocus.
*/
set autofocus(autofocus: boolean);
/**
* Returns required.
*
* @returns Required.
*/
get required(): boolean;
/**
* Sets required.
*
* @param required Required.
*/
set required(required: boolean);
/**
* Returns value.
*
* @returns Value.
*/
get value(): string;
/**
* Sets value.
*
* @param value Value.
*/
set value(value: string);
/**
* Returns selection start.
*
* @returns Selection start.
*/
get selectionStart(): number;
/**
* Sets selection start.
*
* @param start Start.
*/
set selectionStart(start: number);
/**
* Returns selection end.
*
* @returns Selection end.
*/
get selectionEnd(): number;
/**
* Sets selection end.
*
* @param end End.
*/
set selectionEnd(end: number);
/**
* Returns selection direction.
*
* @returns Selection direction.
*/
get selectionDirection(): string;
/**
* Sets selection direction.
*
* @param direction Direction.
*/
set selectionDirection(direction: string);
/**
* Returns the parent form element.
*
* @returns Form.
*/
get form(): HTMLFormElement;
/**
* Returns text length.
*
* @param Text Length.
*/
get textLength(): number;
/**
* Returns the associated label elements.
*
* @returns Label elements.
*/
get labels(): NodeList<HTMLLabelElement>;
/**
* @override
*/
get tabIndex(): number;
/**
* @override
*/
set tabIndex(tabIndex: number);
/**
* Selects the text.
*/
select(): void;
/**
* Set selection range.
*
* @param start Start.
* @param end End.
* @param [direction="none"] Direction.
*/
setSelectionRange(start: number, end: number, direction?: string): void;
/**
* Set range text.
*
* @param replacement Replacement.
* @param [start] Start.
* @param [end] End.
* @param [direction] Direction.
* @param selectionMode
*/
setRangeText(replacement: string, start?: number, end?: number, selectionMode?: HTMLInputElementSelectionModeEnum): void;
/**
* Sets validation message.
*
* @param message Message.
*/
setCustomValidity(message: string): void;
/**
* Checks validity.
*
* @returns "true" if the field is valid.
*/
checkValidity(): boolean;
/**
* Reports validity.
*
* @returns "true" if the field is valid.
*/
reportValidity(): boolean;
/**
* @override
*/
[PropertySymbol.cloneNode](deep?: boolean): HTMLTextAreaElement;
/**
* Resets selection.
*/
[PropertySymbol.resetSelection](): void;
}
//# sourceMappingURL=HTMLTextAreaElement.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"HTMLTextAreaElement.d.ts","sourceRoot":"","sources":["../../../src/nodes/html-text-area-element/HTMLTextAreaElement.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,552 @@
import Event from '../../event/Event.js';
import * as PropertySymbol from '../../PropertySymbol.js';
import DOMExceptionNameEnum from '../../exception/DOMExceptionNameEnum.js';
import HTMLElement from '../html-element/HTMLElement.js';
import HTMLInputElementSelectionDirectionEnum from '../html-input-element/HTMLInputElementSelectionDirectionEnum.js';
import HTMLInputElementSelectionModeEnum from '../html-input-element/HTMLInputElementSelectionModeEnum.js';
import ValidityState from '../../validity-state/ValidityState.js';
import HTMLLabelElementUtility from '../html-label-element/HTMLLabelElementUtility.js';
import ElementEventAttributeUtility from '../element/ElementEventAttributeUtility.js';
/**
* HTML Text Area Element.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLTextAreaElement.
*/
export default class HTMLTextAreaElement extends HTMLElement {
type = 'textarea';
// Internal properties
[PropertySymbol.validationMessage] = '';
[PropertySymbol.validity] = new ValidityState(this);
[PropertySymbol.value] = null;
[PropertySymbol.textAreaNode] = this;
[PropertySymbol.formNode] = null;
// Private properties
#selectionStart = null;
#selectionEnd = null;
#selectionDirection = HTMLInputElementSelectionDirectionEnum.none;
// Events
/* eslint-disable jsdoc/require-jsdoc */
get oninput() {
return ElementEventAttributeUtility.getEventListener(this, 'oninput');
}
set oninput(value) {
this[PropertySymbol.propertyEventListeners].set('oninput', value);
}
get onselectionchange() {
return ElementEventAttributeUtility.getEventListener(this, 'onselectionchange');
}
set onselectionchange(value) {
this[PropertySymbol.propertyEventListeners].set('onselectionchange', value);
}
/* eslint-enable jsdoc/require-jsdoc */
/**
* Returns validation message.
*
* @returns Validation message.
*/
get validationMessage() {
return this[PropertySymbol.validationMessage];
}
/**
* Returns validity.
*
* @returns Validity.
*/
get validity() {
return this[PropertySymbol.validity];
}
/**
* Returns the default value.
*
* @returns Default value.
*/
get defaultValue() {
return this.textContent;
}
/**
* Sets the default value.
*
* @param defaultValue Default value.
*/
set defaultValue(defaultValue) {
this.textContent = defaultValue;
}
/**
* Returns minlength.
*
* @returns Min length.
*/
get minLength() {
const minLength = this.getAttribute('minlength');
if (minLength !== null) {
return parseInt(minLength);
}
return -1;
}
/**
* Sets minlength.
*
* @param minLength Min length.
*/
set minLength(minlength) {
this.setAttribute('minlength', String(minlength));
}
/**
* Returns maxlength.
*
* @returns Max length.
*/
get maxLength() {
const maxLength = this.getAttribute('maxlength');
if (maxLength !== null) {
return parseInt(maxLength);
}
return -1;
}
/**
* Sets maxlength.
*
* @param maxlength Max length.
*/
set maxLength(maxLength) {
this.setAttribute('maxlength', String(maxLength));
}
/**
* Returns name.
*
* @returns Name.
*/
get name() {
return this.getAttribute('name') || '';
}
/**
* Sets name.
*
* @param name Name.
*/
set name(name) {
this.setAttribute('name', name);
}
/**
* Returns placeholder.
*
* @returns Placeholder.
*/
get placeholder() {
return this.getAttribute('placeholder') || '';
}
/**
* Sets placeholder.
*
* @param placeholder Placeholder.
*/
set placeholder(placeholder) {
this.setAttribute('placeholder', placeholder);
}
/**
* Returns inputmode.
*
* @returns Inputmode.
*/
get inputMode() {
return this.getAttribute('inputmode') || '';
}
/**
* Sets inputmode.
*
* @param inputmode Inputmode.
*/
set inputMode(inputmode) {
this.setAttribute('inputmode', inputmode);
}
/**
* Returns cols.
*
* @returns Cols.
*/
get cols() {
return this.getAttribute('cols') || '';
}
/**
* Sets cols.
*
* @param cols Cols.
*/
set cols(cols) {
this.setAttribute('cols', cols);
}
/**
* Returns rows.
*
* @returns Rows.
*/
get rows() {
return this.getAttribute('rows') || '';
}
/**
* Sets rows.
*
* @param rows Rows.
*/
set rows(rows) {
this.setAttribute('rows', rows);
}
/**
* Returns autocomplete.
*
* @returns Autocomplete.
*/
get autocomplete() {
return this.getAttribute('autocomplete') || '';
}
/**
* Sets autocomplete.
*
* @param autocomplete Autocomplete.
*/
set autocomplete(autocomplete) {
this.setAttribute('autocomplete', autocomplete);
}
/**
* Returns readOnly.
*
* @returns ReadOnly.
*/
get readOnly() {
return this.getAttribute('readonly') !== null;
}
/**
* Sets readOnly.
*
* @param readOnly ReadOnly.
*/
set readOnly(readOnly) {
if (!readOnly) {
this.removeAttribute('readonly');
}
else {
this.setAttribute('readonly', '');
}
}
/**
* Returns disabled.
*
* @returns Disabled.
*/
get disabled() {
return this.getAttribute('disabled') !== null;
}
/**
* Sets disabled.
*
* @param disabled Disabled.
*/
set disabled(disabled) {
if (!disabled) {
this.removeAttribute('disabled');
}
else {
this.setAttribute('disabled', '');
}
}
/**
* Returns autofocus.
*
* @returns Autofocus.
*/
get autofocus() {
return this.getAttribute('autofocus') !== null;
}
/**
* Sets autofocus.
*
* @param autofocus Autofocus.
*/
set autofocus(autofocus) {
if (!autofocus) {
this.removeAttribute('autofocus');
}
else {
this.setAttribute('autofocus', '');
}
}
/**
* Returns required.
*
* @returns Required.
*/
get required() {
return this.getAttribute('required') !== null;
}
/**
* Sets required.
*
* @param required Required.
*/
set required(required) {
if (!required) {
this.removeAttribute('required');
}
else {
this.setAttribute('required', '');
}
}
/**
* Returns value.
*
* @returns Value.
*/
get value() {
if (this[PropertySymbol.value] === null) {
return this.textContent;
}
return this[PropertySymbol.value];
}
/**
* Sets value.
*
* @param value Value.
*/
set value(value) {
const oldValue = this[PropertySymbol.value];
this[PropertySymbol.value] = value;
if (oldValue !== this[PropertySymbol.value]) {
this.#selectionStart = this[PropertySymbol.value].length;
this.#selectionEnd = this[PropertySymbol.value].length;
this.#selectionDirection = HTMLInputElementSelectionDirectionEnum.none;
}
}
/**
* Returns selection start.
*
* @returns Selection start.
*/
get selectionStart() {
if (this.#selectionStart === null) {
return this.value.length;
}
return this.#selectionStart;
}
/**
* Sets selection start.
*
* @param start Start.
*/
set selectionStart(start) {
this.setSelectionRange(start, Math.max(start, this.selectionEnd), this.#selectionDirection);
}
/**
* Returns selection end.
*
* @returns Selection end.
*/
get selectionEnd() {
if (this.#selectionEnd === null) {
return this.value.length;
}
return this.#selectionEnd;
}
/**
* Sets selection end.
*
* @param end End.
*/
set selectionEnd(end) {
this.setSelectionRange(this.selectionStart, end, this.#selectionDirection);
}
/**
* Returns selection direction.
*
* @returns Selection direction.
*/
get selectionDirection() {
return this.#selectionDirection;
}
/**
* Sets selection direction.
*
* @param direction Direction.
*/
set selectionDirection(direction) {
this.setSelectionRange(this.selectionStart, this.selectionEnd, direction);
}
/**
* Returns the parent form element.
*
* @returns Form.
*/
get form() {
if (this[PropertySymbol.formNode]) {
return this[PropertySymbol.formNode];
}
const id = this.getAttribute('form');
if (!id || !this[PropertySymbol.isConnected]) {
return null;
}
return this[PropertySymbol.ownerDocument].getElementById(id);
}
/**
* Returns text length.
*
* @param Text Length.
*/
get textLength() {
return this.value.length;
}
/**
* Returns the associated label elements.
*
* @returns Label elements.
*/
get labels() {
return HTMLLabelElementUtility.getAssociatedLabelElements(this);
}
/**
* @override
*/
get tabIndex() {
const tabIndex = this.getAttribute('tabindex');
if (tabIndex !== null) {
const parsed = Number(tabIndex);
return isNaN(parsed) ? 0 : parsed;
}
return 0;
}
/**
* @override
*/
set tabIndex(tabIndex) {
super.tabIndex = tabIndex;
}
/**
* Selects the text.
*/
select() {
this.#selectionStart = 0;
this.#selectionEnd = this.value.length;
this.#selectionDirection = HTMLInputElementSelectionDirectionEnum.none;
this.dispatchEvent(new Event('select', { bubbles: true, cancelable: false }));
}
/**
* Set selection range.
*
* @param start Start.
* @param end End.
* @param [direction="none"] Direction.
*/
setSelectionRange(start, end, direction = 'none') {
this.#selectionEnd = Math.min(end, this.value.length);
this.#selectionStart = Math.min(start, this.selectionEnd);
this.#selectionDirection =
direction === HTMLInputElementSelectionDirectionEnum.forward ||
direction === HTMLInputElementSelectionDirectionEnum.backward
? direction
: HTMLInputElementSelectionDirectionEnum.none;
this.dispatchEvent(new Event('select', { bubbles: true, cancelable: false }));
}
/**
* Set range text.
*
* @param replacement Replacement.
* @param [start] Start.
* @param [end] End.
* @param [direction] Direction.
* @param selectionMode
*/
setRangeText(replacement, start = null, end = null, selectionMode = HTMLInputElementSelectionModeEnum.preserve) {
if (start === null) {
start = this.#selectionStart;
}
if (end === null) {
end = this.#selectionEnd;
}
if (start > end) {
throw new this[PropertySymbol.window].DOMException('The index is not in the allowed range.', DOMExceptionNameEnum.invalidStateError);
}
start = Math.min(start, this.value.length);
end = Math.min(end, this.value.length);
const val = this.value;
let selectionStart = this.#selectionStart;
let selectionEnd = this.#selectionEnd;
this.value = val.slice(0, start) + replacement + val.slice(end);
const newEnd = start + this.value.length;
switch (selectionMode) {
case HTMLInputElementSelectionModeEnum.select:
this.setSelectionRange(start, newEnd);
break;
case HTMLInputElementSelectionModeEnum.start:
this.setSelectionRange(start, start);
break;
case HTMLInputElementSelectionModeEnum.end:
this.setSelectionRange(newEnd, newEnd);
break;
default:
const delta = replacement.length - (end - start);
if (selectionStart > end) {
selectionStart += delta;
}
else if (selectionStart > start) {
selectionStart = start;
}
if (selectionEnd > end) {
selectionEnd += delta;
}
else if (selectionEnd > start) {
selectionEnd = newEnd;
}
this.setSelectionRange(selectionStart, selectionEnd);
break;
}
}
/**
* Sets validation message.
*
* @param message Message.
*/
setCustomValidity(message) {
this[PropertySymbol.validationMessage] = String(message);
}
/**
* Checks validity.
*
* @returns "true" if the field is valid.
*/
checkValidity() {
const valid = this.disabled || this.readOnly || this[PropertySymbol.validity].valid;
if (!valid) {
this.dispatchEvent(new Event('invalid', { bubbles: true, cancelable: true }));
}
return valid;
}
/**
* Reports validity.
*
* @returns "true" if the field is valid.
*/
reportValidity() {
return this.checkValidity();
}
/**
* @override
*/
[PropertySymbol.cloneNode](deep = false) {
const clone = super[PropertySymbol.cloneNode](deep);
clone[PropertySymbol.value] = this[PropertySymbol.value];
clone.#selectionStart = this.#selectionStart;
clone.#selectionEnd = this.#selectionEnd;
clone.#selectionDirection = this.#selectionDirection;
return clone;
}
/**
* Resets selection.
*/
[PropertySymbol.resetSelection]() {
if (this[PropertySymbol.value] === null) {
this.#selectionStart = null;
this.#selectionEnd = null;
this.#selectionDirection = HTMLInputElementSelectionDirectionEnum.none;
}
}
}
//# sourceMappingURL=HTMLTextAreaElement.js.map

File diff suppressed because one or more lines are too long