Skip to content

Commit 70b15c6

Browse files
authored
Merge pull request #431 from abyss-s/main
docs: update core concepts and figma config documentation
2 parents 70d30f4 + 5f9468b commit 70b15c6

File tree

6 files changed

+674
-0
lines changed

6 files changed

+674
-0
lines changed

apps/landing/src/app/(detail)/docs/LeftMenu.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,37 @@ export function LeftMenu() {
1818
to: '/docs/core-concepts/style-storage',
1919
children: 'Style Storage',
2020
},
21+
{
22+
to: '/docs/core-concepts/type-inference-system',
23+
children: 'Type Inference System',
24+
},
25+
{
26+
to: '/docs/core-concepts/optimize-css',
27+
children: 'Optimize CSS',
28+
},
29+
{
30+
to: '/docs/core-concepts/nm-base',
31+
children: 'N/M Base',
32+
},
2133
]}
2234
>
2335
Core Concepts
2436
</MenuItem>
2537
<MenuItem to="/docs/features">Features</MenuItem>
38+
<MenuItem
39+
subMenu={[
40+
{
41+
to: '/docs/figma-and-theme-integration/devup-figma-plugin',
42+
children: 'Devup Figma Plugin',
43+
},
44+
{
45+
to: '/docs/figma-and-theme-integration/devup-json',
46+
children: 'devup.json Configuration',
47+
},
48+
]}
49+
>
50+
Figma and Theme Integration
51+
</MenuItem>
2652
<MenuItem
2753
subMenu={[
2854
{
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
export const metadata = {
2+
title: 'N/M Base',
3+
alternates: {
4+
canonical: '/docs/core-concepts/nm-base',
5+
},
6+
}
7+
8+
# N/M Base
9+
10+
Devup UI uses a custom N/M base numbering system to generate compact, collision-free class names that are optimized for CSS constraints and ad-blocker compatibility.
11+
12+
- **Generates compact class names**: Short, efficient class names like `a`, `b`, `c`
13+
- **Avoids CSS constraints**: Class names never start with digits
14+
- **Prevents ad-blocker conflicts**: Avoids patterns that trigger content blockers
15+
- **Ensures uniqueness**: Each style gets a unique, deterministic class name
16+
- **Optimizes for size**: Minimal class name length for maximum efficiency
17+
18+
## How It Works
19+
20+
### **Base System**
21+
22+
The N/M base system uses two character sets:
23+
24+
- **N Base**: `a-z, _` (27 characters)
25+
- **M Base**: `a-z, 0-9, _` (37 characters)
26+
27+
### **Number Conversion**
28+
29+
Numbers are converted to N/M base using a two-phase approach:
30+
31+
1. **Zero handling**: Returns 'a' when the number is 0
32+
2. **Base conversion**: Uses base-26 to convert numbers to alphabetic characters
33+
- First digit: Uses N base array (a-z)
34+
- Remaining digits: Uses M base array (a-z)
35+
3. **Ad-blocker conflict prevention**: Changes result to "a-d" if it ends with "ad"
36+
37+
### **Class Name Generation**
38+
39+
Class name generation follows these steps:
40+
41+
1. **Style signature creation**: Combines property, level, value, selector, and style order to create a unique key
42+
2. **File identifier addition**: Converts filename to number for per-file CSS splitting
43+
3. **Sequential number assignment**: Assigns a sequential number based on the order of unique styles in the GLOBAL_CLASS_MAP
44+
4. **N/M base conversion**: Converts the sequential number to an alphabetic class name using the N/M base system
45+
5. **Final combination**: Combines file identifier and class number to create the final class name when file identifier exists
46+
47+
## Examples
48+
49+
### **Basic Class Names**
50+
51+
<div
52+
style={{
53+
display: 'grid',
54+
gridTemplateColumns: '1fr 1fr',
55+
gap: '2rem',
56+
marginBottom: '2rem',
57+
alignItems: 'start',
58+
}}
59+
>
60+
<div>
61+
```tsx // Input
62+
<div>
63+
<Box bg="red" />
64+
<Box bg="blue" />
65+
<Box color="white" />
66+
</div>
67+
```
68+
</div>
69+
<div>
70+
```tsx // Output (N/M base class names)
71+
<div>
72+
<Box className="a" /> {/* bg: red */}
73+
<Box className="b" /> {/* bg: blue */}
74+
<Box className="c" /> {/* color: white */}
75+
</div>
76+
```
77+
</div>
78+
</div>
79+
80+
### **Responsive Class Names**
81+
82+
<div
83+
style={{
84+
display: 'grid',
85+
gridTemplateColumns: '1fr 1fr',
86+
gap: '2rem',
87+
marginBottom: '2rem',
88+
alignItems: 'start',
89+
}}
90+
>
91+
<div>
92+
```tsx // Input
93+
<Box w={[100, 200, 300]} />
94+
```
95+
</div>
96+
<div>
97+
```tsx // Output
98+
<Box className="d e f" />
99+
{/* w: 100px, w: 200px, w: 300px */}
100+
```
101+
</div>
102+
</div>
103+
104+
### **Pseudo-selector Class Names**
105+
106+
<div
107+
style={{
108+
display: 'grid',
109+
gridTemplateColumns: '1fr 1fr',
110+
gap: '2rem',
111+
marginBottom: '2rem',
112+
alignItems: 'start',
113+
}}
114+
>
115+
<div>
116+
```tsx
117+
<Box _hover={{ bg: 'red' }} />
118+
```
119+
</div>
120+
<div>
121+
```tsx
122+
<Box className="g" />
123+
{/* .g:hover { background: red; } */}
124+
```
125+
</div>
126+
</div>
127+
128+
### **File-specific Class Names**
129+
130+
<div
131+
style={{
132+
display: 'grid',
133+
gridTemplateColumns: '1fr 1fr',
134+
gap: '2rem',
135+
marginBottom: '2rem',
136+
alignItems: 'start',
137+
}}
138+
>
139+
<div>
140+
```tsx
141+
<div>
142+
<Box bg="red" />
143+
<Box bg="red" />
144+
</div>
145+
```
146+
</div>
147+
<div>
148+
```tsx
149+
<div>
150+
<Box className="a" /> {/* file1.tsx */}
151+
<Box className="a-a" /> {/* file2.tsx */}
152+
</div>
153+
```
154+
</div>
155+
</div>
156+
157+
## Ad-blocker Compatibility
158+
159+
### **Why "ad" is Problematic**
160+
161+
Ad-blockers recognize and block class names containing "ad" patterns as advertisements:
162+
163+
- **Ad-blocker filters**: Classify elements containing "ad" strings as advertisements
164+
- **CSS blocking**: Styles are not applied, causing UI to break
165+
- **Poor user experience**: Unintended style blocking causes layout issues
166+
167+
### **Our Solution**
168+
169+
Devup UI prevents ad-blocker conflicts through the following methods:
170+
171+
- **Pattern avoidance**: Automatically converts class names ending with "ad" to "a-d"
172+
- **Safe character usage**: Uses only `a-z`, `-`, `_` to avoid blocking patterns
173+
- **No numbers**: Ensures class names don't start with digits to comply with CSS constraints
174+
175+
## Advantages
176+
177+
- **Compact class names**: First 26 styles generate single characters like `a`, `b`, `c`
178+
- **Build consistency**: Always generates the same class name for identical input
179+
- **Cache optimization**: Consistent class names improve browser cache efficiency
180+
- **Collision prevention**: Each style has a unique signature to prevent class name collisions
181+
- **Ad-blocker compatibility**: Automatically converts "ad" patterns to "a-d" to prevent blocking
182+
- **CSS constraint compliance**: Class names don't start with digits to comply with CSS rules

0 commit comments

Comments
 (0)