Skip to content

Commit 5dde7d7

Browse files
committed
lib + readme
1 parent ad2b4ed commit 5dde7d7

File tree

12 files changed

+928
-1
lines changed

12 files changed

+928
-1
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ pnpm-debug.log*
88
# Build outputs
99
dist/
1010
build/
11-
lib/
1211
*.tsbuildinfo
1312

1413
# Environment variables

README.md

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
# wc-css-transform
2+
3+
Transform Web Components CSS to regular CSS format with data attribute mapping.
4+
5+
A powerful tool for converting web component CSS (using `:host` selectors) into regular CSS compatible formats, with automatic data attribute mapping for better framework integration.
6+
7+
## Features
8+
9+
- 🎯 **Transform `:host` selectors** to regular CSS format
10+
- 🔄 **Data attribute mapping** - automatically convert attributes to `data-*` format
11+
- 🛠️ **PostCSS plugin** - integrate with your existing build pipeline
12+
- 📦 **Framework agnostic** - works with React, Vue, Angular, and more
13+
- 🎨 **CSS compatible** - outputs clean CSS that works with styled-components, emotion, etc.
14+
15+
## Installation
16+
17+
```bash
18+
npm install wc-css-transform
19+
# or
20+
pnpm add wc-css-transform
21+
# or
22+
yarn add wc-css-transform
23+
```
24+
25+
## Usage
26+
27+
### Basic Usage
28+
29+
```typescript
30+
import { wcCssTransform } from 'wc-css-transform';
31+
32+
const input = `
33+
:host {
34+
color: red;
35+
font-size: 16px;
36+
}
37+
38+
:host([active]) {
39+
background: blue;
40+
}
41+
42+
:host(:hover) {
43+
opacity: 0.8;
44+
}
45+
`;
46+
47+
const output = wcCssTransform(input);
48+
49+
console.log(output);
50+
// Output:
51+
// color: red;
52+
// font-size: 16px;
53+
//
54+
// &[active] {
55+
// background: blue;
56+
// }
57+
//
58+
// &:hover {
59+
// opacity: 0.8;
60+
// }
61+
```
62+
63+
### PostCSS Plugin
64+
65+
```javascript
66+
import postcss from 'postcss';
67+
import { postcssPlugin } from 'wc-css-transform';
68+
69+
const result = await postcss([
70+
postcssPlugin
71+
]).process(input);
72+
```
73+
74+
## API
75+
76+
### `wcCssTransform(input, options)`
77+
78+
Transform web component CSS to regular CSS format.
79+
80+
**Parameters:**
81+
- `input` (string): CSS input string
82+
- `options` (object): Configuration options
83+
84+
**Options:**
85+
- `hostTag` (string): Tag to replace `:host` with (default: `"&"`)
86+
- `dataAttributes` (boolean): Enable data attribute mapping (default: `false`)
87+
- `excludeFromData` (string[]): Attributes to exclude from data- prefix
88+
- `layer` (string | false): CSS layer name (default: `false`)
89+
90+
### `postcssPlugin(options)`
91+
92+
PostCSS plugin for build pipeline integration.
93+
94+
## Examples
95+
96+
### React with styled-components
97+
98+
```typescript
99+
import styled from 'styled-components';
100+
import { wcCssTransform } from 'wc-css-transform';
101+
102+
const webComponentCSS = `
103+
:host {
104+
color: var(--primary-color);
105+
}
106+
107+
:host([size="large"]) {
108+
font-size: 24px;
109+
}
110+
`;
111+
112+
const StyledComponent = styled.div`
113+
${wcCssTransform(webComponentCSS, { hostTag: '&', dataAttributes: true })}
114+
`;
115+
```
116+
117+
### Vue with CSS modules
118+
119+
```typescript
120+
import { wcCssTransform } from 'wc-css-transform';
121+
122+
const componentCSS = wcCssTransform(`
123+
:host {
124+
display: flex;
125+
align-items: center;
126+
}
127+
128+
:host([disabled]) {
129+
opacity: 0.5;
130+
pointer-events: none;
131+
}
132+
`, { hostTag: '&', dataAttributes: true });
133+
```
134+
135+
## Configuration
136+
137+
### Data Attribute Mapping
138+
139+
When `dataAttributes: true`, attributes are automatically prefixed with `data-`:
140+
141+
```css
142+
/* Input */
143+
:host([id]) { }
144+
:host([size="large"]) { }
145+
[active] { }
146+
147+
/* Output */
148+
&[data-id] { }
149+
&[data-size="large"] { }
150+
[data-active] { }
151+
```
152+
153+
### Exclude Attributes
154+
155+
Use `excludeFromData` to prevent certain attributes from being prefixed:
156+
157+
```typescript
158+
wcCssTransform(input, {
159+
dataAttributes: true,
160+
excludeFromData: ['part', 'class', 'id']
161+
});
162+
```
163+
164+
## Build Integration
165+
166+
### Vite
167+
168+
```javascript
169+
// vite.config.js
170+
import { defineConfig } from 'vite';
171+
import { postcssPlugin } from 'wc-css-transform';
172+
173+
export default defineConfig({
174+
css: {
175+
postcss: {
176+
plugins: [
177+
postcssPlugin({
178+
dataAttributes: true
179+
})
180+
]
181+
}
182+
}
183+
});
184+
```
185+
186+
## License
187+
188+
MIT
189+
190+
## Contributing
191+
192+
Contributions are welcome! Please feel free to submit a Pull Request.
193+
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
:host {
2+
color: var(--heading-color);
3+
line-height: var(--line-height-xlarge);
4+
font-weight: var(--font-weight-semibold);
5+
position: relative;
6+
display: table;
7+
margin: 0;
8+
padding: 0 24px 0 0;
9+
scroll-margin-top: 30px;
10+
cursor: default;
11+
}
12+
13+
:host([id]) {
14+
cursor: pointer;
15+
}
16+
17+
:host([noanchor="true"]) {
18+
cursor: default;
19+
}
20+
21+
:host([label="true"]) {
22+
display: flex;
23+
align-items: center;
24+
gap: 8px;
25+
}
26+
27+
:host(:hover) svg {
28+
opacity: 1;
29+
}
30+
31+
:host([kind="muted"]) {
32+
color: var(--heading-color--muted);
33+
cursor: default;
34+
font-weight: var(--font-weight-medium);
35+
}
36+
37+
:host([size="1"]) {
38+
font-size: var(--font-size-2xl);
39+
line-height: var(--line-height-2xl);
40+
}
41+
42+
:host([size="2"]) {
43+
font-size: var(--font-size-xxlarge);
44+
line-height: var(--line-height-xxlarge);
45+
}
46+
47+
:host([size="3"]) {
48+
font-size: var(--font-size-xlarge);
49+
line-height: var(--line-height-xlarge);
50+
}
51+
52+
:host([size="4"]) {
53+
font-size: var(--font-size-large);
54+
line-height: var(--line-height-large);
55+
}
56+
57+
:host([size="5"]) {
58+
font-size: var(--font-size-medium);
59+
line-height: var(--line-height-medium);
60+
}
61+
62+
:host([size="6"]) {
63+
font-size: var(--font-size-small);
64+
line-height: var(--line-height-small);
65+
}
66+
67+
:host [part="icon"] {
68+
position: absolute;
69+
top: 50%;
70+
right: 0;
71+
margin-top: -6px;
72+
opacity: 0;
73+
}
74+
75+
:host([active="true"]) [part="icon"] {
76+
opacity: 1;
77+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
color: var(--heading-color);
2+
line-height: var(--line-height-xlarge);
3+
font-weight: var(--font-weight-semibold);
4+
position: relative;
5+
display: table;
6+
margin: 0;
7+
padding: 0 24px 0 0;
8+
scroll-margin-top: 30px;
9+
cursor: default;
10+
11+
&[data-id] {
12+
cursor: pointer;
13+
}
14+
15+
&[data-noanchor="true"] {
16+
cursor: default;
17+
}
18+
19+
&[data-label="true"] {
20+
display: flex;
21+
align-items: center;
22+
gap: 8px;
23+
}
24+
25+
&:hover svg {
26+
opacity: 1;
27+
}
28+
29+
&[data-kind="muted"] {
30+
color: var(--heading-color--muted);
31+
cursor: default;
32+
font-weight: var(--font-weight-medium);
33+
}
34+
35+
&[data-size="1"] {
36+
font-size: var(--font-size-2xl);
37+
line-height: var(--line-height-2xl);
38+
}
39+
40+
&[data-size="2"] {
41+
font-size: var(--font-size-xxlarge);
42+
line-height: var(--line-height-xxlarge);
43+
}
44+
45+
&[data-size="3"] {
46+
font-size: var(--font-size-xlarge);
47+
line-height: var(--line-height-xlarge);
48+
}
49+
50+
&[data-size="4"] {
51+
font-size: var(--font-size-large);
52+
line-height: var(--line-height-large);
53+
}
54+
55+
&[data-size="5"] {
56+
font-size: var(--font-size-medium);
57+
line-height: var(--line-height-medium);
58+
}
59+
60+
&[data-size="6"] {
61+
font-size: var(--font-size-small);
62+
line-height: var(--line-height-small);
63+
}
64+
65+
& [part="icon"] {
66+
position: absolute;
67+
top: 50%;
68+
right: 0;
69+
margin-top: -6px;
70+
opacity: 0;
71+
}
72+
73+
&[data-active="true"] [part="icon"] {
74+
opacity: 1;
75+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
:host {
2+
color: var(--heading-color);
3+
line-height: var(--line-height-xlarge);
4+
font-weight: var(--font-weight-semibold);
5+
}
6+
7+
:host([id]) {
8+
cursor: pointer;
9+
}
10+
11+
:host([size="2"]) {
12+
font-size: 24px;
13+
}
14+
15+
[active] {
16+
opacity: 1;
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
color: var(--heading-color);
2+
line-height: var(--line-height-xlarge);
3+
font-weight: var(--font-weight-semibold);
4+
5+
&[data-id] {
6+
cursor: pointer;
7+
}
8+
9+
&[data-size="2"] {
10+
font-size: 24px;
11+
}
12+
13+
[data-active] {
14+
opacity: 1;
15+
}

0 commit comments

Comments
 (0)