pax_global_header00006660000000000000000000000064131104156260014511gustar00rootroot0000000000000052 comment=3d96fcb8bb0dd4bd9407ca4241a019034281570a postcss-icss-values-1.3.0/000077500000000000000000000000001311041562600154445ustar00rootroot00000000000000postcss-icss-values-1.3.0/.gitignore000066400000000000000000000000221311041562600174260ustar00rootroot00000000000000node_modules lib/ postcss-icss-values-1.3.0/.npmignore000066400000000000000000000000001311041562600174310ustar00rootroot00000000000000postcss-icss-values-1.3.0/.travis.yml000066400000000000000000000002411311041562600175520ustar00rootroot00000000000000language: node_js node_js: - "4" - "6" - "node" script: npm run travis before_install: - '[ "${TRAVIS_NODE_VERSION}" != "0.10" ] || npm install -g npm' postcss-icss-values-1.3.0/README.md000066400000000000000000000026711311041562600167310ustar00rootroot00000000000000# CSS Modules: Values Pass arbitrary values between your module files ### Usage ```css /* colors.css */ @value primary: #BF4040; @value secondary: #1F4F7F; .text-primary { color: primary; } .text-secondary { color: secondary; } ``` ```css /* breakpoints.css */ @value small: (max-width: 599px); @value medium: (min-width: 600px) and (max-width: 959px); @value large: (min-width: 960px); ``` ```css /* my-component.css */ /* alias paths for other values or composition */ @value colors: "./colors.css"; /* import multiple from a single file */ @value primary, secondary from colors; /* make local aliases to imported values */ @value small as bp-small, large as bp-large from "./breakpoints.css"; .header { composes: text-primary from colors; box-shadow: 0 0 10px secondary; } @media bp-small { .header { box-shadow: 0 0 4px secondary; } } @media bp-large { .header { box-shadow: 0 0 20px secondary; } } ``` **If you are using Sass** along with this PostCSS plugin, do not use the colon `:` in your `@value` definitions. It will cause Sass to crash. Note also you can _import_ multiple values at once but can only _define_ one value per line. ```css @value a: b, c: d; /* defines a as "b, c: d" */ ``` ### Justification See [this PR](https://github.com/css-modules/css-modules-loader-core/pull/28) for more background ## License ISC ## With thanks - Mark Dalgleish - Tobias Koppers - Josh Johnston --- Glen Maddern, 2015. postcss-icss-values-1.3.0/package.json000066400000000000000000000024671311041562600177430ustar00rootroot00000000000000{ "name": "postcss-modules-values", "version": "1.3.0", "description": "PostCSS plugin for CSS Modules to pass arbitrary values between your module files", "main": "lib/index.js", "scripts": { "lint": "standard src test", "build": "babel --out-dir lib src", "autotest": "chokidar src test -c 'npm test'", "test": "mocha --compilers js:babel-core/register", "posttest": "npm run lint && npm run build", "travis": "npm run test", "prepublish": "npm run build" }, "repository": { "type": "git", "url": "git+https://github.com/css-modules/postcss-modules-values.git" }, "keywords": [ "css", "modules", "postcss" ], "author": "Glen Maddern", "license": "ISC", "bugs": { "url": "https://github.com/css-modules/postcss-modules-values/issues" }, "homepage": "https://github.com/css-modules/postcss-modules-values#readme", "devDependencies": { "babel-cli": "^6.5.2", "babel-core": "^6.5.2", "babel-plugin-add-module-exports": "^0.2.1", "babel-preset-es2015": "^6.3.13", "chokidar": "^1.2.0", "mocha": "^3.0.2", "standard": "^8.4.0" }, "dependencies": { "icss-replace-symbols": "^1.1.0", "postcss": "^6.0.1" }, "babel": { "presets": [ "es2015" ], "plugins": [ "add-module-exports" ] } } postcss-icss-values-1.3.0/src/000077500000000000000000000000001311041562600162335ustar00rootroot00000000000000postcss-icss-values-1.3.0/src/index.js000066400000000000000000000062371311041562600177100ustar00rootroot00000000000000import postcss from 'postcss' import replaceSymbols, {replaceAll} from 'icss-replace-symbols' const matchImports = /^(.+?|\([\s\S]+?\))\s+from\s+("[^"]*"|'[^']*'|[\w-]+)$/ const matchValueDefinition = /(?:\s+|^)([\w-]+):?\s+(.+?)\s*$/g const matchImport = /^([\w-]+)(?:\s+as\s+([\w-]+))?/ let options = {} let importIndex = 0 let createImportedName = options && options.createImportedName || ((importName/*, path*/) => `i__const_${importName.replace(/\W/g, '_')}_${importIndex++}`) export default postcss.plugin('postcss-modules-values', () => (css, result) => { let importAliases = [] let definitions = {} const addDefinition = atRule => { let matches while (matches = matchValueDefinition.exec(atRule.params)) { let [/*match*/, key, value] = matches // Add to the definitions, knowing that values can refer to each other definitions[key] = replaceAll(definitions, value) atRule.remove() } } const addImport = atRule => { let matches = matchImports.exec(atRule.params) if (matches) { let [/*match*/, aliases, path] = matches // We can use constants for path names if (definitions[path]) path = definitions[path] let imports = aliases.replace(/^\(\s*([\s\S]+)\s*\)$/, '$1').split(/\s*,\s*/).map(alias => { let tokens = matchImport.exec(alias) if (tokens) { let [/*match*/, theirName, myName = theirName] = tokens let importedName = createImportedName(myName) definitions[myName] = importedName return { theirName, importedName } } else { throw new Error(`@import statement "${alias}" is invalid!`) } }) importAliases.push({ path, imports }) atRule.remove() } } /* Look at all the @value statements and treat them as locals or as imports */ css.walkAtRules('value', atRule => { if (matchImports.exec(atRule.params)) { addImport(atRule) } else { if (atRule.params.indexOf('@value') !== -1) { result.warn('Invalid value definition: ' + atRule.params) } addDefinition(atRule) } }) /* We want to export anything defined by now, but don't add it to the CSS yet or it well get picked up by the replacement stuff */ let exportDeclarations = Object.keys(definitions).map(key => postcss.decl({ value: definitions[key], prop: key, raws: { before: "\n " } })) /* If we have no definitions, don't continue */ if (!Object.keys(definitions).length) return /* Perform replacements */ replaceSymbols(css, definitions) /* Add export rules if any */ if (exportDeclarations.length > 0) { let exportRule = postcss.rule({ selector: `:export`, raws: { after: "\n" } }) exportRule.append(exportDeclarations) css.prepend(exportRule) } /* Add import rules */ importAliases.reverse().forEach(({ path, imports }) => { let importRule = postcss.rule({ selector: `:import(${path})`, raws: { after: "\n" } }) imports.forEach(({ theirName, importedName }) => { importRule.append({ value: theirName, prop: importedName, raws: { before: "\n " } }) }) css.prepend(importRule) }) }) postcss-icss-values-1.3.0/test/000077500000000000000000000000001311041562600164235ustar00rootroot00000000000000postcss-icss-values-1.3.0/test/index.js000066400000000000000000000126761311041562600201040ustar00rootroot00000000000000/* global describe, it */ import postcss from 'postcss' import assert from 'assert' import constants from '../src' const test = (input, expected) => { let processor = postcss([constants]) assert.equal(processor.process(input).css, expected) } describe('constants', () => { it('should pass through an empty string', () => { test('', '') }) it('should export a constant', () => { test('@value red blue;', ':export {\n red: blue\n}') }) it('gives an error when there is no semicolon between lines', () => { const input = '@value red blue\n@value green yellow' let processor = postcss([constants]) const result = processor.process(input) const warnings = result.warnings() assert.equal(warnings.length, 1) assert.equal(warnings[0].text, 'Invalid value definition: red blue\n@value green yellow') }) it('should export a more complex constant', () => { test('@value small (max-width: 599px);', ':export {\n small: (max-width: 599px)\n}') }) it('should replace constants within the file', () => { test('@value blue red; .foo { color: blue; }', ':export {\n blue: red;\n}\n.foo { color: red; }') }) it('should import and re-export a simple constant', () => { test('@value red from "./colors.css";', ':import("./colors.css") {\n i__const_red_0: red\n}\n:export {\n red: i__const_red_0\n}') }) it('should import a simple constant and replace usages', () => { test('@value red from "./colors.css"; .foo { color: red; }', ':import("./colors.css") {\n i__const_red_1: red;\n}\n:export {\n red: i__const_red_1;\n}\n.foo { color: i__const_red_1; }') }) it('should import and alias a constant and replace usages', () => { test('@value blue as red from "./colors.css"; .foo { color: red; }', ':import("./colors.css") {\n i__const_red_2: blue;\n}\n:export {\n red: i__const_red_2;\n}\n.foo { color: i__const_red_2; }') }) it('should import multiple from a single file', () => { test( `@value blue, red from "./colors.css"; .foo { color: red; } .bar { color: blue }`, `:import("./colors.css") { i__const_blue_3: blue; i__const_red_4: red; } :export { blue: i__const_blue_3; red: i__const_red_4; } .foo { color: i__const_red_4; } .bar { color: i__const_blue_3 }`) }) it('should import from a definition', () => { test( '@value colors: "./colors.css"; @value red from colors;', ':import("./colors.css") {\n i__const_red_5: red\n}\n' + ':export {\n colors: "./colors.css";\n red: i__const_red_5\n}' ) }) it('should only allow values for paths if defined in the right order', () => { test( '@value red from colors; @value colors: "./colors.css";', ':import(colors) {\n i__const_red_6: red\n}\n' + ':export {\n red: i__const_red_6;\n colors: "./colors.css"\n}' ) }) it('should allow transitive values', () => { test( '@value aaa: red;\n@value bbb: aaa;\n.a { color: bbb; }', ':export {\n aaa: red;\n bbb: red;\n}\n.a { color: red; }' ) }) it('should allow transitive values within calc', () => { test( '@value base: 10px;\n@value large: calc(base * 2);\n.a { margin: large; }', ':export {\n base: 10px;\n large: calc(10px * 2);\n}\n.a { margin: calc(10px * 2); }' ) }) it('should preserve import order', () => { test( '@value a from "./a.css"; @value b from "./b.css";', ':import("./a.css") {\n i__const_a_7: a\n}\n' + ':import("./b.css") {\n i__const_b_8: b\n}\n' + ':export {\n a: i__const_a_7;\n b: i__const_b_8\n}' ) }) it('should allow custom-property-style names', () => { test( '@value --red from "./colors.css"; .foo { color: --red; }', ':import("./colors.css") {\n i__const___red_9: --red;\n}\n' + ':export {\n --red: i__const___red_9;\n}\n' + '.foo { color: i__const___red_9; }') }) it('should allow all colour types', () => { test( '@value named: red; @value 3char #0f0; @value 6char #00ff00; @value rgba rgba(34, 12, 64, 0.3); @value hsla hsla(220, 13.0%, 18.0%, 1);\n' + '.foo { color: named; background-color: 3char; border-top-color: 6char; border-bottom-color: rgba; outline-color: hsla; }', ':export {\n named: red;\n 3char: #0f0;\n 6char: #00ff00;\n rgba: rgba(34, 12, 64, 0.3);\n hsla: hsla(220, 13.0%, 18.0%, 1);\n}\n' + '.foo { color: red; background-color: #0f0; border-top-color: #00ff00; border-bottom-color: rgba(34, 12, 64, 0.3); outline-color: hsla(220, 13.0%, 18.0%, 1); }') }) it('should import multiple from a single file on multiple lines', () => { test( `@value ( blue, red ) from "./colors.css"; .foo { color: red; } .bar { color: blue }`, `:import("./colors.css") { i__const_blue_10: blue; i__const_red_11: red; } :export { blue: i__const_blue_10; red: i__const_red_11; } .foo { color: i__const_red_11; } .bar { color: i__const_blue_10 }`) }) it('should allow definitions with commas in them', () => { test( '@value coolShadow: 0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14) ;\n' + '.foo { box-shadow: coolShadow; }', ':export {\n coolShadow: 0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14);\n}\n' + '.foo { box-shadow: 0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14); }') }) it('should allow values with nested parantheses', () => { test( '@value aaa: color(red lightness(50%));', ':export {\n aaa: color(red lightness(50%))\n}' ) }) })