bemoji-postcss 1.0.0-beta.1

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 (2) hide show
  1. package/package.json +18 -0
  2. package/src/index.js +101 -0
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "bemoji-postcss",
3
+ "version": "1.0.0-beta.1",
4
+ "description": "PostCSS plugin for BEMoji — transforms readable BEM names to emoji class names at build time.",
5
+ "main": "src/index.js",
6
+ "scripts": {
7
+ "test": "vitest run --passWithNoTests"
8
+ },
9
+ "keywords": ["postcss-plugin", "bemoji", "css", "emoji", "bem"],
10
+ "license": "MIT",
11
+ "peerDependencies": {
12
+ "postcss": ">=8.0.0"
13
+ },
14
+ "devDependencies": {
15
+ "postcss": "^8.4.38",
16
+ "vitest": "^1.4.0"
17
+ }
18
+ }
package/src/index.js ADDED
@@ -0,0 +1,101 @@
1
+ /**
2
+ * bemoji-postcss
3
+ *
4
+ * PostCSS plugin that transforms readable BEM class names (written in bracket
5
+ * shorthand) to emoji class names at build time.
6
+ *
7
+ * Input:
8
+ * .[card] { ... }
9
+ * .[card__image] { ... }
10
+ * .[card__image--featured] { ... }
11
+ *
12
+ * Output:
13
+ * .🃏 { ... }
14
+ * .🃏__🖼️ { ... }
15
+ * .🃏__🖼️--🌟 { ... }
16
+ *
17
+ * Options:
18
+ * config {string|object} Path to bemoji.config.js or config object
19
+ * escape {'raw'|'unicode'|'auto'} CSS escape mode (default: 'auto')
20
+ * sourceMap {boolean} Generate source maps (default: true)
21
+ */
22
+
23
+ import { loadConfig, encode, escapeForCSS } from '../../core/src/resolver.js';
24
+
25
+ const BRACKET_PATTERN = /\.\[([^\]]+)\]/g;
26
+
27
+ /**
28
+ * Determine whether to escape emoji for a given environment.
29
+ * 'auto' uses raw emoji for modern environments (Node 18+, modern PostCSS).
30
+ */
31
+ function shouldEscape(mode) {
32
+ if (mode === 'unicode') return true;
33
+ if (mode === 'raw') return false;
34
+ // auto: check Node version
35
+ const major = parseInt(process.version.slice(1));
36
+ return major < 18;
37
+ }
38
+
39
+ /**
40
+ * Transform a single selector string.
41
+ */
42
+ function transformSelector(selector, config, escape) {
43
+ return selector.replace(BRACKET_PATTERN, (_, readable) => {
44
+ const emoji = encode(readable, config);
45
+ const cls = escape ? escapeForCSS(emoji) : emoji;
46
+ return '.' + cls;
47
+ });
48
+ }
49
+
50
+ /**
51
+ * Transform a CSS value string (e.g. for content: '[card]' edge cases).
52
+ * Not applied to property values — only selectors.
53
+ */
54
+
55
+ const plugin = (opts = {}) => {
56
+ const userConfig = typeof opts.config === 'object'
57
+ ? opts.config
58
+ : {}; // In production: require(opts.config)
59
+
60
+ const config = loadConfig(userConfig);
61
+ const escape = shouldEscape(opts.escape ?? 'auto');
62
+
63
+ return {
64
+ postcssPlugin: 'bemoji-postcss',
65
+
66
+ Rule(rule) {
67
+ // Transform all selectors in this rule
68
+ const originalSelector = rule.selector;
69
+ rule.selector = rule.selectors
70
+ .map(sel => transformSelector(sel, config, escape))
71
+ .join(', ');
72
+
73
+ if (opts.sourceMap && rule.selector !== originalSelector) {
74
+ rule.source = rule.source; // preserve source position
75
+ }
76
+ },
77
+
78
+ AtRule: {
79
+ // Handle @media, @supports, etc. — no selector transforms needed
80
+ // but pass through intact
81
+ },
82
+
83
+ Declaration(decl) {
84
+ // Transform emoji custom property names in declarations
85
+ // e.g. var(--[shadow-md]) → var(--🌑-md)
86
+ // (This is an extension — not required for basic usage)
87
+ },
88
+ };
89
+ };
90
+
91
+ plugin.postcss = true;
92
+ export default plugin;
93
+
94
+ /**
95
+ * CJS compat wrapper for environments that need require()
96
+ * @see postcss docs on plugin exports
97
+ */
98
+ if (typeof module !== 'undefined') {
99
+ module.exports = plugin;
100
+ module.exports.default = plugin;
101
+ }