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.
Files changed (39) hide show
  1. package/README.md +215 -0
  2. package/bin/bem-wind.js +106 -0
  3. package/dist/generate/index.d.ts +6 -0
  4. package/dist/generate/index.d.ts.map +1 -0
  5. package/dist/generate/index.js +49 -0
  6. package/dist/generate/index.js.map +1 -0
  7. package/dist/generate/templates.d.ts +3 -0
  8. package/dist/generate/templates.d.ts.map +1 -0
  9. package/dist/generate/templates.js +80 -0
  10. package/dist/generate/templates.js.map +1 -0
  11. package/dist/generate/utils.d.ts +2 -0
  12. package/dist/generate/utils.d.ts.map +1 -0
  13. package/dist/generate/utils.js +24 -0
  14. package/dist/generate/utils.js.map +1 -0
  15. package/dist/index.d.ts +4 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +10 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/lint/index.d.ts +5 -0
  20. package/dist/lint/index.d.ts.map +1 -0
  21. package/dist/lint/index.js +38 -0
  22. package/dist/lint/index.js.map +1 -0
  23. package/dist/setup/generators.d.ts +11 -0
  24. package/dist/setup/generators.d.ts.map +1 -0
  25. package/dist/setup/generators.js +101 -0
  26. package/dist/setup/generators.js.map +1 -0
  27. package/dist/setup/index.d.ts +8 -0
  28. package/dist/setup/index.d.ts.map +1 -0
  29. package/dist/setup/index.js +100 -0
  30. package/dist/setup/index.js.map +1 -0
  31. package/dist/setup/templates.d.ts +10 -0
  32. package/dist/setup/templates.d.ts.map +1 -0
  33. package/dist/setup/templates.js +370 -0
  34. package/dist/setup/templates.js.map +1 -0
  35. package/package.json +65 -0
  36. package/scripts/sync-skill.js +22 -0
  37. package/skill/bem-wind/SKILL.md +106 -0
  38. package/skill/bem-wind/reference/examples.md +206 -0
  39. 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
@@ -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,6 @@
1
+ export interface ComponentOptions {
2
+ prefix?: string;
3
+ type?: 'element' | 'pattern' | 'layout';
4
+ }
5
+ export declare function generateComponent(projectPath: string, name: string, options: ComponentOptions): Promise<void>;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -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,3 @@
1
+ export declare const templates: Record<string, string>;
2
+ export declare function getComponentTemplate(type: string): string;
3
+ //# sourceMappingURL=templates.d.ts.map
@@ -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,2 @@
1
+ export declare function updateMainImports(projectPath: string, componentType: string, name: string): Promise<void>;
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -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"}
@@ -0,0 +1,4 @@
1
+ export { setupProject, SetupOptions } from './setup';
2
+ export { generateComponent, ComponentOptions } from './generate';
3
+ export { runLinting, LintOptions } from './lint';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -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,5 @@
1
+ export interface LintOptions {
2
+ fix?: boolean;
3
+ }
4
+ export declare function runLinting(projectPath: string, options: LintOptions): Promise<void>;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -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"}