feat(FN-1890): improve mobile UX for SkillsView component

- Add comprehensive mobile CSS overrides for skills page layout and responsiveness
- Improve touch targets for toggle switches and interactive elements (44px minimum per Apple HIG)
- Polish skills view base styles with refined toggle dimensions
- Expand mobile CSS tests to cover touch target sizes and responsive layout
This commit is contained in:
Fusion
2026-04-16 06:16:50 -07:00
committed by gsxdsm
parent fdaf1cacfe
commit 261bfff9ae
3 changed files with 157 additions and 14 deletions

View File

@@ -128,19 +128,19 @@ export function SkillsView({ projectId, addToast, onClose }: SkillsViewProps) {
<Wrench size={20} />
Skills
</h2>
<span className="skills-view-count">{discoveredSkills.length} discovered</span>
<span className="skills-view-count" aria-label={`${discoveredSkills.length} discovered skills`}>{discoveredSkills.length} discovered</span>
</div>
<div className="skills-view-actions">
<button
className="btn-icon skills-view-close"
className="btn-icon skills-view-close touch-target"
onClick={onClose}
aria-label="Close skills view"
>
<X size={16} />
</button>
<button
className="btn btn-sm"
className="btn btn-sm touch-target"
onClick={() => void loadDiscoveredSkills()}
disabled={isLoadingDiscovered}
>

View File

@@ -76,9 +76,88 @@ describe("skills-view mobile css", () => {
it("defines .skills-view-toggle-slider with minimum dimensions on mobile", () => {
expect(mobileMediaBlock).toContain(".skills-view-toggle-slider");
const block = extractRuleBlock(cssContent, ".skills-view-toggle-slider");
expect(block).toContain("min-width: 32px");
expect(block).toContain("min-height: 18px");
const block = extractRuleBlock(mobileMediaBlock, ".skills-view-toggle-slider");
expect(block).toContain("min-width: 40px");
expect(block).toContain("min-height: 22px");
});
it("defines .skills-view-section with reduced margin-bottom on mobile", () => {
expect(mobileMediaBlock).toContain(".skills-view-section");
const block = extractRuleBlock(mobileMediaBlock, ".skills-view-section");
expect(block).toMatch(/margin-bottom:\s*var\(--space-md\)/);
});
it("defines .skills-view-section-title with smaller font on mobile", () => {
expect(mobileMediaBlock).toContain(".skills-view-section-title");
const block = extractRuleBlock(mobileMediaBlock, ".skills-view-section-title");
expect(block).toContain("font-size: 13px");
});
it("defines .skills-view-card with reduced padding on mobile", () => {
expect(mobileMediaBlock).toContain(".skills-view-card");
const block = extractRuleBlock(mobileMediaBlock, ".skills-view-card");
expect(block).toContain("padding: var(--space-sm)");
});
it("defines .skills-view-card-title with smaller font on mobile", () => {
expect(mobileMediaBlock).toContain(".skills-view-card-title");
const block = extractRuleBlock(mobileMediaBlock, ".skills-view-card-title");
expect(block).toContain("font-size: 13px");
});
it("defines .skills-view-card-description with smaller font on mobile", () => {
expect(mobileMediaBlock).toContain(".skills-view-card-description");
const block = extractRuleBlock(mobileMediaBlock, ".skills-view-card-description");
expect(block).toContain("font-size: 12px");
});
it("defines .skills-view-empty with reduced padding on mobile", () => {
expect(mobileMediaBlock).toContain(".skills-view-empty");
const block = extractRuleBlock(mobileMediaBlock, ".skills-view-empty");
expect(block).toContain("padding: var(--space-lg)");
});
it("defines .skills-view-error with reduced padding on mobile", () => {
expect(mobileMediaBlock).toContain(".skills-view-error");
const block = extractRuleBlock(mobileMediaBlock, ".skills-view-error");
expect(block).toContain("padding: var(--space-lg)");
});
it("defines .skills-view-loading with reduced padding on mobile", () => {
expect(mobileMediaBlock).toContain(".skills-view-loading");
const block = extractRuleBlock(mobileMediaBlock, ".skills-view-loading");
expect(block).toContain("padding: var(--space-md)");
});
it("defines .skills-view-item with padding on mobile", () => {
expect(mobileMediaBlock).toContain(".skills-view-item");
const block = extractRuleBlock(mobileMediaBlock, ".skills-view-item");
expect(block).toContain("padding: var(--space-md)");
});
it("defines .skills-view-item-info with full width on mobile", () => {
expect(mobileMediaBlock).toContain(".skills-view-item-info");
const block = extractRuleBlock(mobileMediaBlock, ".skills-view-item-info");
expect(block).toContain("width: 100%");
});
it("defines .skills-view-item-toggle with padding on mobile", () => {
expect(mobileMediaBlock).toContain(".skills-view-item-toggle");
const block = extractRuleBlock(mobileMediaBlock, ".skills-view-item-toggle");
expect(block).toContain("padding: var(--space-sm)");
});
it("defines .skills-view-count with smaller font on mobile", () => {
expect(mobileMediaBlock).toContain(".skills-view-count");
const block = extractRuleBlock(mobileMediaBlock, ".skills-view-count");
expect(block).toContain("font-size: 12px");
});
it("defines .badge--sm base class in CSS", () => {
expect(cssContent).toContain(".badge--sm {");
const block = extractRuleBlock(cssContent, ".badge--sm");
expect(block).toContain("font-size: 10px");
expect(block).toContain("padding: 1px 6px");
});
it("skills-view base styles are defined in styles.css", () => {