@longtq2501/next-spring-skills 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT.md +3 -0
- package/README.md +7 -0
- package/package.json +1 -1
- package/skills/SKILL.md +3 -0
- package/skills/nextjs/component-aesthetics.md +58 -0
- package/skills/nextjs/design-tokens.md +68 -0
- package/skills/nextjs/monorepo.md +116 -0
- package/skills/nextjs/premium-effects.md +61 -0
- package/skills/nextjs/premium-inputs.md +65 -0
- package/skills/nextjs/responsive-design.md +56 -0
- package/skills/nextjs/testing.md +74 -70
- package/skills/nextjs/ux-feedback.md +56 -0
package/AGENT.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Agent Instructions
|
|
2
2
|
|
|
3
|
+
> [!IMPORTANT]
|
|
4
|
+
> **MANDATORY STARTUP STEP**: Upon starting a new session or entering this project, the AI Agent **MUST** immediately read `skills/SKILL.md` to index all available standards and architectural patterns. Do not proceed with code generation until you have understood the patterns in the `skills/` directory.
|
|
5
|
+
|
|
3
6
|
Rules for contributing to this repository.
|
|
4
7
|
|
|
5
8
|
## Style Guidelines
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Next-Spring Skills
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@longtq2501/next-spring-skills)
|
|
4
|
+
|
|
3
5
|
Modular best practices, code templates, and interaction protocols for full-stack projects using **Next.js** and **Spring Boot**.
|
|
4
6
|
|
|
5
7
|
## Key Directories
|
|
@@ -11,6 +13,11 @@ Modular best practices, code templates, and interaction protocols for full-stack
|
|
|
11
13
|
|
|
12
14
|
---
|
|
13
15
|
|
|
16
|
+
## NPM Package
|
|
17
|
+
📦 **Registry**: [https://www.npmjs.com/package/@longtq2501/next-spring-skills](https://www.npmjs.com/package/@longtq2501/next-spring-skills)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
14
21
|
## Installation
|
|
15
22
|
You can instantly add these skills to any project using `npx`:
|
|
16
23
|
|
package/package.json
CHANGED
package/skills/SKILL.md
CHANGED
|
@@ -69,6 +69,9 @@ See [webrtc.md](./nextjs/webrtc.md) for real-time media and signaling.
|
|
|
69
69
|
### Quality Assurance
|
|
70
70
|
See [testing.md](./nextjs/testing.md) for Vitest and React Testing Library patterns.
|
|
71
71
|
|
|
72
|
+
### Architecture & Monorepo
|
|
73
|
+
See [monorepo.md](./nextjs/monorepo.md) for Turborepo and code-sharing strategies.
|
|
74
|
+
|
|
72
75
|
### Accessibility (a11y)
|
|
73
76
|
See [accessibility.md](./nextjs/accessibility.md) for semantic HTML and ARIA.
|
|
74
77
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Component Aesthetics
|
|
2
|
+
|
|
3
|
+
Standardizing the "feel" of components like cards, buttons, and sections ensures a premium, cohesive user experience.
|
|
4
|
+
|
|
5
|
+
## 1. The 8px Spacing System
|
|
6
|
+
|
|
7
|
+
A consistent spacing system is the foundation of professional-looking UI. Always use multiples of 8px (or 4px for fine-tuning).
|
|
8
|
+
|
|
9
|
+
- **Nano**: `4px` (`p-1`, `m-1`) - Micro-spacing for icons/text.
|
|
10
|
+
- **Small**: `8px` (`p-2`, `m-2`) - Default gap for small items.
|
|
11
|
+
- **Base**: `16px` (`p-4`, `m-4`) - Standard padding for cards/modals.
|
|
12
|
+
- **Large**: `24px` (`p-6`, `m-6`) - Generous padding for landing sections.
|
|
13
|
+
- **Huge**: `32px` (`p-8`, `m-8`) - Container margins.
|
|
14
|
+
|
|
15
|
+
> [!TIP]
|
|
16
|
+
> Use `gap-{n}` instead of margins whenever possible to keep layout logic centralized in the container.
|
|
17
|
+
|
|
18
|
+
## 2. Border Radius Scale
|
|
19
|
+
|
|
20
|
+
Consistent rounded corners make the UI feel modern and approachable. Avoid "sharp" 0px corners or "clipping" 2px corners.
|
|
21
|
+
|
|
22
|
+
- **Soft (md)**: `6px` / `0.375rem` - Checkboxes, small inputs.
|
|
23
|
+
- **Standard (lg)**: `8px` / `0.5rem` - Default button radius.
|
|
24
|
+
- **Premium (xl)**: `12px` / `0.75rem` - Cards, dropdown menus.
|
|
25
|
+
- **Super (2xl)**: `16px` / `1rem` - Large modals, image containers.
|
|
26
|
+
- **Full**: `9999px` - Pills, circular avatars.
|
|
27
|
+
|
|
28
|
+
## 3. Shadow & Depth (Elevation)
|
|
29
|
+
|
|
30
|
+
Shadows should be subtle and multi-layered. Avoid single, dark, blurry shadows.
|
|
31
|
+
|
|
32
|
+
```css
|
|
33
|
+
/* Custom utility for Premium Shadow */
|
|
34
|
+
.shadow-premium {
|
|
35
|
+
box-shadow:
|
|
36
|
+
0 1px 2px rgba(0, 0, 0, 0.05),
|
|
37
|
+
0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
|
38
|
+
0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* Glassmorphism Border (Adds depth without heavy shadows) */
|
|
42
|
+
.border-premium {
|
|
43
|
+
border: 1px solid hsl(var(--border) / 0.5);
|
|
44
|
+
background-clip: padding-box;
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 4. Visual Hierarchy Techniques
|
|
49
|
+
|
|
50
|
+
- **Surface Contrast**: In dark mode, nested components should be *lighter* than their parents to simulate light reflection.
|
|
51
|
+
- Body Background: `hsl(240 10% 3.9%)`
|
|
52
|
+
- Card/Overlay: `hsl(240 10% 7.5%)`
|
|
53
|
+
- **Ghost Dividers**: Instead of solid lines, use `border-muted/30` or just whitespace (`gap`) to separate content.
|
|
54
|
+
|
|
55
|
+
## Best Practices
|
|
56
|
+
1. **Consistency is King**: If one card has `rounded-xl`, all equivalent cards must have `rounded-xl`.
|
|
57
|
+
2. **Inner Radius Logic**: If a parent has `rounded-xl` (12px), the child should have `rounded-lg` (8px) to maintain a concentric look.
|
|
58
|
+
3. **Subtle Borders**: Never use `#eee` or `black` for borders. Use `hsl(var(--border))` with varying opacities.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Modern Design Tokens
|
|
2
|
+
|
|
3
|
+
Design tokens are the visual atoms of your design system. Standardizing these ensures professional color harmony, readable typography, and consistent aesthetics across the application.
|
|
4
|
+
|
|
5
|
+
## 1. Color Harmony (HSL)
|
|
6
|
+
|
|
7
|
+
Always use HSL (Hue, Saturation, Lightness) for colors. It is intuitive and allows for programmatically generating shades.
|
|
8
|
+
|
|
9
|
+
### Core Palette
|
|
10
|
+
Avoid generic "pure" colors. Use curated HSL values.
|
|
11
|
+
|
|
12
|
+
```css
|
|
13
|
+
:root {
|
|
14
|
+
/* Neutral Palette - Slate/Zinc */
|
|
15
|
+
--background: 240 10% 3.9%;
|
|
16
|
+
--foreground: 0 0% 98%;
|
|
17
|
+
--muted: 240 3.7% 15.9%;
|
|
18
|
+
--muted-foreground: 240 5% 64.9%;
|
|
19
|
+
|
|
20
|
+
/* Primary - Deep Indigo/Blue */
|
|
21
|
+
--primary: 263.4 70% 50.4%;
|
|
22
|
+
--primary-foreground: 210 20% 98%;
|
|
23
|
+
|
|
24
|
+
/* Accent - Soft Violet */
|
|
25
|
+
--accent: 240 3.7% 15.9%;
|
|
26
|
+
--accent-foreground: 0 0% 98%;
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Semantic Colors
|
|
31
|
+
Define clear colors for status to improve UX.
|
|
32
|
+
|
|
33
|
+
- **Success**: Emerald (`142.1 70.6% 45.3%`)
|
|
34
|
+
- **Warning**: Amber (`37.9 92.1% 50.2%`)
|
|
35
|
+
- **Destructive**: Rose (`346.8 77.2% 49.8%`)
|
|
36
|
+
|
|
37
|
+
## 2. Typography Excellence
|
|
38
|
+
|
|
39
|
+
Premium UIs rely on high-quality font stacks and proper spacing.
|
|
40
|
+
|
|
41
|
+
### Font Stacks
|
|
42
|
+
Use modern, highly legible fonts.
|
|
43
|
+
|
|
44
|
+
```css
|
|
45
|
+
/* Tailwind Config */
|
|
46
|
+
fontFamily: {
|
|
47
|
+
sans: ['var(--font-geist-sans)', 'Inter', 'system-ui', 'sans-serif'],
|
|
48
|
+
display: ['Outfit', 'var(--font-geist-sans)'],
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Hierarchy & Leading
|
|
53
|
+
- **Body Text**: `tracking-tight` and `leading-relaxed` (1.625).
|
|
54
|
+
- **Headings**: `tracking-tighter` and `leading-tight` (1.2) for a modern, compact look.
|
|
55
|
+
- **Micro-copy**: `uppercase`, `tracking-widest`, `text-xs`, `font-semibold`.
|
|
56
|
+
|
|
57
|
+
## 3. Dark Mode Strategy
|
|
58
|
+
|
|
59
|
+
Modern apps must prioritize dark mode. Use "Soft Dark" instead of "Pure Black" (`#000000`) for backgrounds to reduce eye strain.
|
|
60
|
+
|
|
61
|
+
- **Background**: `hsl(240 10% 3.9%)`
|
|
62
|
+
- **Surface/Card**: `hsl(240 10% 6%)`
|
|
63
|
+
- **Border**: `hsl(240 5% 15%)`
|
|
64
|
+
|
|
65
|
+
## Best Practices
|
|
66
|
+
1. **Never use Hex/RGB for primary tokens**: Use HSL to allow for opacity modifiers (e.g., `bg-primary/20`).
|
|
67
|
+
2. **Limit Colors**: Stick to 1 Primary, 1 Neutral, and the 3 Semantic colors.
|
|
68
|
+
3. **Contrast First**: Always verify your foreground/background contrast using APCA or WCAG 2.1 standards.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Skill: Monorepo Management - Turborepo (Production Blueprint)
|
|
2
|
+
|
|
3
|
+
Guidelines for building a scalable, high-performance monorepo for enterprise-level multi-platform projects.
|
|
4
|
+
|
|
5
|
+
## TL;DR - Quick Reference
|
|
6
|
+
|
|
7
|
+
### Critical Rules
|
|
8
|
+
1. **Orchestration**: Use Turborepo for build pipeline and remote caching.
|
|
9
|
+
2. **Modular Packages**: Extract logic to `packages/` to ensure 95%+ code reusability.
|
|
10
|
+
3. **Internal Linking**: Use `workspace:*` for local package dependencies.
|
|
11
|
+
4. **Consistency**: Share ESLint, Prettier, Tailwind, and TS configs across all apps.
|
|
12
|
+
5. **Types First**: Shared DTOs in `packages/types` are the single source of truth for FE/BE sync.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1. Enterprise Directory Structure
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
/my-monorepo/
|
|
20
|
+
├── apps/ # Deployable Applications
|
|
21
|
+
│ ├── web/ # Next.js 14 App Router
|
|
22
|
+
│ ├── admin/ # Admin Dashboard
|
|
23
|
+
│ ├── mobile/ # React Native (Expo)
|
|
24
|
+
│ ├── desktop/ # Electron
|
|
25
|
+
│ └── api/ # Spring Boot (Backend)
|
|
26
|
+
├── packages/ # Shared Domain Logic
|
|
27
|
+
│ ├── ui/ # Core UI (Shadcn/React)
|
|
28
|
+
│ ├── types/ # Shared Interfaces & DTOs
|
|
29
|
+
│ ├── validators/ # Zod/Validation Logic
|
|
30
|
+
│ ├── utils/ # Shared Helpers (Date, String)
|
|
31
|
+
│ ├── api-client/ # Axios/Fetch Wrapper
|
|
32
|
+
│ └── database/ # Prisma/DB Client
|
|
33
|
+
├── infra/ # Shared Configuration
|
|
34
|
+
│ ├── tailwind-config/
|
|
35
|
+
│ ├── eslint-config/
|
|
36
|
+
│ └── typescript-config/
|
|
37
|
+
├── turbo.json # Build Pipeline Config
|
|
38
|
+
└── package.json # Workspace Definition
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 2. Core Configurations
|
|
44
|
+
|
|
45
|
+
### turbo.json (The Brain)
|
|
46
|
+
Defines task dependencies and caching outputs.
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"$schema": "https://turbo.build/schema.json",
|
|
51
|
+
"pipeline": {
|
|
52
|
+
"build": {
|
|
53
|
+
"dependsOn": ["^build"],
|
|
54
|
+
"outputs": [".next/**", "dist/**", "out/**"]
|
|
55
|
+
},
|
|
56
|
+
"lint": {},
|
|
57
|
+
"test": {
|
|
58
|
+
"cache": true
|
|
59
|
+
},
|
|
60
|
+
"dev": {
|
|
61
|
+
"cache": false,
|
|
62
|
+
"persistent": true
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### package.json (The Workspace)
|
|
69
|
+
Must include `workspaces` (npm/yarn) or `pnpm-workspace.yaml`.
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"private": true,
|
|
74
|
+
"workspaces": ["apps/*", "packages/*"],
|
|
75
|
+
"scripts": {
|
|
76
|
+
"dev": "turbo dev",
|
|
77
|
+
"build": "turbo build",
|
|
78
|
+
"test": "turbo test"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 3. Shared Packages Pattern
|
|
86
|
+
|
|
87
|
+
### How to share a package (ex: Types)
|
|
88
|
+
1. Create `packages/types/package.json` with a scoped name like `@repo/types`.
|
|
89
|
+
2. Export your types/interfaces from `index.ts`.
|
|
90
|
+
3. In `apps/web/package.json`, add `"@repo/types": "workspace:*"`.
|
|
91
|
+
|
|
92
|
+
// Good: Shared DTO Example
|
|
93
|
+
export interface OrderDTO {
|
|
94
|
+
id: string;
|
|
95
|
+
status: 'PENDING' | 'DONE';
|
|
96
|
+
items: string[];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 4. Scaling & Efficiency
|
|
102
|
+
|
|
103
|
+
### Remote Caching
|
|
104
|
+
Enable `turbo login` and `turbo link` in CI/CD to share build artifacts across the team, reducing build times from minutes to seconds.
|
|
105
|
+
|
|
106
|
+
### Monolith to Monorepo Migration
|
|
107
|
+
- **Step 1**: Move your monolithic `src/` to `apps/main-app/`.
|
|
108
|
+
- **Step 2**: Identify shared logic (utils, constants) and move them to `packages/`.
|
|
109
|
+
- **Step 3**: Introduce internal packages and replace local imports with `@repo/...`.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Related Skills
|
|
114
|
+
- **Frontend Testing**: `skills/nextjs/testing.md`
|
|
115
|
+
- **Performance**: `skills/nextjs/performance.md`
|
|
116
|
+
- **Agent Workflow**: `skills/agent-workflow.md`
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Premium Effects
|
|
2
|
+
|
|
3
|
+
These advanced visual techniques provide the "WOW" factor that differentiates a professional application from a basic one.
|
|
4
|
+
|
|
5
|
+
## 1. Glassmorphism
|
|
6
|
+
|
|
7
|
+
A modern aesthetic that uses semi-transparent, blurred backgrounds to create a "frosted glass" look.
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
/* Standard Glassmorphism Card */
|
|
11
|
+
<div className="
|
|
12
|
+
bg-white/10 backdrop-blur-md
|
|
13
|
+
border border-white/20 rounded-2xl
|
|
14
|
+
shadow-xl
|
|
15
|
+
">
|
|
16
|
+
Content appears on a glass surface
|
|
17
|
+
</div>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Critical Rules for Glassmorphism:
|
|
21
|
+
- **Background**: Ensure the underlying background has enough color/texture for the blur to be noticeable.
|
|
22
|
+
- **Borders**: Always use a semi-transparent white/light border (`border-white/20`) to define the edges.
|
|
23
|
+
- **Contrast**: Check text readability carefully; dark mode often works better with glassmorphism.
|
|
24
|
+
|
|
25
|
+
## 2. Sophisticated Gradients
|
|
26
|
+
|
|
27
|
+
Avoid hard, two-color linear gradients. Use multi-stop or mesh gradients for a premium feel.
|
|
28
|
+
|
|
29
|
+
```css
|
|
30
|
+
/* Mesh Gradient Example */
|
|
31
|
+
.bg-mesh {
|
|
32
|
+
background-color: hsla(240, 100%, 5%, 1);
|
|
33
|
+
background-image:
|
|
34
|
+
radial-gradient(at 0% 0%, hsla(253,16%,7%,1) 0, transparent 50%),
|
|
35
|
+
radial-gradient(at 50% 0%, hsla(225,39%,30%,1) 0, transparent 50%),
|
|
36
|
+
radial-gradient(at 100% 0%, hsla(339,49%,30%,1) 0, transparent 50%);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- **Brand Glow**: Use a subtle gradient on primary buttons or active states.
|
|
41
|
+
- **Text Gradients**: Use `bg-clip-text text-transparent bg-gradient-to-r` for high-impact headlines.
|
|
42
|
+
|
|
43
|
+
## 3. Grain & Texture
|
|
44
|
+
|
|
45
|
+
Adding subtle noise or textures prevents the UI from looking "too flat."
|
|
46
|
+
|
|
47
|
+
- **SVG Noise**: A very low opacity (1-3%) SVG noise layer over backgrounds.
|
|
48
|
+
- **Pattern Overlays**: Subtle dot grids or geometric patterns at 5% opacity.
|
|
49
|
+
|
|
50
|
+
## 4. Micro-interactions (The "Alive" Feel)
|
|
51
|
+
|
|
52
|
+
Use Framer Motion to add organic movement.
|
|
53
|
+
|
|
54
|
+
- **Hover Reveal**: Animate an element's opacity or position slightly when a parent card is hovered.
|
|
55
|
+
- **Floating Effects**: Subtle vertical floating for cards or high-priority icons (`animate={{ y: [0, -4, 0] }}`).
|
|
56
|
+
- **Staggered Entry**: Use `staggerChildren` in Framer Motion to reveal lists item by item instead of all at once.
|
|
57
|
+
|
|
58
|
+
## Best Practices
|
|
59
|
+
1. **Don't Overdo It**: Too many effects (blur + gradient + grain + noise) can look messy and impact performance.
|
|
60
|
+
2. **Performance First**: `backdrop-blur` is heavy on GPUs. Use it sparingly, mainly for navbars or small overlays.
|
|
61
|
+
3. **Accessibility**: Never communicate information *only* through a visual effect; ensure proper contrast and ARIA labels.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Premium Inputs & Buttons
|
|
2
|
+
|
|
3
|
+
The most interactive elements of your application deserve the most attention. Standardizing these prevents "clunky" or "ugly" user interfaces.
|
|
4
|
+
|
|
5
|
+
## 1. Button Archetypes
|
|
6
|
+
|
|
7
|
+
Every button should have a clear purpose and a distinct visual style.
|
|
8
|
+
|
|
9
|
+
| Variant | Usage | Style |
|
|
10
|
+
|:---|:---|:---|
|
|
11
|
+
| **Primary** | Main Action (Save, Submit) | Solid brand color, high contrast. |
|
|
12
|
+
| **Secondary** | Secondary Action (Cancel, Edit) | Outline or subtle background. |
|
|
13
|
+
| **Ghost** | Tertiary Action (Navigation) | No background/border until hover. |
|
|
14
|
+
| **Subtle** | Low-priority utility | Very low contrast background. |
|
|
15
|
+
|
|
16
|
+
### Interactive States (The "Vibe")
|
|
17
|
+
Always add micro-interactions to buttons to make them feel responsive.
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
<button className="
|
|
21
|
+
px-4 py-2 rounded-lg font-medium transition-all
|
|
22
|
+
hover:scale-[1.02] active:scale-[0.98]
|
|
23
|
+
hover:brightness-110 active:brightness-90
|
|
24
|
+
focus-visible:ring-2 focus-visible:ring-primary/50
|
|
25
|
+
">
|
|
26
|
+
Click Me
|
|
27
|
+
</button>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 2. Input Polish
|
|
31
|
+
|
|
32
|
+
Modern inputs should feel deep and clean.
|
|
33
|
+
|
|
34
|
+
- **Height**: Minimum `40px` (h-10) for readability and touch targets.
|
|
35
|
+
- **Padding**: Horizontal `12px` (px-3), Vertical `8px` (py-2).
|
|
36
|
+
- **Focus State**: Use a subtle inner shadow or a distinct (but not jarring) border glow.
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
<input className="
|
|
40
|
+
w-full bg-background border border-input rounded-md px-3 py-2
|
|
41
|
+
placeholder:text-muted-foreground
|
|
42
|
+
focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary
|
|
43
|
+
transition-shadow
|
|
44
|
+
" />
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 3. Shared Field Patterns
|
|
48
|
+
|
|
49
|
+
- **Label Placement**: Place labels 4px-8px above the input. Use `text-sm font-medium`.
|
|
50
|
+
- **Help/Error Text**: Use `text-[12px]` (text-xs) and ensure `Destructive` color for errors.
|
|
51
|
+
- **Required Indicator**: Use a subtle dot or `*` in the brand color, not just plain red.
|
|
52
|
+
|
|
53
|
+
## 4. Loading States
|
|
54
|
+
|
|
55
|
+
Never leave a user guessing. If a button triggers an async action, it *must* show a loading state.
|
|
56
|
+
|
|
57
|
+
- **Spinner**: Small, centered, matching the text color.
|
|
58
|
+
- **Text change**: Optionally change "Submit" to "Submitting...".
|
|
59
|
+
- **Disabling**: Disable the button to prevent double-submissions.
|
|
60
|
+
|
|
61
|
+
## Best Practices
|
|
62
|
+
1. **Touch Targets**: Ensure all clickable elements are at least `44x44px` on mobile.
|
|
63
|
+
2. **Clear Affordance**: Buttons should look like buttons (radius, slight shadow, or distinct color).
|
|
64
|
+
3. **Contrast**: Ensure text inside buttons is highly readable (Primary foreground vs Primary background).
|
|
65
|
+
4. **No Placeholders as Labels**: Never use `placeholder` as a substitute for a real `<label>`.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Responsive Design
|
|
2
|
+
|
|
3
|
+
Ensuring the application is usable and beautiful on every screen size, from mobile phones to ultra-wide monitors. We follow a **Mobile-First** approach.
|
|
4
|
+
|
|
5
|
+
## 1. Mobile-First Workflow
|
|
6
|
+
|
|
7
|
+
Always start with mobile styles (default) and use Tailwind breakpoints to "add" complexity for larger screens.
|
|
8
|
+
|
|
9
|
+
- **Mobile (Default)**: Single column, full-width buttons, condensed headers.
|
|
10
|
+
- **Tablet (`md:`)**: Two columns, sidebar reveals, increased padding.
|
|
11
|
+
- **Desktop (`lg:`)**: Multi-column layouts, full navigation menus, expanded content.
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
/* Responsive Container Example */
|
|
15
|
+
<div className="
|
|
16
|
+
grid grid-cols-1 gap-4
|
|
17
|
+
md:grid-cols-2 lg:grid-cols-3
|
|
18
|
+
p-4 md:p-8
|
|
19
|
+
">
|
|
20
|
+
{/* Content adapts to screen size */}
|
|
21
|
+
</div>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 2. Standard Breakpoints
|
|
25
|
+
|
|
26
|
+
Stick to Tailwind's default breakpoints for consistency:
|
|
27
|
+
|
|
28
|
+
| Breakpoint | Prefix | Width | Usage |
|
|
29
|
+
|:---|:---|:---|:---|
|
|
30
|
+
| **Small** | `sm:` | 640px | Small tablets / Large phones |
|
|
31
|
+
| **Medium** | `md:` | 768px | Tablets (Portrait) |
|
|
32
|
+
| **Large** | `lg:` | 1024px | Laptops / Tablets (Landscape) |
|
|
33
|
+
| **Extra Large**| `xl:` | 1280px | Desktops |
|
|
34
|
+
|
|
35
|
+
## 3. Fluid Typography & Spacing
|
|
36
|
+
|
|
37
|
+
Instead of hardcoding sizes, use relative units or clamp functions for elements that need to scale smoothly.
|
|
38
|
+
|
|
39
|
+
- **Prefer**: `text-base md:text-lg` over a static size.
|
|
40
|
+
- **Stacking**: Use `flex-col md:flex-row` for components that should stack on mobile but be side-by-side on desktop.
|
|
41
|
+
|
|
42
|
+
## 4. Touch-Friendly UI (Mobile)
|
|
43
|
+
|
|
44
|
+
- **Hit Targets**: Buttons and links must be at least `44x44px`.
|
|
45
|
+
- **No Hover for Logic**: Never hide critical functionality behind a hover state on mobile (mobile has no hover).
|
|
46
|
+
- **Navigation**: Use "Hamburger" menus or bottom bars for mobile navigation.
|
|
47
|
+
|
|
48
|
+
## 5. Responsive Media
|
|
49
|
+
|
|
50
|
+
- **Images**: Use `next/image` with `sizes` attribute to prevent loading massive images on small screens.
|
|
51
|
+
- **Aspect Ratio**: Use `aspect-video` or `aspect-square` to maintain proportions during resizing.
|
|
52
|
+
|
|
53
|
+
## Best Practices
|
|
54
|
+
1. **Test in Browser**: Always verify by resizing the browser or using Device Mode in DevTools.
|
|
55
|
+
2. **Avoid "Hiding" Content**: Try to reorganize content rather than using `hidden` to remove logic for mobile users.
|
|
56
|
+
3. **Overflow Handling**: Always use `overflow-x-hidden` on the main container to prevent accidental horizontal scrolling.
|
package/skills/nextjs/testing.md
CHANGED
|
@@ -1,86 +1,90 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Advanced Frontend Testing - Vitest
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
When building frontend features, **testing logic is as important as building the UI**. This skill ensures that every piece of business logic (hooks, utils, state) is verified automatically.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 1. Logic-First Testing Strategy
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
1. **User-Centric Testing**: Test how the user interacts with the app (e.g., clicking buttons), not implementation details (e.g., state).
|
|
9
|
-
2. **Vitest**: Use Vitest for speed and compatibility with Vite/Next.js.
|
|
10
|
-
3. **Screen Queries**: Prefer `getByRole`, `getByLabelText`, and `getByText` over `test-id`.
|
|
11
|
-
4. **Mocking**: Use `vi.mock()` for modules and **MSW (Mock Service Worker)** for API calls.
|
|
12
|
-
5. **Async Handling**: Use `findBy...` or `waitFor` to handle elements that appear after an async operation.
|
|
7
|
+
Always separate business logic from UI components. This makes testing easier and more reliable.
|
|
13
8
|
|
|
14
|
-
|
|
9
|
+
### Testing Utility Functions
|
|
10
|
+
Test pure functions that transform data or perform calculations.
|
|
15
11
|
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
```typescript
|
|
13
|
+
// utils/price.test.ts
|
|
14
|
+
import { describe, it, expect } from 'vitest'
|
|
15
|
+
import { formatCurrency } from './price'
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
describe('formatCurrency', () => {
|
|
18
|
+
it('should format numbers to VND correctly', () => {
|
|
19
|
+
expect(formatCurrency(100000)).toBe('100.000 ₫')
|
|
20
|
+
})
|
|
21
|
+
})
|
|
22
|
+
```
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const items = [{ price: 100 }, { price: 200 }];
|
|
26
|
-
const result = calculateTotal(items, 0.1);
|
|
27
|
-
expect(result).toBe(330);
|
|
28
|
-
});
|
|
29
|
-
});
|
|
24
|
+
### Testing Custom Hooks
|
|
25
|
+
Use `renderHook` to test hooks that contain state or side effects.
|
|
30
26
|
|
|
31
|
-
|
|
27
|
+
```typescript
|
|
28
|
+
// hooks/useCounter.test.ts
|
|
29
|
+
import { renderHook, act } from '@testing-library/react'
|
|
30
|
+
import { useCounter } from './useCounter'
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
it('should increment correctly', () => {
|
|
33
|
+
const { result } = renderHook(() => useCounter())
|
|
34
|
+
act(() => result.current.increment())
|
|
35
|
+
expect(result.current.count).toBe(1)
|
|
36
|
+
})
|
|
37
|
+
```
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
import { render, screen, fireEvent } from '@testing-library/react';
|
|
38
|
-
import { Button } from './Button';
|
|
39
|
+
## 2. Integration Testing (Components + Logic)
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
const handleClick = vi.fn();
|
|
42
|
-
render(<Button onClick={handleClick}>Click Me</Button>);
|
|
43
|
-
|
|
44
|
-
fireEvent.click(screen.getByText(/click me/i));
|
|
45
|
-
|
|
46
|
-
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
47
|
-
});
|
|
41
|
+
Test how the UI interacts with the underlying logic and services.
|
|
48
42
|
|
|
49
|
-
|
|
43
|
+
- **Mock Service Worker (MSW)**: Always intercept network calls. Never hit the live API during tests.
|
|
44
|
+
- **User Actions**: Use `@testing-library/user-event` for more realistic interaction simulation than `fireEvent`.
|
|
50
45
|
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
```tsx
|
|
47
|
+
// components/LoginForm.test.tsx
|
|
48
|
+
import { render, screen } from '@testing-library/react'
|
|
49
|
+
import userEvent from '@testing-library/user-event'
|
|
50
|
+
import { LoginForm } from './LoginForm'
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
render(<
|
|
52
|
+
it('should show error when login fails', async () => {
|
|
53
|
+
const user = userEvent.setup()
|
|
54
|
+
render(<LoginForm />)
|
|
57
55
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
expect(item).toBeInTheDocument();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## 4. Hooks Testing
|
|
66
|
-
Use `@testing-library/react-hooks` or the built-in `renderHook` from RTL.
|
|
67
|
-
|
|
68
|
-
// Good: Testing a custom hook
|
|
69
|
-
import { renderHook, act } from '@testing-library/react';
|
|
70
|
-
import { useCounter } from './useCounter';
|
|
71
|
-
|
|
72
|
-
it('should increment counter', () => {
|
|
73
|
-
const { result } = renderHook(() => useCounter());
|
|
56
|
+
await user.type(screen.getByLabelText(/email/i), 'wrong@example.com')
|
|
57
|
+
await user.click(screen.getByRole('button', { name: /login/i }))
|
|
74
58
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
59
|
+
expect(await screen.findByText(/invalid credentials/i)).toBeInTheDocument()
|
|
60
|
+
})
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## 3. Mocking Next.js Patterns
|
|
64
|
+
|
|
65
|
+
Next.js 15+ patterns require specific mocking strategies. Admin - Menu Management
|
|
66
|
+
|
|
67
|
+
- **Navigation**: Mock `useRouter` and `usePathname`.
|
|
68
|
+
- **Server Actions**: Wrap calls in `vi.fn()` to track submissions.
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// Setup file or top of test
|
|
72
|
+
vi.mock('next/navigation', () => ({
|
|
73
|
+
useRouter: () => ({ push: vi.fn() }),
|
|
74
|
+
usePathname: () => '/home',
|
|
75
|
+
}))
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## 4. Automated Testing Protocol for Agents
|
|
79
|
+
|
|
80
|
+
When requested to build a feature, the agent should:
|
|
81
|
+
1. **Draft the Logic**: Write the function/hook.
|
|
82
|
+
2. **Generate the Test**: Immediately create a `.test.ts(x)` file covering edge cases.
|
|
83
|
+
3. **Run Vitest**: Use `npm test` to verify logic before even building the UI.
|
|
84
|
+
4. **Connect to UI**: Build the component and add integration tests.
|
|
85
|
+
|
|
86
|
+
## Best Practices
|
|
87
|
+
1. **Coverage over UI**: prioritize testing complex logic over simple "it renders" tests.
|
|
88
|
+
2. **No implementation details**: Don't test internal state variables; test the output visible to the user.
|
|
89
|
+
3. **Environment**: Ensure `jsdom` is configured in `vitest.config.ts`.
|
|
90
|
+
4. **Clean up**: Use `afterEach(() => cleanup())` to prevent state leakage between tests.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# UX Feedback Patterns
|
|
2
|
+
|
|
3
|
+
Ensuring the application feels responsive and communicates clearly with the user. A premium app never leaves the user wondering "Is it working?".
|
|
4
|
+
|
|
5
|
+
## 1. Skeleton Screens
|
|
6
|
+
|
|
7
|
+
Always prefer skeletons over generic spinners for page transitions. Skeletons should precisely match the layout of the final content.
|
|
8
|
+
|
|
9
|
+
- **Pulse Animation**: Use a subtle pulse (`animate-pulse`) instead of a fast blink.
|
|
10
|
+
- **Shape Matching**: If it's a circle avatar, the skeleton must be a circle. If it's a 16px title, the skeleton must be 16x100px.
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
/* Simple Stat Card Skeleton */
|
|
14
|
+
<div className="p-4 rounded-xl border border-border animate-pulse">
|
|
15
|
+
<div className="h-4 w-24 bg-muted rounded mb-2" />
|
|
16
|
+
<div className="h-8 w-16 bg-muted-foreground/20 rounded" />
|
|
17
|
+
</div>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 2. Optimistic UI
|
|
21
|
+
|
|
22
|
+
For actions that are likely to succeed (like toggling a like button or marking a task as done), update the UI *before* the server responds.
|
|
23
|
+
|
|
24
|
+
- **Immediate Feedback**: The user sees the change instantly.
|
|
25
|
+
- **Rollback Logic**: If the request fails, revert the UI and show a toast.
|
|
26
|
+
|
|
27
|
+
> [!NOTE]
|
|
28
|
+
> React's `useOptimistic` hook is the standard for implementing this in Next.js.
|
|
29
|
+
|
|
30
|
+
## 3. Non-Intrusive Toasts
|
|
31
|
+
|
|
32
|
+
Use toasts for feedback on background actions (Save, Delete, Update).
|
|
33
|
+
|
|
34
|
+
- **Position**: Usually `bottom-right` or `top-center`.
|
|
35
|
+
- **Duration**: `3-5 seconds` is enough for most messages.
|
|
36
|
+
- **Interaction**: Allow users to swipe or click to dismiss early.
|
|
37
|
+
- **Icons**: Always include a small icon (Checkmark for success, Alert for error).
|
|
38
|
+
|
|
39
|
+
## 4. Empty & Error States
|
|
40
|
+
|
|
41
|
+
Never show a blank white screen when there's an error or no data.
|
|
42
|
+
|
|
43
|
+
- **Empty State**: Use an illustration or a clear message + a "Call to Action" (e.g., "No items found. Create your first one?").
|
|
44
|
+
- **Error State**: Provide a clear explanation and a "Retry" button.
|
|
45
|
+
|
|
46
|
+
## 5. Layout Transitions (Exit/Enter)
|
|
47
|
+
|
|
48
|
+
Use `<AnimatePresence>` to prevent elements from simply "disappearing" or "popping in."
|
|
49
|
+
|
|
50
|
+
- **Exit**: Fade out + slide down.
|
|
51
|
+
- **Enter**: Fade in + slide up.
|
|
52
|
+
|
|
53
|
+
## Best Practices
|
|
54
|
+
1. **Consistency**: Use the same animation durations (e.g., 200ms or 300ms) for all similar transitions.
|
|
55
|
+
2. **Avoid Flash of Unstyled Content (FOUC)**: Use server-side state or Suspense to ensure some content is ready before rendering.
|
|
56
|
+
3. **Progressive Disclosure**: Only show the most important information first; reveal details on interaction to keep the UI clean.
|