From 24aa7588c5fdb6bf08840e2f328ca784deb66041 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Thu, 18 Sep 2025 14:10:55 +0000 Subject: [PATCH] feat(dees-stepper): Revamp dees-stepper: modern styling, new steps and improved navigation/validation --- changelog.md | 10 ++ readme.plan.md | Bin 9652 -> 10085 bytes ts_web/00_commitinfo_data.ts | 2 +- ts_web/elements/dees-stepper.ts | 228 +++++++++++++++++++++++++------- 4 files changed, 189 insertions(+), 51 deletions(-) diff --git a/changelog.md b/changelog.md index c72c3f1..f076425 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,15 @@ # Changelog +## 2025-09-18 - 1.12.0 - feat(dees-stepper) +Revamp dees-stepper: modern styling, new steps and improved navigation/validation + +- Visual refresh for dees-stepper: updated card shapes, shadows, refined borders and stronger selected-state visuals for a modern shadcn-inspired look +- Improved transitions and animations (transform, box-shadow, filter) for smoother step selection and show/hide behavior +- Expanded default/demo steps: replaced small sample with a richer multi-step flow (Account Setup, Profile Details, Contact Information, Team Size, Goals, Brand Preferences, Integrations, Review & Launch) +- Enhanced step interactions: safer goNext/goBack handling with boundary checks and reset of validation flags to avoid stale validation state +- Better toolbar/controls placement for stepper demo (spacing, counters, accessible back control) and improved keyboard/UX affordances +- Minor documentation and meta updates: readme.plan.md extended with dees-stepper plan items and added .claude/settings.local.json + ## 2025-09-18 - 1.11.8 - fix(ci) Add local tool permissions config to allow running pnpm scripts and enable mcp__zen__chat diff --git a/readme.plan.md b/readme.plan.md index 17965790a9d07faad48184585eac0c48860ca045..5485639f837bf1b5acb7228d0b49f439a892fb25 100644 GIT binary patch delta 444 zcmZvY%Sr=55JmU%6$L?egA#O|MQ|mGIOs-%wB0q+g+1L(S4|$P{F00OlK){%G6Vwd z`azvr=N=w^pMMTl`)W3W`R)9^UM!#nhsZSx=8OfNlEV_AkzJtJRW*EUKj9VEgd4yu zvFPjNL@>KF2$<-A97dsb2kecrv8KqG3OXp*Qp8?=S&{pZ`Iem#gwyoRvT2}A<&rE( z?}663R)1Q{n&KF)A(zw@WQJlWOiR9F8Kb`j3Jy#wI>jdou-?QDxthH9|A{XZ4KFDW z`?Gbc8D1%vVN5>rHl6~)H)0;!P~_%0zhB3TiD5`vfY(K5eXFyaS}p3)mDH Z?I3D+3>mvQ);&a6<(PXYdO8ZNsy}Q*oUs4^ delta 7 OcmaFrx5azI7F7TcYXiIh diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index d58a213..1b5c9b3 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: '1.11.8', + version: '1.12.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/dees-stepper.ts b/ts_web/elements/dees-stepper.ts index 24798ba..42e7aca 100644 --- a/ts_web/elements/dees-stepper.ts +++ b/ts_web/elements/dees-stepper.ts @@ -36,30 +36,130 @@ export class DeesStepper extends DeesElement { - - - - Next + + + Continue `, validationFunc: async (stepperArg, elementArg) => { const deesForm = elementArg.querySelector('dees-form'); - deesForm.addEventListener('formData', (eventArg) => { - stepperArg.goNext(); - }); + deesForm.addEventListener('formData', () => stepperArg.goNext(), { once: true }); }, }, { - title: 'Whats your mobile number?', - content: html``, + title: 'Profile Details', + content: html` + + + + Continue + + `, + validationFunc: async (stepperArg, elementArg) => { + const deesForm = elementArg.querySelector('dees-form'); + deesForm.addEventListener('formData', () => stepperArg.goNext(), { once: true }); + }, + }, + { + title: 'Contact Information', + content: html` + + + + Continue + + `, + validationFunc: async (stepperArg, elementArg) => { + const deesForm = elementArg.querySelector('dees-form'); + deesForm.addEventListener('formData', () => stepperArg.goNext(), { once: true }); + }, + }, + { + title: 'Team Size', + content: html` + + + Continue + + `, + validationFunc: async (stepperArg, elementArg) => { + const deesForm = elementArg.querySelector('dees-form'); + deesForm.addEventListener('formData', () => stepperArg.goNext(), { once: true }); + }, + }, + { + title: 'Goals', + content: html` + + + Continue + + `, + validationFunc: async (stepperArg, elementArg) => { + const deesForm = elementArg.querySelector('dees-form'); + deesForm.addEventListener('formData', () => stepperArg.goNext(), { once: true }); + }, + }, + { + title: 'Brand Preferences', + content: html` + + + + Continue + + `, + validationFunc: async (stepperArg, elementArg) => { + const deesForm = elementArg.querySelector('dees-form'); + deesForm.addEventListener('formData', () => stepperArg.goNext(), { once: true }); + }, + }, + { + title: 'Integrations', + content: html` + + + Continue + + `, + validationFunc: async (stepperArg, elementArg) => { + const deesForm = elementArg.querySelector('dees-form'); + deesForm.addEventListener('formData', () => stepperArg.goNext(), { once: true }); + }, + }, + { + title: 'Review & Launch', + content: html` + +

Almost there! Review your selections and launch whenever you're ready.

+
+ `, }, ] as IStep[]} >
@@ -99,30 +199,33 @@ export class DeesStepper extends DeesElement { position: relative; pointer-events: none; overflow: hidden; - transition: all 0.7s ease-in-out; + transition: transform 0.35s ease, box-shadow 0.35s ease, filter 0.35s ease, border 0.35s ease; max-width: 500px; min-height: 300px; - border-radius: 16px; - background: ${cssManager.bdTheme('#ffffff', '#181818')}; - border-top: 1px solid ${cssManager.bdTheme('#ffffff', '#181818')}; - color: ${cssManager.bdTheme('#333', '#fff')}; + border-radius: 18px; + background: ${cssManager.bdTheme('#ffffff', '#18181b')}; + border: 1px solid ${cssManager.bdTheme('rgba(226, 232, 240, 0.9)', 'rgba(63, 63, 70, 0.85)')}; + color: ${cssManager.bdTheme('#0f172a', '#f5f5f5')}; margin: auto; margin-bottom: 20px; - filter: opacity(0.5) grayscale(1); - box-shadow: 0px 0px 3px #00000010; + filter: opacity(0.55) saturate(0.85); + box-shadow: ${cssManager.bdTheme('0 20px 40px -25px rgba(15, 23, 42, 0.45)', '0 20px 36px -22px rgba(15, 23, 42, 0.65)')}; user-select: none; + background-clip: padding-box; } .step.selected { - border-top: 1px solid #e4002b; pointer-events: all; - filter: opacity(1) grayscale(0); - box-shadow: 0px 0px 5px #00000010; + filter: opacity(1) saturate(1); + transform: translateY(-6px); + border: 1px solid ${cssManager.bdTheme(colors.dark.blue, colors.dark.blue)}; + box-shadow: ${cssManager.bdTheme('0 28px 60px -30px rgba(15, 23, 42, 0.42)', '0 26px 55px -28px rgba(37, 99, 235, 0.6)')}; user-select: auto; } .step.hiddenStep { filter: opacity(0); + transform: translateY(16px); } .step:last-child { @@ -130,40 +233,50 @@ export class DeesStepper extends DeesElement { } .step .stepCounter { - color: #999; + color: ${cssManager.bdTheme('#64748b', '#a1a1aa')}; position: absolute; - top: 0px; - right: 0px; - padding: 10px 15px; + top: 12px; + right: 12px; + padding: 6px 14px; font-size: 12px; - border-bottom-left-radius: 3px; - background: ${cssManager.bdTheme('#00000008', '#ffffff08')}; + border-radius: 999px; + background: ${cssManager.bdTheme('rgba(226, 232, 240, 0.5)', 'rgba(63, 63, 70, 0.45)')}; + border: 1px solid ${cssManager.bdTheme('rgba(226, 232, 240, 0.7)', 'rgba(63, 63, 70, 0.6)')}; } .step .goBack { - color: #999; - cursor: default; position: absolute; - top: 0px; - left: 0px; - padding: 10px 15px; + top: 12px; + left: 12px; + display: inline-flex; + align-items: center; + gap: 6px; + padding: 6px 12px; font-size: 12px; - border-bottom-right-radius: 3px; - background: ${cssManager.bdTheme('#00000008', '#ffffff08')}; + font-weight: 500; + border-radius: 999px; + border: 1px solid ${cssManager.bdTheme('rgba(226, 232, 240, 0.9)', 'rgba(63, 63, 70, 0.85)')}; + background: ${cssManager.bdTheme('rgba(255, 255, 255, 0.9)', 'rgba(39, 39, 42, 0.85)')}; + color: ${cssManager.bdTheme('#475569', '#d4d4d8')}; + cursor: pointer; + transition: border 0.2s ease, color 0.2s ease, background 0.2s ease, transform 0.2s ease; } .step .goBack:hover { - color: ${cssManager.bdTheme('#333', '#fff')}; - background: ${cssManager.bdTheme('#00000012', colors.dark.blue)}; + color: ${cssManager.bdTheme('#0f172a', '#fafafa')}; + border-color: ${cssManager.bdTheme(colors.dark.blue, colors.dark.blue)}; + background: ${cssManager.bdTheme('rgba(226, 232, 240, 0.95)', 'rgba(63, 63, 70, 0.7)')}; + transform: translateX(-2px); } .step .goBack:active { - color: ${cssManager.bdTheme('#333', '#fff')}; - background: ${cssManager.bdTheme('#00000012', colors.dark.blueActive)}; + color: ${cssManager.bdTheme('#0f172a', '#fafafa')}; + border-color: ${cssManager.bdTheme(colors.dark.blueActive, colors.dark.blueActive)}; + background: ${cssManager.bdTheme('rgba(226, 232, 240, 0.85)', 'rgba(63, 63, 70, 0.6)')}; } .step .goBack span { - transition: all 0.2s; + transition: transform 0.2s ease; display: inline-block; } @@ -173,15 +286,16 @@ export class DeesStepper extends DeesElement { .step .title { text-align: center; - padding-top: 50px; + padding-top: 64px; font-family: 'Geist Sans', sans-serif; - font-size: 22px; - - font-weight: 500; + font-size: 24px; + font-weight: 600; + letter-spacing: -0.01em; + color: inherit; } .step .content { - padding: 20px; + padding: 24px 28px 32px; } `, ]; @@ -270,7 +384,14 @@ export class DeesStepper extends DeesElement { public async goBack() { const currentIndex = this.steps.findIndex((stepArg) => stepArg === this.selectedStep); - this.selectedStep = this.steps[currentIndex - 1]; + if (currentIndex <= 0) { + return; + } + const currentStep = this.steps[currentIndex]; + currentStep.validationFuncCalled = false; + const previousStep = this.steps[currentIndex - 1]; + previousStep.validationFuncCalled = false; + this.selectedStep = previousStep; await this.domtoolsPromise; await this.domtools.convenience.smartdelay.delayFor(100); this.selectedStep.onReturnToStepFunc?.(this, this.shadowRoot.querySelector('.selected')); @@ -278,6 +399,13 @@ export class DeesStepper extends DeesElement { public goNext() { const currentIndex = this.steps.findIndex((stepArg) => stepArg === this.selectedStep); - this.selectedStep = this.steps[currentIndex + 1]; + if (currentIndex < 0 || currentIndex >= this.steps.length - 1) { + return; + } + const currentStep = this.steps[currentIndex]; + currentStep.validationFuncCalled = false; + const nextStep = this.steps[currentIndex + 1]; + nextStep.validationFuncCalled = false; + this.selectedStep = nextStep; } }