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:
@@ -14,10 +14,10 @@ export function BackendCard({ name, description, selected = false, onClick, ...r
|
|||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
data-selected={selected}
|
data-selected={selected}
|
||||||
className={[
|
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
|
selected
|
||||||
? 'border-primary bg-primary/10'
|
? 'border-primary bg-primary/10 shadow-md'
|
||||||
: 'border-outline bg-surface-container hover:border-primary hover:bg-surface',
|
: 'border-outline bg-surface-container shadow hover:border-primary hover:bg-surface hover:shadow-md',
|
||||||
].join(' ')}
|
].join(' ')}
|
||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { useWizard } from '../../store/context';
|
|||||||
import type { BackendType } from '../../store/types';
|
import type { BackendType } from '../../store/types';
|
||||||
import { BACKEND_REGISTRY } from '../../schemas/registry';
|
import { BACKEND_REGISTRY } from '../../schemas/registry';
|
||||||
import { BackendCard } from '../ui/BackendCard';
|
import { BackendCard } from '../ui/BackendCard';
|
||||||
|
import { MD3_BTN_FILLED } from '../../styles/md3-buttons';
|
||||||
|
|
||||||
const remoteNameSchema = z.object({
|
const remoteNameSchema = z.object({
|
||||||
name: z
|
name: z
|
||||||
@@ -71,6 +72,11 @@ export function BackendSelectionStep() {
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex gap-3 mt-6">
|
||||||
|
<button type="submit" className={MD3_BTN_FILLED}>
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Dispatches SET_DEPLOYMENT live on every control change (no submit needed for deployment options).
|
// Dispatches SET_DEPLOYMENT live on every control change (no submit needed for deployment options).
|
||||||
|
|
||||||
import { useWizard } from '../../store/context';
|
import { useWizard } from '../../store/context';
|
||||||
|
import { MD3_BTN_FILLED, MD3_BTN_OUTLINED } from '../../styles/md3-buttons';
|
||||||
|
|
||||||
export function DeploymentStep() {
|
export function DeploymentStep() {
|
||||||
const { state, dispatch } = useWizard();
|
const { state, dispatch } = useWizard();
|
||||||
@@ -91,14 +92,14 @@ export function DeploymentStep() {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => dispatch({ type: 'SET_STEP', payload: 1 })}
|
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
|
Back
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => dispatch({ type: 'SET_STEP', payload: 3 })}
|
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
|
Next / Review
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// disabled prop gates both actions (SECU-01 security acknowledgement gate).
|
// disabled prop gates both actions (SECU-01 security acknowledgement gate).
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { downloadFile } from '../../utils/downloadFile';
|
import { downloadFile } from '../../utils/downloadFile';
|
||||||
|
import { MD3_BTN_OUTLINED } from '../../styles/md3-buttons';
|
||||||
|
|
||||||
export interface OutputBlockProps {
|
export interface OutputBlockProps {
|
||||||
label: string;
|
label: string;
|
||||||
@@ -20,6 +21,8 @@ export function OutputBlock({ label, content, filename, disabled = false }: Outp
|
|||||||
setTimeout(() => setCopied(false), 2000);
|
setTimeout(() => setCopied(false), 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const smallBtn = `${MD3_BTN_OUTLINED} !text-xs !px-3 !py-1.5`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<div className="flex items-center justify-between mb-1">
|
<div className="flex items-center justify-between mb-1">
|
||||||
@@ -29,7 +32,7 @@ export function OutputBlock({ label, content, filename, disabled = false }: Outp
|
|||||||
type="button"
|
type="button"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onClick={handleCopy}
|
onClick={handleCopy}
|
||||||
className="text-xs px-2 py-1 rounded border border-outline disabled:opacity-40"
|
className={smallBtn}
|
||||||
>
|
>
|
||||||
{copied ? 'Copied!' : 'Copy'}
|
{copied ? 'Copied!' : 'Copy'}
|
||||||
</button>
|
</button>
|
||||||
@@ -38,14 +41,14 @@ export function OutputBlock({ label, content, filename, disabled = false }: Outp
|
|||||||
type="button"
|
type="button"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onClick={() => downloadFile(content, filename)}
|
onClick={() => downloadFile(content, filename)}
|
||||||
className="text-xs px-2 py-1 rounded border border-outline disabled:opacity-40"
|
className={smallBtn}
|
||||||
>
|
>
|
||||||
Download
|
Download
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</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>
|
<code>{content}</code>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { FieldRenderer } from '../ui/FieldRenderer';
|
|||||||
import { AzureAuthToggle } from './AzureAuthToggle';
|
import { AzureAuthToggle } from './AzureAuthToggle';
|
||||||
import { SftpAuthToggle } from './SftpAuthToggle';
|
import { SftpAuthToggle } from './SftpAuthToggle';
|
||||||
import type { FieldError } from 'react-hook-form';
|
import type { FieldError } from 'react-hook-form';
|
||||||
|
import { MD3_BTN_FILLED, MD3_BTN_OUTLINED } from '../../styles/md3-buttons';
|
||||||
|
|
||||||
export function RemoteConfigStep() {
|
export function RemoteConfigStep() {
|
||||||
const { state, dispatch } = useWizard();
|
const { state, dispatch } = useWizard();
|
||||||
@@ -110,13 +111,13 @@ export function RemoteConfigStep() {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => dispatch({ type: 'SET_STEP', payload: 0 })}
|
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
|
Back
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="px-4 py-2 text-sm bg-primary text-on-primary rounded-md hover:bg-primary"
|
className={MD3_BTN_FILLED}
|
||||||
>
|
>
|
||||||
Next
|
Next
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// Covers CONF-02, CONF-03, DOWN-01–DOWN-06, SECU-01, SECU-02.
|
// Covers CONF-02, CONF-03, DOWN-01–DOWN-06, SECU-01, SECU-02.
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { useWizard } from '../../store/context';
|
import { useWizard } from '../../store/context';
|
||||||
|
import { MD3_BTN_FILLED, MD3_BTN_OUTLINED } from '../../styles/md3-buttons';
|
||||||
import {
|
import {
|
||||||
buildRcloneConf,
|
buildRcloneConf,
|
||||||
buildIntuneInstall,
|
buildIntuneInstall,
|
||||||
@@ -128,7 +129,7 @@ export function ReviewStep() {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => dispatch({ type: 'SET_STEP', payload: 2 })}
|
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
|
Back
|
||||||
</button>
|
</button>
|
||||||
@@ -139,7 +140,7 @@ export function ReviewStep() {
|
|||||||
type="button"
|
type="button"
|
||||||
disabled={!acknowledged}
|
disabled={!acknowledged}
|
||||||
onClick={handleDownloadZip}
|
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)
|
Download All (ZIP)
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user