feat(09-03): apply MD3 button styles and elevation across all wizard steps

- BackendCard: rounded-lg -> rounded-xl, added shadow/shadow-md elevation
- OutputBlock: pre rounded -> rounded-xl + shadow-sm; Copy/Download use MD3_BTN_OUTLINED small variant
- BackendSelectionStep: added explicit Next submit button with MD3_BTN_FILLED
- RemoteConfigStep: Back uses MD3_BTN_OUTLINED, Next uses MD3_BTN_FILLED
- DeploymentStep: Back uses MD3_BTN_OUTLINED, Next/Review uses MD3_BTN_FILLED
- ReviewStep: Back uses MD3_BTN_OUTLINED, Download All (ZIP) uses MD3_BTN_FILLED
- All 179 tests pass (zero regressions)
This commit is contained in:
2026-04-01 09:29:52 +02:00
parent e560a6af84
commit d7a2cad7ea
6 changed files with 24 additions and 12 deletions
+3 -3
View File
@@ -14,10 +14,10 @@ export function BackendCard({ name, description, selected = false, onClick, ...r
onClick={onClick}
data-selected={selected}
className={[
'flex flex-col items-start gap-1 rounded-lg border-2 p-4 text-left transition-colors',
'flex flex-col items-start gap-1 rounded-xl border-2 p-4 text-left transition-all',
selected
? 'border-primary bg-primary/10'
: 'border-outline bg-surface-container hover:border-primary hover:bg-surface',
? 'border-primary bg-primary/10 shadow-md'
: 'border-outline bg-surface-container shadow hover:border-primary hover:bg-surface hover:shadow-md',
].join(' ')}
{...rest}
>
@@ -6,6 +6,7 @@ import { useWizard } from '../../store/context';
import type { BackendType } from '../../store/types';
import { BACKEND_REGISTRY } from '../../schemas/registry';
import { BackendCard } from '../ui/BackendCard';
import { MD3_BTN_FILLED } from '../../styles/md3-buttons';
const remoteNameSchema = z.object({
name: z
@@ -71,6 +72,11 @@ export function BackendSelectionStep() {
/>
))}
</div>
<div className="flex gap-3 mt-6">
<button type="submit" className={MD3_BTN_FILLED}>
Next
</button>
</div>
</form>
</div>
);
+3 -2
View File
@@ -3,6 +3,7 @@
// Dispatches SET_DEPLOYMENT live on every control change (no submit needed for deployment options).
import { useWizard } from '../../store/context';
import { MD3_BTN_FILLED, MD3_BTN_OUTLINED } from '../../styles/md3-buttons';
export function DeploymentStep() {
const { state, dispatch } = useWizard();
@@ -91,14 +92,14 @@ export function DeploymentStep() {
<button
type="button"
onClick={() => dispatch({ type: 'SET_STEP', payload: 1 })}
className="px-4 py-2 text-sm border border-outline rounded-md hover:bg-surface"
className={MD3_BTN_OUTLINED}
>
Back
</button>
<button
type="button"
onClick={() => dispatch({ type: 'SET_STEP', payload: 3 })}
className="px-4 py-2 text-sm bg-primary text-on-primary rounded-md hover:bg-primary"
className={MD3_BTN_FILLED}
>
Next / Review
</button>
+6 -3
View File
@@ -3,6 +3,7 @@
// disabled prop gates both actions (SECU-01 security acknowledgement gate).
import { useState } from 'react';
import { downloadFile } from '../../utils/downloadFile';
import { MD3_BTN_OUTLINED } from '../../styles/md3-buttons';
export interface OutputBlockProps {
label: string;
@@ -20,6 +21,8 @@ export function OutputBlock({ label, content, filename, disabled = false }: Outp
setTimeout(() => setCopied(false), 2000);
}
const smallBtn = `${MD3_BTN_OUTLINED} !text-xs !px-3 !py-1.5`;
return (
<div className="mb-6">
<div className="flex items-center justify-between mb-1">
@@ -29,7 +32,7 @@ export function OutputBlock({ label, content, filename, disabled = false }: Outp
type="button"
disabled={disabled}
onClick={handleCopy}
className="text-xs px-2 py-1 rounded border border-outline disabled:opacity-40"
className={smallBtn}
>
{copied ? 'Copied!' : 'Copy'}
</button>
@@ -38,14 +41,14 @@ export function OutputBlock({ label, content, filename, disabled = false }: Outp
type="button"
disabled={disabled}
onClick={() => downloadFile(content, filename)}
className="text-xs px-2 py-1 rounded border border-outline disabled:opacity-40"
className={smallBtn}
>
Download
</button>
)}
</div>
</div>
<pre className="bg-surface-variant text-on-surface-variant rounded p-4 text-xs overflow-x-auto whitespace-pre-wrap">
<pre className="bg-surface-variant text-on-surface-variant rounded-xl shadow-sm p-4 text-xs overflow-x-auto whitespace-pre-wrap">
<code>{content}</code>
</pre>
</div>
+3 -2
View File
@@ -11,6 +11,7 @@ import { FieldRenderer } from '../ui/FieldRenderer';
import { AzureAuthToggle } from './AzureAuthToggle';
import { SftpAuthToggle } from './SftpAuthToggle';
import type { FieldError } from 'react-hook-form';
import { MD3_BTN_FILLED, MD3_BTN_OUTLINED } from '../../styles/md3-buttons';
export function RemoteConfigStep() {
const { state, dispatch } = useWizard();
@@ -110,13 +111,13 @@ export function RemoteConfigStep() {
<button
type="button"
onClick={() => dispatch({ type: 'SET_STEP', payload: 0 })}
className="px-4 py-2 text-sm border border-outline rounded-md hover:bg-surface"
className={MD3_BTN_OUTLINED}
>
Back
</button>
<button
type="submit"
className="px-4 py-2 text-sm bg-primary text-on-primary rounded-md hover:bg-primary"
className={MD3_BTN_FILLED}
>
Next
</button>
+3 -2
View File
@@ -3,6 +3,7 @@
// Covers CONF-02, CONF-03, DOWN-01DOWN-06, SECU-01, SECU-02.
import { useMemo, useState } from 'react';
import { useWizard } from '../../store/context';
import { MD3_BTN_FILLED, MD3_BTN_OUTLINED } from '../../styles/md3-buttons';
import {
buildRcloneConf,
buildIntuneInstall,
@@ -128,7 +129,7 @@ export function ReviewStep() {
<button
type="button"
onClick={() => dispatch({ type: 'SET_STEP', payload: 2 })}
className="px-4 py-2 text-sm border border-outline rounded-md hover:bg-surface"
className={MD3_BTN_OUTLINED}
>
Back
</button>
@@ -139,7 +140,7 @@ export function ReviewStep() {
type="button"
disabled={!acknowledged}
onClick={handleDownloadZip}
className="w-full py-2 px-4 bg-primary text-on-primary rounded font-medium disabled:opacity-40 disabled:cursor-not-allowed hover:bg-primary"
className={`w-full mt-4 ${MD3_BTN_FILLED}`}
>
Download All (ZIP)
</button>