bem-wind 0.1.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/README.md +215 -0
- package/bin/bem-wind.js +106 -0
- package/dist/generate/index.d.ts +6 -0
- package/dist/generate/index.d.ts.map +1 -0
- package/dist/generate/index.js +49 -0
- package/dist/generate/index.js.map +1 -0
- package/dist/generate/templates.d.ts +3 -0
- package/dist/generate/templates.d.ts.map +1 -0
- package/dist/generate/templates.js +80 -0
- package/dist/generate/templates.js.map +1 -0
- package/dist/generate/utils.d.ts +2 -0
- package/dist/generate/utils.d.ts.map +1 -0
- package/dist/generate/utils.js +24 -0
- package/dist/generate/utils.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/lint/index.d.ts +5 -0
- package/dist/lint/index.d.ts.map +1 -0
- package/dist/lint/index.js +38 -0
- package/dist/lint/index.js.map +1 -0
- package/dist/setup/generators.d.ts +11 -0
- package/dist/setup/generators.d.ts.map +1 -0
- package/dist/setup/generators.js +101 -0
- package/dist/setup/generators.js.map +1 -0
- package/dist/setup/index.d.ts +8 -0
- package/dist/setup/index.d.ts.map +1 -0
- package/dist/setup/index.js +100 -0
- package/dist/setup/index.js.map +1 -0
- package/dist/setup/templates.d.ts +10 -0
- package/dist/setup/templates.d.ts.map +1 -0
- package/dist/setup/templates.js +370 -0
- package/dist/setup/templates.js.map +1 -0
- package/package.json +65 -0
- package/scripts/sync-skill.js +22 -0
- package/skill/bem-wind/SKILL.md +106 -0
- package/skill/bem-wind/reference/examples.md +206 -0
- package/skill/bem-wind/reference/tokens.css +134 -0
package/README.md
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# BEM-Wind CLI
|
|
2
|
+
|
|
3
|
+
A powerful CLI tool to setup and manage BEM-Wind design systems with Tailwind, SCSS, and intelligent linting.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g bem-wind
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or use directly with npx:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx bem-wind init
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Commands
|
|
18
|
+
|
|
19
|
+
### `bem-wind init`
|
|
20
|
+
|
|
21
|
+
Sets up BEM-Wind in your current project with:
|
|
22
|
+
- ✨ Custom component prefix (auto-detected from project name)
|
|
23
|
+
- 🎨 Tailwind CSS configuration with BEM-Wind integration
|
|
24
|
+
- 📦 SCSS architecture with core tokens, primitives, and themes
|
|
25
|
+
- 🛡️ Stylelint and ESLint rules for design system compliance
|
|
26
|
+
- 📚 Documentation and examples
|
|
27
|
+
|
|
28
|
+
**Options:**
|
|
29
|
+
- `-p, --prefix <prefix>` - Custom component prefix (default: project name)
|
|
30
|
+
- `-t, --theme <theme>` - Theme template to use (default: 'default')
|
|
31
|
+
- `-f, --framework <framework>` - Framework (react, vue, astro) (default: 'react')
|
|
32
|
+
- `--skip-install` - Skip npm install
|
|
33
|
+
|
|
34
|
+
**Example:**
|
|
35
|
+
```bash
|
|
36
|
+
# Interactive setup
|
|
37
|
+
npx bem-wind init
|
|
38
|
+
|
|
39
|
+
# Custom prefix
|
|
40
|
+
npx bem-wind init --prefix "myapp"
|
|
41
|
+
|
|
42
|
+
# Skip dependency installation
|
|
43
|
+
npx bem-wind init --skip-install
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### `bem-wind add-skill`
|
|
47
|
+
|
|
48
|
+
Installs the BEM-Wind **Claude skill** into your `.claude/skills` directory, so Claude Code writes and reviews CSS using the BEM-Wind methodology automatically.
|
|
49
|
+
|
|
50
|
+
**Options:**
|
|
51
|
+
- `-g, --global` - Install into `~/.claude/skills` (all projects) instead of `./.claude/skills`
|
|
52
|
+
- `--force` - Overwrite an existing install
|
|
53
|
+
|
|
54
|
+
**Examples:**
|
|
55
|
+
```bash
|
|
56
|
+
# Add the skill to the current project (commit it to share with your team)
|
|
57
|
+
npx bem-wind add-skill
|
|
58
|
+
|
|
59
|
+
# Add it globally for every project on your machine
|
|
60
|
+
npx bem-wind add-skill --global
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Then ask Claude to style or convert a component, or invoke it explicitly with `/bem-wind`.
|
|
64
|
+
|
|
65
|
+
### `bem-wind component <name>`
|
|
66
|
+
|
|
67
|
+
Generates a new BEM-Wind component with proper structure and documentation.
|
|
68
|
+
|
|
69
|
+
**Options:**
|
|
70
|
+
- `-p, --prefix <prefix>` - Component prefix (uses project default)
|
|
71
|
+
- `-t, --type <type>` - Component type: element, pattern, layout (default: 'element')
|
|
72
|
+
|
|
73
|
+
**Examples:**
|
|
74
|
+
```bash
|
|
75
|
+
# Generate a button element
|
|
76
|
+
npx bem-wind component button
|
|
77
|
+
|
|
78
|
+
# Generate a hero pattern
|
|
79
|
+
npx bem-wind component hero --type pattern
|
|
80
|
+
|
|
81
|
+
# Generate a sidebar layout
|
|
82
|
+
npx bem-wind component sidebar --type layout
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### `bem-wind lint`
|
|
86
|
+
|
|
87
|
+
Runs comprehensive linting rules for BEM-Wind compliance:
|
|
88
|
+
- 🚫 Prevents decimal arbitrary values (`translate-y-0.5`)
|
|
89
|
+
- ✅ Enforces BEM naming conventions
|
|
90
|
+
- 📏 Validates semantic spacing usage
|
|
91
|
+
- 🎯 Checks @apply directive usage
|
|
92
|
+
|
|
93
|
+
**Options:**
|
|
94
|
+
- `--fix` - Auto-fix issues where possible
|
|
95
|
+
|
|
96
|
+
**Examples:**
|
|
97
|
+
```bash
|
|
98
|
+
# Check for issues
|
|
99
|
+
npx bem-wind lint
|
|
100
|
+
|
|
101
|
+
# Auto-fix issues
|
|
102
|
+
npx bem-wind lint --fix
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## What Gets Created
|
|
106
|
+
|
|
107
|
+
When you run `bem-wind init`, you get:
|
|
108
|
+
|
|
109
|
+
### Directory Structure
|
|
110
|
+
```
|
|
111
|
+
src/styles/bem-wind/
|
|
112
|
+
├── core/
|
|
113
|
+
│ └── tokens.css # Design tokens & CSS variables
|
|
114
|
+
├── primitives/
|
|
115
|
+
│ ├── elements/ # Button, Card, Input, etc.
|
|
116
|
+
│ ├── patterns/ # Hero, Navigation, Footer, etc.
|
|
117
|
+
│ └── layouts/ # Grid, Container, Sidebar, etc.
|
|
118
|
+
├── themes/
|
|
119
|
+
│ └── default.scss # Project-specific styling
|
|
120
|
+
├── utilities/ # Helper classes
|
|
121
|
+
└── main.scss # Main entry point
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Configuration Files
|
|
125
|
+
- `tailwind.config.js` - Tailwind setup with BEM-Wind integration
|
|
126
|
+
- `postcss.config.js` - PostCSS configuration
|
|
127
|
+
- `.stylelintrc.json` - Stylelint rules for BEM compliance
|
|
128
|
+
- `.eslintrc.bem-wind.js` - ESLint rules for @apply usage
|
|
129
|
+
- `.bem-wind.json` - Project configuration
|
|
130
|
+
|
|
131
|
+
### Documentation
|
|
132
|
+
- `BEM-WIND-README.md` - Project-specific usage guide
|
|
133
|
+
- Component examples and usage patterns
|
|
134
|
+
|
|
135
|
+
## Features
|
|
136
|
+
|
|
137
|
+
### 🎯 **Smart Prefix Detection**
|
|
138
|
+
Automatically detects your project name and suggests an appropriate component prefix.
|
|
139
|
+
|
|
140
|
+
### 🛡️ **Intelligent Linting**
|
|
141
|
+
- Prevents decimal arbitrary values like `translate-y-0.5`
|
|
142
|
+
- Enforces semantic spacing from Tailwind scale
|
|
143
|
+
- Validates BEM naming conventions
|
|
144
|
+
- Checks for proper @apply usage
|
|
145
|
+
|
|
146
|
+
### 📦 **Component Scaffolding**
|
|
147
|
+
Generates properly structured components with:
|
|
148
|
+
- BEM methodology
|
|
149
|
+
- @apply directives only
|
|
150
|
+
- Semantic class names
|
|
151
|
+
- Documentation comments
|
|
152
|
+
|
|
153
|
+
### 🎨 **Theme System**
|
|
154
|
+
- Unstyled primitives that work with any design
|
|
155
|
+
- Project-specific theme overrides
|
|
156
|
+
- CSS custom properties for design tokens
|
|
157
|
+
- Direct Figma-to-code mapping
|
|
158
|
+
|
|
159
|
+
### ⚡ **Framework Agnostic**
|
|
160
|
+
Works with React, Vue, Astro, or any HTML/CSS project.
|
|
161
|
+
|
|
162
|
+
## Example Output
|
|
163
|
+
|
|
164
|
+
After running `bem-wind init --prefix "myapp"`, you can immediately use:
|
|
165
|
+
|
|
166
|
+
```html
|
|
167
|
+
<button class="myapp-button myapp-button--primary myapp-button--large">
|
|
168
|
+
<span class="myapp-button__icon">🚀</span>
|
|
169
|
+
<span class="myapp-button__text">Get Started</span>
|
|
170
|
+
</button>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
With styling that automatically adapts to your theme:
|
|
174
|
+
|
|
175
|
+
```scss
|
|
176
|
+
.myapp-button {
|
|
177
|
+
@apply inline-flex items-center justify-center cursor-pointer;
|
|
178
|
+
@apply py-4 px-6 text-lg gap-3; // Large size
|
|
179
|
+
@apply transition-all duration-300 ease-in-out;
|
|
180
|
+
|
|
181
|
+
&--primary {
|
|
182
|
+
@apply bg-primary text-white; // Theme colors
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Best Practices
|
|
188
|
+
|
|
189
|
+
### ✅ **Do This**
|
|
190
|
+
```scss
|
|
191
|
+
.myapp-card {
|
|
192
|
+
@apply p-4 mb-6 rounded-lg; // Standard Tailwind scale
|
|
193
|
+
@apply max-w-[400px]; // Logical arbitrary values
|
|
194
|
+
@apply transition-all duration-300; // Semantic timing
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### ❌ **Don't Do This**
|
|
199
|
+
```scss
|
|
200
|
+
.myapp-card {
|
|
201
|
+
@apply p-3.5 mb-5.5; // Decimal values
|
|
202
|
+
padding: 14px; // Raw CSS when @apply available
|
|
203
|
+
transition: all 250ms; // Non-semantic timing
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Support
|
|
208
|
+
|
|
209
|
+
- 📖 [Full Documentation](./BEM-WIND-MANUAL.md)
|
|
210
|
+
- 🐛 [Report Issues](https://github.com/your-username/bem-wind/issues)
|
|
211
|
+
- 💬 [Discussions](https://github.com/your-username/bem-wind/discussions)
|
|
212
|
+
|
|
213
|
+
## License
|
|
214
|
+
|
|
215
|
+
MIT © Taryn Southern
|
package/bin/bem-wind.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { program } = require('commander');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
|
|
7
|
+
// Import setup module directly
|
|
8
|
+
const { setupProject } = require('../dist/setup');
|
|
9
|
+
|
|
10
|
+
// Resolve the bundled Claude skill, falling back to the repo source in dev.
|
|
11
|
+
function resolveSkillDir() {
|
|
12
|
+
const candidates = [
|
|
13
|
+
path.join(__dirname, '..', 'skill', 'bem-wind'), // bundled in npm tarball
|
|
14
|
+
path.join(__dirname, '..', '..', '..', 'skill', 'bem-wind'), // repo source of truth (dev)
|
|
15
|
+
];
|
|
16
|
+
return candidates.find((p) => fs.existsSync(path.join(p, 'SKILL.md')));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
program
|
|
20
|
+
.name('bem-wind')
|
|
21
|
+
.description('Setup BEM-Wind design system with Tailwind, SCSS, and linting')
|
|
22
|
+
.version('1.0.0');
|
|
23
|
+
|
|
24
|
+
program
|
|
25
|
+
.command('init')
|
|
26
|
+
.description('Initialize BEM-Wind in current project')
|
|
27
|
+
.option('-p, --prefix <prefix>', 'Custom component prefix (default: project name)', '')
|
|
28
|
+
.option('-t, --theme <theme>', 'Theme template to use', 'default')
|
|
29
|
+
.option('-f, --framework <framework>', 'Framework (react, vue, astro)', 'react')
|
|
30
|
+
.option('--skip-install', 'Skip npm install', false)
|
|
31
|
+
.action(async (options) => {
|
|
32
|
+
try {
|
|
33
|
+
await setupProject(process.cwd(), options);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.error('Error setting up BEM-Wind:', error.message);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
program
|
|
41
|
+
.command('component <name>')
|
|
42
|
+
.description('Generate a new BEM-Wind component')
|
|
43
|
+
.option('-p, --prefix <prefix>', 'Component prefix', '')
|
|
44
|
+
.option('-t, --type <type>', 'Component type (element, pattern, layout)', 'element')
|
|
45
|
+
.action(async (name, options) => {
|
|
46
|
+
try {
|
|
47
|
+
const { generateComponent } = require('../dist/generate');
|
|
48
|
+
await generateComponent(process.cwd(), name, options);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error('Error generating component:', error.message);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
program
|
|
56
|
+
.command('lint')
|
|
57
|
+
.description('Run BEM-Wind linting rules')
|
|
58
|
+
.option('--fix', 'Auto-fix issues where possible', false)
|
|
59
|
+
.action(async (options) => {
|
|
60
|
+
try {
|
|
61
|
+
const { runLinting } = require('../dist/lint');
|
|
62
|
+
await runLinting(process.cwd(), options);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error('Error running linting:', error.message);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
program
|
|
70
|
+
.command('add-skill')
|
|
71
|
+
.description('Install the BEM-Wind Claude skill into .claude/skills')
|
|
72
|
+
.option('-g, --global', 'Install into ~/.claude/skills instead of ./.claude/skills', false)
|
|
73
|
+
.option('--force', 'Overwrite an existing install', false)
|
|
74
|
+
.action((options) => {
|
|
75
|
+
try {
|
|
76
|
+
const skillDir = resolveSkillDir();
|
|
77
|
+
if (!skillDir) {
|
|
78
|
+
console.error('Error: bundled BEM-Wind skill not found in this package.');
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const baseDir = options.global
|
|
83
|
+
? path.join(require('os').homedir(), '.claude', 'skills')
|
|
84
|
+
: path.join(process.cwd(), '.claude', 'skills');
|
|
85
|
+
const target = path.join(baseDir, 'bem-wind');
|
|
86
|
+
|
|
87
|
+
if (fs.existsSync(target) && !options.force) {
|
|
88
|
+
console.error(`Skill already exists at ${target}. Re-run with --force to overwrite.`);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
fs.rmSync(target, { recursive: true, force: true });
|
|
93
|
+
fs.mkdirSync(baseDir, { recursive: true });
|
|
94
|
+
fs.cpSync(skillDir, target, { recursive: true });
|
|
95
|
+
|
|
96
|
+
console.log(`✓ Installed BEM-Wind skill → ${target}`);
|
|
97
|
+
console.log(options.global
|
|
98
|
+
? ' Active across all your projects. Invoke it with /bem-wind in Claude Code.'
|
|
99
|
+
: ' Active in this project. Commit .claude/skills/bem-wind to share it with your team.');
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error('Error installing skill:', error.message);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
program.parse();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generate/index.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;CACzC;AAED,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,gBAAgB,iBAgD1B"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateComponent = generateComponent;
|
|
7
|
+
const ora_1 = __importDefault(require("ora"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const mustache_1 = __importDefault(require("mustache"));
|
|
12
|
+
const templates_1 = require("./templates");
|
|
13
|
+
const utils_1 = require("./utils");
|
|
14
|
+
async function generateComponent(projectPath, name, options) {
|
|
15
|
+
const spinner = (0, ora_1.default)(`Generating component: ${name}`).start();
|
|
16
|
+
try {
|
|
17
|
+
const configPath = path_1.default.join(projectPath, '.bem-wind.json');
|
|
18
|
+
let config = { prefix: 'bw' };
|
|
19
|
+
if (await fs_extra_1.default.pathExists(configPath)) {
|
|
20
|
+
config = await fs_extra_1.default.readJSON(configPath);
|
|
21
|
+
}
|
|
22
|
+
const prefix = options.prefix || config.prefix;
|
|
23
|
+
const componentType = options.type || 'element';
|
|
24
|
+
const componentPath = path_1.default.join(projectPath, 'src/styles/bem-wind/primitives', `${componentType}s`, `${name}.scss`);
|
|
25
|
+
const template = (0, templates_1.getComponentTemplate)(componentType);
|
|
26
|
+
const rendered = mustache_1.default.render(template, {
|
|
27
|
+
name,
|
|
28
|
+
prefix,
|
|
29
|
+
className: `${prefix}-${name}`,
|
|
30
|
+
blockName: name.charAt(0).toUpperCase() + name.slice(1),
|
|
31
|
+
});
|
|
32
|
+
await fs_extra_1.default.writeFile(componentPath, rendered);
|
|
33
|
+
await (0, utils_1.updateMainImports)(projectPath, componentType, name);
|
|
34
|
+
spinner.succeed(chalk_1.default.green(`Component ${name} generated! 📦`));
|
|
35
|
+
console.log(chalk_1.default.cyan(`\nComponent created at:`));
|
|
36
|
+
console.log(chalk_1.default.gray(componentPath));
|
|
37
|
+
console.log(chalk_1.default.cyan(`\nUsage:`));
|
|
38
|
+
console.log(chalk_1.default.gray(`<div class="${prefix}-${name}">`));
|
|
39
|
+
console.log(chalk_1.default.gray(` <div class="${prefix}-${name}__content">`));
|
|
40
|
+
console.log(chalk_1.default.gray(` <!-- Your content -->`));
|
|
41
|
+
console.log(chalk_1.default.gray(` </div>`));
|
|
42
|
+
console.log(chalk_1.default.gray(`</div>`));
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
spinner.fail(chalk_1.default.red('Component generation failed'));
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generate/index.ts"],"names":[],"mappings":";;;;;AAaA,8CAmDC;AAhED,8CAAsB;AACtB,kDAA0B;AAC1B,wDAA0B;AAC1B,gDAAwB;AACxB,wDAAgC;AAChC,2CAAmD;AACnD,mCAA4C;AAOrC,KAAK,UAAU,iBAAiB,CACrC,WAAmB,EACnB,IAAY,EACZ,OAAyB;IAEzB,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;IAE7D,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;QAC5D,IAAI,MAAM,GAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAEnC,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACpC,MAAM,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACzC,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;QAC/C,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;QAEhD,MAAM,aAAa,GAAG,cAAI,CAAC,IAAI,CAC7B,WAAW,EACX,gCAAgC,EAChC,GAAG,aAAa,GAAG,EACnB,GAAG,IAAI,OAAO,CACf,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAA,gCAAoB,EAAC,aAAa,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,kBAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE;YACzC,IAAI;YACJ,MAAM;YACN,SAAS,EAAE,GAAG,MAAM,IAAI,IAAI,EAAE;YAC9B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;SACxD,CAAC,CAAC;QAEH,MAAM,kBAAE,CAAC,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QAE5C,MAAM,IAAA,yBAAiB,EAAC,WAAW,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;QAE1D,OAAO,CAAC,OAAO,CAAC,eAAK,CAAC,KAAK,CAAC,aAAa,IAAI,gBAAgB,CAAC,CAAC,CAAC;QAEhE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,eAAe,MAAM,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,iBAAiB,MAAM,IAAI,IAAI,aAAa,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,eAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC,CAAC;QACvD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/generate/templates.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAuE5C,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.templates = void 0;
|
|
4
|
+
exports.getComponentTemplate = getComponentTemplate;
|
|
5
|
+
exports.templates = {
|
|
6
|
+
element: `/**
|
|
7
|
+
* {{blockName}} Element
|
|
8
|
+
*
|
|
9
|
+
* {{prefix}}-{{name}} provides {{name}} structure and behavior
|
|
10
|
+
* without any visual styling.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
.{{className}} {
|
|
14
|
+
@apply /* Add your base styles here */;
|
|
15
|
+
|
|
16
|
+
/* Element children */
|
|
17
|
+
&__content {
|
|
18
|
+
@apply /* Content styles */;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Modifiers */
|
|
22
|
+
&--variant {
|
|
23
|
+
@apply /* Variant styles */;
|
|
24
|
+
}
|
|
25
|
+
}`,
|
|
26
|
+
pattern: `/**
|
|
27
|
+
* {{blockName}} Pattern
|
|
28
|
+
*
|
|
29
|
+
* {{prefix}}-{{name}} provides a reusable {{name}} pattern
|
|
30
|
+
* combining multiple elements.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
.{{className}} {
|
|
34
|
+
@apply /* Pattern base styles */;
|
|
35
|
+
|
|
36
|
+
&__container {
|
|
37
|
+
@apply /* Container styles */;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
&__content {
|
|
41
|
+
@apply /* Content area styles */;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Pattern variants */
|
|
45
|
+
&--centered {
|
|
46
|
+
@apply /* Centered variant */;
|
|
47
|
+
}
|
|
48
|
+
}`,
|
|
49
|
+
layout: `/**
|
|
50
|
+
* {{blockName}} Layout
|
|
51
|
+
*
|
|
52
|
+
* {{prefix}}-{{name}} provides layout structure
|
|
53
|
+
* for page composition.
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
.{{className}} {
|
|
57
|
+
@apply /* Layout base styles */;
|
|
58
|
+
|
|
59
|
+
&__wrapper {
|
|
60
|
+
@apply /* Wrapper styles */;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&__main {
|
|
64
|
+
@apply /* Main content area */;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&__sidebar {
|
|
68
|
+
@apply /* Sidebar area */;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* Responsive variants */
|
|
72
|
+
&--responsive {
|
|
73
|
+
@apply /* Responsive behavior */;
|
|
74
|
+
}
|
|
75
|
+
}`,
|
|
76
|
+
};
|
|
77
|
+
function getComponentTemplate(type) {
|
|
78
|
+
return exports.templates[type] || exports.templates.element;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/generate/templates.ts"],"names":[],"mappings":";;;AAyEA,oDAEC;AA3EY,QAAA,SAAS,GAA2B;IAC/C,OAAO,EAAE;;;;;;;;;;;;;;;;;;;EAmBT;IACA,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;EAsBT;IACA,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BR;CACD,CAAC;AAEF,SAAgB,oBAAoB,CAAC,IAAY;IAC/C,OAAO,iBAAS,CAAC,IAA8B,CAAC,IAAI,iBAAS,CAAC,OAAO,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/generate/utils.ts"],"names":[],"mappings":"AAGA,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,iBAiBb"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.updateMainImports = updateMainImports;
|
|
7
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
async function updateMainImports(projectPath, componentType, name) {
|
|
10
|
+
const mainScssPath = path_1.default.join(projectPath, 'src/styles/bem-wind/main.scss');
|
|
11
|
+
if (await fs_extra_1.default.pathExists(mainScssPath)) {
|
|
12
|
+
let content = await fs_extra_1.default.readFile(mainScssPath, 'utf8');
|
|
13
|
+
const importLine = `@import './primitives/${componentType}s/${name}.scss';`;
|
|
14
|
+
if (!content.includes(importLine)) {
|
|
15
|
+
const importSection = content.match(/\/\* Primitive components \*\/([\s\S]*?)\/\* Theme styling \*\//);
|
|
16
|
+
if (importSection) {
|
|
17
|
+
const newImportSection = importSection[1] + importLine + '\n';
|
|
18
|
+
content = content.replace(importSection[1], newImportSection);
|
|
19
|
+
await fs_extra_1.default.writeFile(mainScssPath, content);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/generate/utils.ts"],"names":[],"mappings":";;;;;AAGA,8CAoBC;AAvBD,wDAA0B;AAC1B,gDAAwB;AAEjB,KAAK,UAAU,iBAAiB,CACrC,WAAmB,EACnB,aAAqB,EACrB,IAAY;IAEZ,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,+BAA+B,CAAC,CAAC;IAE7E,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACtC,IAAI,OAAO,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,UAAU,GAAG,yBAAyB,aAAa,KAAK,IAAI,SAAS,CAAC;QAE5E,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;YACvG,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,gBAAgB,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,UAAU,GAAG,IAAI,CAAC;gBAC9D,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;gBAC9D,MAAM,kBAAE,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runLinting = exports.generateComponent = exports.setupProject = void 0;
|
|
4
|
+
var setup_1 = require("./setup");
|
|
5
|
+
Object.defineProperty(exports, "setupProject", { enumerable: true, get: function () { return setup_1.setupProject; } });
|
|
6
|
+
var generate_1 = require("./generate");
|
|
7
|
+
Object.defineProperty(exports, "generateComponent", { enumerable: true, get: function () { return generate_1.generateComponent; } });
|
|
8
|
+
var lint_1 = require("./lint");
|
|
9
|
+
Object.defineProperty(exports, "runLinting", { enumerable: true, get: function () { return lint_1.runLinting; } });
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iCAAqD;AAA5C,qGAAA,YAAY,OAAA;AACrB,uCAAiE;AAAxD,6GAAA,iBAAiB,OAAA;AAC1B,+BAAiD;AAAxC,kGAAA,UAAU,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lint/index.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,iBA6BzE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runLinting = runLinting;
|
|
7
|
+
const ora_1 = __importDefault(require("ora"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
async function runLinting(projectPath, options) {
|
|
11
|
+
const spinner = (0, ora_1.default)('Running BEM-Wind linting...').start();
|
|
12
|
+
try {
|
|
13
|
+
const stylelintCommand = `npx stylelint "src/**/*.{css,scss}" ${options.fix ? '--fix' : ''}`;
|
|
14
|
+
(0, child_process_1.execSync)(stylelintCommand, { stdio: 'pipe', cwd: projectPath });
|
|
15
|
+
try {
|
|
16
|
+
const eslintCommand = `npx eslint "src/**/*.{js,jsx,ts,tsx}" ${options.fix ? '--fix' : ''}`;
|
|
17
|
+
(0, child_process_1.execSync)(eslintCommand, { stdio: 'pipe', cwd: projectPath });
|
|
18
|
+
}
|
|
19
|
+
catch (eslintError) {
|
|
20
|
+
// ESLint might not be configured
|
|
21
|
+
}
|
|
22
|
+
spinner.succeed(chalk_1.default.green('Linting completed successfully! ✨'));
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
spinner.fail(chalk_1.default.red('Linting found issues'));
|
|
26
|
+
try {
|
|
27
|
+
(0, child_process_1.execSync)(`npx stylelint "src/**/*.{css,scss}"`, {
|
|
28
|
+
stdio: 'inherit',
|
|
29
|
+
cwd: projectPath,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
// Error already shown
|
|
34
|
+
}
|
|
35
|
+
throw new Error('Linting failed - see output above');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lint/index.ts"],"names":[],"mappings":";;;;;AAQA,gCA6BC;AArCD,8CAAsB;AACtB,kDAA0B;AAC1B,iDAAyC;AAMlC,KAAK,UAAU,UAAU,CAAC,WAAmB,EAAE,OAAoB;IACxE,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,6BAA6B,CAAC,CAAC,KAAK,EAAE,CAAC;IAE3D,IAAI,CAAC;QACH,MAAM,gBAAgB,GAAG,uCAAuC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC7F,IAAA,wBAAQ,EAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;QAEhE,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,yCAAyC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC5F,IAAA,wBAAQ,EAAC,aAAa,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,WAAW,EAAE,CAAC;YACrB,iCAAiC;QACnC,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,eAAK,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC;IACpE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,eAAK,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAEhD,IAAI,CAAC;YACH,IAAA,wBAAQ,EAAC,qCAAqC,EAAE;gBAC9C,KAAK,EAAE,SAAS;gBAChB,GAAG,EAAE,WAAW;aACjB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,sBAAsB;QACxB,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function generateTailwindConfig(projectPath: string, _prefix: string): Promise<void>;
|
|
2
|
+
export declare function generatePostCSSConfig(projectPath: string): Promise<void>;
|
|
3
|
+
export declare function generateStylelintConfig(projectPath: string, prefix: string): Promise<void>;
|
|
4
|
+
export declare function generateESLintConfig(projectPath: string, prefix: string): Promise<void>;
|
|
5
|
+
export declare function generateCoreTokens(bemWindPath: string, prefix: string): Promise<void>;
|
|
6
|
+
export declare function generateBaseComponents(bemWindPath: string, prefix: string): Promise<void>;
|
|
7
|
+
export declare function generateTheme(bemWindPath: string, prefix: string, theme: string): Promise<void>;
|
|
8
|
+
export declare function generateMainScss(bemWindPath: string, prefix: string): Promise<void>;
|
|
9
|
+
export declare function generateComponentConfig(projectPath: string, prefix: string): Promise<void>;
|
|
10
|
+
export declare function generateReadme(projectPath: string, prefix: string): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=generators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/setup/generators.ts"],"names":[],"mappings":"AAeA,wBAAsB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBAEhF;AAED,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,MAAM,iBAE9D;AAED,wBAAsB,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAiChF;AAED,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAM7E;AAED,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAG3E;AAED,wBAAsB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAsB/E;AAED,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,iBAOd;AAED,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAGzE;AAED,wBAAsB,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAYhF;AAED,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAMvE"}
|