From 2d354ace552442acb3fc2f64a7ccd6f455e79f6e Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Sun, 5 Apr 2026 09:50:35 +0000 Subject: [PATCH] feat(dees-input-list): allow freeform entries alongside candidate suggestions in dees-input-list --- changelog.md | 7 ++++ ts_web/00_commitinfo_data.ts | 2 +- .../dees-input-list/dees-input-list.demo.ts | 20 ++++++++++- .../dees-input-list/dees-input-list.ts | 33 ++++++++++++++++++- 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index d9f5d9a..6ae3c9b 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2026-04-05 - 3.61.0 - feat(dees-input-list) +allow freeform entries alongside candidate suggestions in dees-input-list + +- adds an allowFreeform option so Enter can add values that do not exactly match the candidate list +- shows check and question-mark indicators to distinguish known candidates from custom freeform items +- updates the component demo with a freeform-plus-candidates example + ## 2026-04-05 - 3.60.0 - feat(dees-input-list) add candidate autocomplete with tab completion and payload retrieval diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index 0436c01..66789e8 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@design.estate/dees-catalog', - version: '3.60.0', + version: '3.61.0', description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.' } diff --git a/ts_web/elements/00group-input/dees-input-list/dees-input-list.demo.ts b/ts_web/elements/00group-input/dees-input-list/dees-input-list.demo.ts index 26c4a0a..410cc61 100644 --- a/ts_web/elements/00group-input/dees-input-list/dees-input-list.demo.ts +++ b/ts_web/elements/00group-input/dees-input-list/dees-input-list.demo.ts @@ -322,7 +322,25 @@ export const demoFunc = () => html` > - + + + + + { @property({ type: Array }) accessor candidates: IListCandidate[] = []; + @property({ type: Boolean }) + accessor allowFreeform: boolean = false; + @property({ type: String }) accessor validationText: string = ''; @@ -184,6 +187,20 @@ export class DeesInputList extends DeesInputBase { } + .candidate-check { + width: 14px; + height: 14px; + color: ${cssManager.bdTheme('hsl(142.1 76.2% 36.3%)', 'hsl(142.1 70.6% 45.3%)')}; + flex-shrink: 0; + } + + .candidate-unknown { + width: 14px; + height: 14px; + color: ${cssManager.bdTheme('hsl(45 93% 47%)', 'hsl(45 93% 58%)')}; + flex-shrink: 0; + } + .drag-handle { display: flex; align-items: center; @@ -442,6 +459,14 @@ export class DeesInputList extends DeesInputBase { ` : ''} + ${this.candidates.length > 0 ? html` + ${this.candidates.some(c => c.viewKey === item) ? html` + + ` : html` + + `} + ` : ''} +
${this.editingIndex === index ? html` { if (e.key === 'Enter' && this.inputValue.trim()) { e.preventDefault(); if (this.candidates.length > 0) { - // In candidate mode, only allow exact matches + // Try exact candidate match first const match = this.candidates.find( c => c.viewKey.toLowerCase() === this.inputValue.trim().toLowerCase() ); if (match) { this.selectCandidate(match); + } else if (this.allowFreeform) { + // Allow freeform entry (won't have a candidate checkmark) + this.ghostText = ''; + this.currentCandidateIndex = -1; + this.matchingCandidates = []; + this.addItem(); } return; }