diff --git a/plugins/postcss-focus-within/.editorconfig b/plugins/postcss-focus-within/.editorconfig
deleted file mode 100644
index e06d7982b..000000000
--- a/plugins/postcss-focus-within/.editorconfig
+++ /dev/null
@@ -1,15 +0,0 @@
-root = true
-
-[*]
-charset = utf-8
-end_of_line = lf
-indent_style = tab
-insert_final_newline = true
-trim_trailing_whitespace = true
-
-[*.md]
-trim_trailing_whitespace = false
-
-[*.{json,md,yml}]
-indent_size = 2
-indent_style = space
diff --git a/plugins/postcss-focus-within/.gitattributes b/plugins/postcss-focus-within/.gitattributes
deleted file mode 100644
index 6313b56c5..000000000
--- a/plugins/postcss-focus-within/.gitattributes
+++ /dev/null
@@ -1 +0,0 @@
-* text=auto eol=lf
diff --git a/plugins/postcss-focus-within/.github/workflows/test.yml b/plugins/postcss-focus-within/.github/workflows/test.yml
deleted file mode 100644
index 4a287db8e..000000000
--- a/plugins/postcss-focus-within/.github/workflows/test.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-name: test
-on:
- push:
-
-jobs:
- test:
- runs-on: ubuntu-latest
- strategy:
- matrix:
- node: [12, 16]
- steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-node@v2
- with:
- node-version: ${{ matrix.node }}
-
- - run: yarn install --ignore-scripts
- - run: yarn run test
diff --git a/plugins/postcss-focus-within/.gitignore b/plugins/postcss-focus-within/.gitignore
index 72a6a3d37..17847a362 100644
--- a/plugins/postcss-focus-within/.gitignore
+++ b/plugins/postcss-focus-within/.gitignore
@@ -1,13 +1,12 @@
-dist
node_modules
+dist
package-lock.json
yarn.lock
*.log*
*.result.css
-.*
+*.result.css.map
!.editorconfig
-!.gitattributes
!.gitignore
!.rollup.js
!.tape.js
-!.github
+!.travis.yml
diff --git a/plugins/postcss-focus-within/.rollup.js b/plugins/postcss-focus-within/.rollup.js
deleted file mode 100644
index 876826dab..000000000
--- a/plugins/postcss-focus-within/.rollup.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import pkg from './package.json'
-
-export default {
- ...pkg.rollup,
- plugins: pkg.rollup.plugins.map(plugin => ((plugin = [].concat(plugin)), require(plugin[0])(...plugin.slice(1)))),
- onwarn(warning, warn) {
- if (warning.code !== 'UNRESOLVED_IMPORT') warn(warning)
- }
-}
diff --git a/plugins/postcss-focus-within/CONTRIBUTING.md b/plugins/postcss-focus-within/CONTRIBUTING.md
deleted file mode 100644
index f133b571f..000000000
--- a/plugins/postcss-focus-within/CONTRIBUTING.md
+++ /dev/null
@@ -1,65 +0,0 @@
-# Contributing to PostCSS Focus Within
-
-You want to help? You rock! Now, take a moment to be sure your contributions
-make sense to everyone else.
-
-## Reporting Issues
-
-Found a problem? Want a new feature?
-
-- See if your issue or idea has [already been reported].
-- Provide a [reduced test case] or a [live example].
-
-Remember, a bug is a _demonstrable problem_ caused by _our_ code.
-
-## Submitting Pull Requests
-
-Pull requests are the greatest contributions, so be sure they are focused in
-scope and avoid unrelated commits.
-
-1. To begin; [fork this project], clone your fork, and add our upstream.
- ```bash
- # Clone your fork of the repo into the current directory
- git clone git@github.com:YOUR_USER/postcss-focus-within.git
-
- # Navigate to the newly cloned directory
- cd postcss-focus-within
-
- # Assign the original repo to a remote called "upstream"
- git remote add upstream git@github.com:csstools/postcss-focus-within.git
-
- # Install the tools necessary for testing
- npm install
- ```
-
-2. Create a branch for your feature or fix:
- ```bash
- # Move into a new branch for your feature
- git checkout -b feature/thing
- ```
- ```bash
- # Move into a new branch for your fix
- git checkout -b fix/something
- ```
-
-3. If your code follows our practices, then push your feature branch:
- ```bash
- # Test current code
- npm test
- ```
- ```bash
- # Push the branch for your new feature
- git push origin feature/thing
- ```
- ```bash
- # Or, push the branch for your update
- git push origin update/something
- ```
-
-That’s it! Now [open a pull request] with a clear title and description.
-
-[already been reported]: issues
-[fork this project]: fork
-[live example]: https://codepen.io/pen
-[open a pull request]: https://help.github.com/articles/using-pull-requests/
-[reduced test case]: https://css-tricks.com/reduced-test-cases/
diff --git a/plugins/postcss-focus-within/INSTALL.md b/plugins/postcss-focus-within/INSTALL.md
index 1e41af4d9..e4921c95e 100644
--- a/plugins/postcss-focus-within/INSTALL.md
+++ b/plugins/postcss-focus-within/INSTALL.md
@@ -165,6 +165,6 @@ grunt.initConfig({
[PostCSS]: https://github.com/postcss/postcss
[PostCSS CLI]: https://github.com/postcss/postcss-cli
[PostCSS Loader]: https://github.com/postcss/postcss-loader
-[PostCSS]: https://github.com/csstools/postcss-focus-within
+[PostCSS]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-within
[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss
[React App Rewired]: https://github.com/timarney/react-app-rewired
diff --git a/plugins/postcss-focus-within/README.md b/plugins/postcss-focus-within/README.md
index f11e7df72..e44073cee 100644
--- a/plugins/postcss-focus-within/README.md
+++ b/plugins/postcss-focus-within/README.md
@@ -2,7 +2,7 @@
[
][npm-url]
[
][css-url]
-[
][cli-url]
+[
][cli-url]
[
][git-url]
[PostCSS Focus Within] lets you use the `:focus-within` pseudo-class in CSS,
@@ -116,7 +116,7 @@ focusWithin({ replaceWith: '.focus-within' });
```
[css-url]: https://cssdb.org/#focus-within-pseudo-class
-[cli-url]: https://github.com/csstools/postcss-focus-within/actions/workflows/test.yml?query=workflow/test
+[cli-url]: https://github.com/csstools/postcss-plugins/tree/main/postcss-focus-within/actions/workflows/test.yml?query=workflow/test
[git-url]: https://gitter.im/postcss/postcss
[npm-url]: https://www.npmjs.com/package/postcss-focus-within
@@ -124,6 +124,6 @@ focusWithin({ replaceWith: '.focus-within' });
[Gulp PostCSS]: https://github.com/postcss/gulp-postcss
[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss
[PostCSS]: https://github.com/postcss/postcss
-[PostCSS Focus Within]: https://github.com/csstools/postcss-focus-within
+[PostCSS Focus Within]: https://github.com/csstools/postcss-plugins/tree/main/postcss-focus-within
[PostCSS Loader]: https://github.com/postcss/postcss-loader
[Selectors Level 4 specification]: https://www.w3.org/TR/selectors-4/#the-focus-within-pseudo
diff --git a/plugins/postcss-focus-within/package.json b/plugins/postcss-focus-within/package.json
index 1c9d71d40..8b4f54cd9 100644
--- a/plugins/postcss-focus-within/package.json
+++ b/plugins/postcss-focus-within/package.json
@@ -5,96 +5,40 @@
"author": "Jonathan Neal ",
"license": "CC0-1.0",
"repository": "csstools/postcss-focus-within",
- "homepage": "https://github.com/csstools/postcss-focus-within#readme",
- "bugs": "https://github.com/csstools/postcss-focus-within/issues",
+ "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-within#readme",
+ "bugs": "https://github.com/csstools/postcss-plugins/issues",
"main": "dist/index.cjs",
"module": "dist/index.mjs",
- "types": "./dist/index.d.ts",
- "exports": {
- ".": {
- "import": "./dist/index.mjs",
- "require": "./dist/index.cjs",
- "types": "./dist/index.d.ts"
- }
- },
+ "types": "dist/index.d.ts",
"files": [
+ "CHANGELOG.md",
+ "INSTALL.md",
+ "LICENSE.md",
+ "README.md",
"dist"
],
+ "bin": {
+ "postcss-focus-within": "dist/cli.mjs"
+ },
"scripts": {
- "build": "npx rollup -c .rollup.js",
- "build:watch": "npx rollup -c .rollup.js --watch",
- "lint": "npx eslint --cache src",
- "lint:fix": "npx eslint --cache --fix",
- "prepublishOnly": "npm test",
- "pretest": "npm install && npm run build",
- "test": "npm run lint && npm run tape",
- "tape": "npx postcss-tape"
+ "prepublishOnly": "npm run build && npm run test",
+ "lint": "eslint src/**/*.ts",
+ "test": "postcss-tape",
+ "build": "rollup -c ../../rollup/default.ts.js",
+ "stryker": "stryker run --logLevel error"
},
"engines": {
- "node": ">=12"
+ "node": "^12 || ^14 || >=16"
},
- "peerDependencies": {
- "postcss": "^8.3"
+ "dependencies": {
+ "postcss-selector-parser": "6.0.6"
},
"devDependencies": {
- "@babel/core": "7.15.5",
- "@babel/preset-env": "7.15.6",
- "eslint": "7.32.0",
"postcss": "8.3.6",
- "postcss-tape": "6.0.1",
- "pre-commit": "1.2.2",
- "rollup": "2.57.0",
- "rollup-plugin-babel": "4.4.0",
- "rollup-plugin-copy": "^3.4.0"
+ "postcss-tape": "6.0.1"
},
- "babel": {
- "presets": [
- [
- "@babel/env",
- {
- "targets": "maintained node versions"
- }
- ]
- ]
- },
- "eslintConfig": {
- "env": {
- "es6": true,
- "node": true
- },
- "extends": "eslint:recommended",
- "parserOptions": {
- "ecmaVersion": 2020,
- "sourceType": "module"
- }
- },
- "rollup": {
- "input": "src/index.js",
- "plugins": [
- "rollup-plugin-babel",
- [
- "rollup-plugin-copy",
- {
- "targets": [
- {
- "src": "./src/index.d.ts",
- "dest": "./dist"
- }
- ]
- }
- ]
- ],
- "output": [
- {
- "exports": "default",
- "file": "dist/index.cjs",
- "format": "cjs"
- },
- {
- "file": "dist/index.mjs",
- "format": "esm"
- }
- ]
+ "peerDependencies": {
+ "postcss": "^8.3"
},
"keywords": [
"postcss",
diff --git a/plugins/postcss-focus-within/src/cli.ts b/plugins/postcss-focus-within/src/cli.ts
new file mode 100644
index 000000000..5802812f2
--- /dev/null
+++ b/plugins/postcss-focus-within/src/cli.ts
@@ -0,0 +1,16 @@
+import plugin from './index';
+import { cli, helpTextLogger } from '@csstools/base-cli';
+
+cli(
+ plugin,
+ ['preserve', 'replaceWith'],
+ helpTextLogger(
+ 'postcss-focus-within',
+ 'PostCSS Focus Within',
+ 'Lets you use the `:focus-within` pseudo-class in CSS, following the Selectors Level 4 specification.',
+ {
+ preserve: true,
+ replaceWith: '.focus-within',
+ },
+ ),
+);
diff --git a/plugins/postcss-focus-within/src/index.d.ts b/plugins/postcss-focus-within/src/index.d.ts
deleted file mode 100644
index 31ea82644..000000000
--- a/plugins/postcss-focus-within/src/index.d.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-export type PluginOptions = {
- /** Defines whether the original selector should remain. */
- preserve?: boolean
- /** Defines the selector to replace `:focus-within`. */
- replaceWith?: string
-}
-
-export type Plugin = {
- (pluginOptions?: PluginOptions): {
- postcssPlugin: 'postcss-focus-within'
- }
- postcss: true
-}
-
-declare const plugin: Plugin
-
-export default plugin
diff --git a/plugins/postcss-focus-within/src/index.js b/plugins/postcss-focus-within/src/index.js
deleted file mode 100644
index f8e95de7b..000000000
--- a/plugins/postcss-focus-within/src/index.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const selectorRegExp = /(? {
- const replaceWith = String(Object(opts).replaceWith || '[focus-within]');
- const preserve = Boolean('preserve' in Object(opts) ? opts.preserve : true);
-
- return {
- postcssPlugin: 'postcss-focus-within',
- Rule: rule => {
- if (!selectorRegExp.test(rule.selector)) {
- return;
- }
-
- const selector = rule.selector.replace(selectorRegExp, ($0, $1) => `${replaceWith}${$1}`);
-
- // Check is the rule is processed yet
- if (preserve && rule.prev()?.selector === selector) {
- return;
- }
-
- const clone = rule.clone({ selector });
-
- if (preserve) {
- rule.before(clone);
- } else {
- rule.replaceWith(clone);
- }
- }
- }
-};
-
-plugin.postcss = true;
-
-export default plugin;
diff --git a/plugins/postcss-focus-within/src/index.ts b/plugins/postcss-focus-within/src/index.ts
new file mode 100644
index 000000000..79598d637
--- /dev/null
+++ b/plugins/postcss-focus-within/src/index.ts
@@ -0,0 +1,42 @@
+import parser from 'postcss-selector-parser';
+import type { PluginCreator } from 'postcss';
+
+const selectorRegExp = /(? = (opts?: { preserve?: boolean, replaceWith?: string }) => {
+ const replaceWith = String(Object(opts).replaceWith || '[focus-within]');
+ const preserve = Boolean('preserve' in Object(opts) ? opts.preserve : true);
+ const replacementAST = parser().astSync(replaceWith);
+
+ return {
+ postcssPlugin: 'postcss-focus-within',
+ Rule: (rule)=> {
+ if (!selectorRegExp.test(rule.selector)) {
+ return;
+ }
+
+ const modifiedSelectorAST = parser((selectors) => {
+ selectors.walkPseudos((pseudo) => {
+ if (pseudo.value !== ':focus-within') {
+ return;
+ }
+
+ pseudo.replaceWith(replacementAST.clone({}));
+ });
+ }).processSync(rule.selector);
+
+ const clone = rule.clone({ selector: String(modifiedSelectorAST) });
+
+ if (preserve) {
+ rule.before(clone);
+ } else {
+ rule.replaceWith(clone);
+ }
+ },
+ };
+};
+
+creator.postcss = true;
+
+export default creator;
+
diff --git a/plugins/postcss-focus-within/test/basic.expect.css b/plugins/postcss-focus-within/test/basic.expect.css
index 5cdbbda92..9d913359c 100644
--- a/plugins/postcss-focus-within/test/basic.expect.css
+++ b/plugins/postcss-focus-within/test/basic.expect.css
@@ -6,8 +6,7 @@
order: 1;
}
-[focus-within],
-[focus-within] test,
+[focus-within],[focus-within] test,
test [focus-within],
test test[focus-within],
test [focus-within] test,
diff --git a/plugins/postcss-focus-within/test/basic.preserve.expect.css b/plugins/postcss-focus-within/test/basic.preserve.expect.css
index 716915d18..14178c31e 100644
--- a/plugins/postcss-focus-within/test/basic.preserve.expect.css
+++ b/plugins/postcss-focus-within/test/basic.preserve.expect.css
@@ -2,8 +2,7 @@
order: 1;
}
-[focus-within],
-[focus-within] test,
+[focus-within],[focus-within] test,
test [focus-within],
test test[focus-within],
test [focus-within] test,
diff --git a/plugins/postcss-focus-within/test/basic.replacewith.expect.css b/plugins/postcss-focus-within/test/basic.replacewith.expect.css
index e0adc9430..1d97e95d3 100644
--- a/plugins/postcss-focus-within/test/basic.replacewith.expect.css
+++ b/plugins/postcss-focus-within/test/basic.replacewith.expect.css
@@ -6,8 +6,7 @@
order: 1;
}
-.focus-within,
-.focus-within test,
+.focus-within,.focus-within test,
test .focus-within,
test test.focus-within,
test .focus-within test,
diff --git a/plugins/postcss-focus-within/tsconfig.json b/plugins/postcss-focus-within/tsconfig.json
new file mode 100644
index 000000000..68a2606f6
--- /dev/null
+++ b/plugins/postcss-focus-within/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "dist",
+ "declarationDir": "."
+ },
+ "include": ["./src/**/*"],
+ "exclude": ["dist"],
+}