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 1796579..5485639 100644 Binary files a/readme.plan.md and b/readme.plan.md differ 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; } }