CSS Selector Builder
This project is a TypeScript library for building CSS selectors programmatically, and also a user interface around that library.
Motivation
- Create a nice interface that people can use to build CSS selectors and explore different types of CSS selectors
- Practice type definitions, test-driven development, functional programming, pipelines, dark mode design, controlled components, and recursive components in Vue 3
- Have fun with my favorite tools
- TypeScript
- Vue 3 Composition API
- Tailwind
- Vite, both for building the website and bundling the library
- uvu (test runner)
- Try out Headless UI
Usage
Interface
To use the CSS selector builder interface, go to the website.
As you build your selector, you'll see the URL update with any new conditions you've created. You can share that URL with anyone to show them what you've built!
To play with the selector builder's recursive abilities:
- Add a new condition
- Open the dropdown, and type
matches
- Pick one of the options that starts with "matches" to render a nested selector builder. Fun stuff!
The relevant source code for the user interface is in in the src/interface
directory.
Library
To use the library:
npm i @alexvipond/css-selector-pipes
From the library, you can import functions for building CSS selectors:
import { tag, className, not } from '@alexvipond/css-selector-pipes'
tag('h1')() // 'h1'
className('poop')() // .poop
not(tag('h1')())() // ':not(h1)'
Each function is a higher order function, returning a function that accepts a CSS selector (String) as its only parameter, and returns the transformed selector.
import { tag, className } from '@alexvipond/css-selector-pipes'
const tagFunction = tag('h1')
const classNameFunction = className('poop')
tagFunction(classNameFunction()) // h1.poop
You can also import a pipe
utility that makes it easier to compose multiple functions into a selector pipeline.
import { pipe, tag, className, attribute, focus } from '@alexvipond/css-selector-pipes'
pipe(
tag('h1'),
className('poop'),
attribute('name', '$=', 'lol'),
focus()
)() // h1.poop["name"$="lol"]:focus
Or, if your dev environment supports it, you can use the upcoming pipeline operator:
import { tag, className, attribute, focus } from '@alexvipond/css-selector-pipes'
|> tag('h1'),
|> className('poop'),
|> attribute('name', '$=', 'lol'),
|> focus()
// h1.poop["name"$="lol"]:focus
All functions are fully typed, and you can check out these test files for further documentation and a list of available functions:
The relevant source code is in the src/pipes
directory.
Development
Set up the project locally:
git clone https://github.com/AlexVipond/css-selector-builder && cd css-selector-builder && npm install
Run tests:
npm run test
Run tests for a specific file:
npm run test:only [filename, excluding the .test.ts extension]
npm tun test:only toSelector
npm tun test:only append
Run the interface in development mode on localhost:3000
:
npm run dev
Build the interface for production:
npm run build
Build the library for production:
npm run build:lib