kempo-css 1.3.1 → 1.3.6

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.
@@ -1,255 +1,255 @@
1
- const getStyle = (el, prop) => getComputedStyle(el)[prop];
2
-
3
- export const beforeAll = async () => {
4
- const link = document.createElement('link');
5
- link.rel = 'stylesheet';
6
- link.href = '/src/kempo.css';
7
- document.head.appendChild(link);
8
- await new Promise(resolve => link.onload = resolve);
9
- };
10
-
11
- export default {
12
- 'should apply small font size with .small': ({pass, fail}) => {
13
- const el = document.createElement('span');
14
- el.className = 'small';
15
- const normal = document.createElement('span');
16
- document.body.appendChild(el);
17
- document.body.appendChild(normal);
18
- const smallSize = parseFloat(getStyle(el, 'fontSize'));
19
- const normalSize = parseFloat(getStyle(normal, 'fontSize'));
20
- el.remove();
21
- normal.remove();
22
- if(smallSize < normalSize){
23
- pass(`.small reduces font size (${smallSize}px < ${normalSize}px)`);
24
- } else {
25
- fail(`Expected smaller font, got ${smallSize}px vs ${normalSize}px`);
26
- }
27
- },
28
-
29
- 'should apply large font size with .large': ({pass, fail}) => {
30
- const el = document.createElement('span');
31
- el.className = 'large';
32
- const normal = document.createElement('span');
33
- document.body.appendChild(el);
34
- document.body.appendChild(normal);
35
- const largeSize = parseFloat(getStyle(el, 'fontSize'));
36
- const normalSize = parseFloat(getStyle(normal, 'fontSize'));
37
- el.remove();
38
- normal.remove();
39
- if(largeSize > normalSize){
40
- pass(`.large increases font size (${largeSize}px > ${normalSize}px)`);
41
- } else {
42
- fail(`Expected larger font, got ${largeSize}px vs ${normalSize}px`);
43
- }
44
- },
45
-
46
- 'should apply bold font weight to headings': ({pass, fail}) => {
47
- const h1 = document.createElement('h1');
48
- document.body.appendChild(h1);
49
- const weight = getStyle(h1, 'fontWeight');
50
- h1.remove();
51
- if(parseInt(weight) >= 700){
52
- pass(`Headings are bold (weight: ${weight})`);
53
- } else {
54
- fail(`Expected bold weight >= 700, got ${weight}`);
55
- }
56
- },
57
-
58
- 'should apply heading font sizes in descending order': ({pass, fail}) => {
59
- const sizes = [];
60
- for(let i = 1; i <= 6; i++){
61
- const h = document.createElement(`h${i}`);
62
- document.body.appendChild(h);
63
- sizes.push(parseFloat(getStyle(h, 'fontSize')));
64
- h.remove();
65
- }
66
- let descending = true;
67
- for(let i = 0; i < sizes.length - 1; i++){
68
- if(sizes[i] <= sizes[i + 1]){
69
- descending = false;
70
- break;
71
- }
72
- }
73
- if(descending){
74
- pass(`Heading sizes descend: ${sizes.join(' > ')}`);
75
- } else {
76
- fail(`Expected descending sizes, got: ${sizes.join(', ')}`);
77
- }
78
- },
79
-
80
- 'should apply heading classes .h1-.h6': ({pass, fail}) => {
81
- const failed = [];
82
- for(let i = 1; i <= 6; i++){
83
- const div = document.createElement('div');
84
- div.className = `h${i}`;
85
- const h = document.createElement(`h${i}`);
86
- document.body.appendChild(div);
87
- document.body.appendChild(h);
88
- const divSize = getStyle(div, 'fontSize');
89
- const hSize = getStyle(h, 'fontSize');
90
- div.remove();
91
- h.remove();
92
- if(divSize !== hSize){
93
- failed.push(`h${i}: ${divSize} vs ${hSize}`);
94
- }
95
- }
96
- if(failed.length === 0){
97
- pass('.h1-.h6 classes match heading sizes');
98
- } else {
99
- fail(`Size mismatches: ${failed.join(', ')}`);
100
- }
101
- },
102
-
103
- 'should apply monospace font to code': ({pass, fail}) => {
104
- const code = document.createElement('code');
105
- document.body.appendChild(code);
106
- const fontFamily = getStyle(code, 'fontFamily');
107
- code.remove();
108
- if(fontFamily.toLowerCase().includes('mono') || fontFamily.toLowerCase().includes('consolas')){
109
- pass(`Code uses monospace font: ${fontFamily}`);
110
- } else {
111
- fail(`Expected monospace font, got ${fontFamily}`);
112
- }
113
- },
114
-
115
- 'should apply background to code': ({pass, fail}) => {
116
- const code = document.createElement('code');
117
- code.textContent = 'test';
118
- document.body.appendChild(code);
119
- const bg = getStyle(code, 'backgroundColor');
120
- code.remove();
121
- if(bg && bg !== 'rgba(0, 0, 0, 0)' && bg !== 'transparent'){
122
- pass(`Code has background: ${bg}`);
123
- } else {
124
- fail('Code should have a background color');
125
- }
126
- },
127
-
128
- 'should style pre code as block': ({pass, fail}) => {
129
- const pre = document.createElement('pre');
130
- const code = document.createElement('code');
131
- pre.appendChild(code);
132
- document.body.appendChild(pre);
133
- const display = getStyle(code, 'display');
134
- pre.remove();
135
- if(display === 'block'){
136
- pass('pre code displays as block');
137
- } else {
138
- fail(`Expected block display, got ${display}`);
139
- }
140
- },
141
-
142
- 'should apply text alignment classes': ({pass, fail}) => {
143
- const tests = [
144
- {className: 'ta-left', expected: 'left'},
145
- {className: 'ta-center', expected: 'center'},
146
- {className: 'ta-right', expected: 'right'}
147
- ];
148
- const failed = [];
149
- tests.forEach(({className, expected}) => {
150
- const el = document.createElement('div');
151
- el.className = className;
152
- document.body.appendChild(el);
153
- const align = getStyle(el, 'textAlign');
154
- el.remove();
155
- if(align !== expected && align !== `${expected}`){
156
- failed.push(`${className}: ${align}`);
157
- }
158
- });
159
- if(failed.length === 0){
160
- pass('Text alignment classes work correctly');
161
- } else {
162
- fail(`Alignment issues: ${failed.join(', ')}`);
163
- }
164
- },
165
-
166
- 'should style links with color': ({pass, fail}) => {
167
- const a = document.createElement('a');
168
- a.href = '#';
169
- document.body.appendChild(a);
170
- const color = getStyle(a, 'color');
171
- a.remove();
172
- if(color && color !== 'rgb(0, 0, 0)'){
173
- pass(`Links have color: ${color}`);
174
- } else {
175
- fail('Links should have a distinct color');
176
- }
177
- },
178
-
179
- 'should apply .link class styling': ({pass, fail}) => {
180
- const span = document.createElement('span');
181
- span.className = 'link';
182
- document.body.appendChild(span);
183
- const color = getStyle(span, 'color');
184
- span.remove();
185
- if(color && color !== 'rgb(0, 0, 0)'){
186
- pass(`.link class applies link color: ${color}`);
187
- } else {
188
- fail('.link should have link color');
189
- }
190
- },
191
-
192
- 'should style blockquote with left border': ({pass, fail}) => {
193
- const bq = document.createElement('blockquote');
194
- document.body.appendChild(bq);
195
- const borderLeft = getStyle(bq, 'borderLeftWidth');
196
- bq.remove();
197
- if(parseFloat(borderLeft) > 0){
198
- pass(`Blockquote has left border: ${borderLeft}`);
199
- } else {
200
- fail('Blockquote should have left border');
201
- }
202
- },
203
-
204
- 'should style hr as border': ({pass, fail}) => {
205
- const hr = document.createElement('hr');
206
- document.body.appendChild(hr);
207
- const borderTop = getStyle(hr, 'borderTopWidth');
208
- hr.remove();
209
- if(parseFloat(borderTop) > 0){
210
- pass(`hr has top border: ${borderTop}`);
211
- } else {
212
- fail('hr should have top border');
213
- }
214
- },
215
-
216
- 'should apply .ff-mono class': ({pass, fail}) => {
217
- const el = document.createElement('span');
218
- el.className = 'ff-mono';
219
- document.body.appendChild(el);
220
- const fontFamily = getStyle(el, 'fontFamily');
221
- el.remove();
222
- if(fontFamily.toLowerCase().includes('mono') || fontFamily.toLowerCase().includes('consolas')){
223
- pass(`.ff-mono applies monospace: ${fontFamily}`);
224
- } else {
225
- fail(`Expected monospace, got ${fontFamily}`);
226
- }
227
- },
228
-
229
- 'should apply .no-link class': ({pass, fail}) => {
230
- const a = document.createElement('a');
231
- a.className = 'no-link';
232
- a.href = '#';
233
- document.body.appendChild(a);
234
- const textDecoration = getStyle(a, 'textDecorationLine');
235
- a.remove();
236
- if(textDecoration === 'none'){
237
- pass('.no-link removes text decoration');
238
- } else {
239
- fail(`Expected no decoration, got ${textDecoration}`);
240
- }
241
- },
242
-
243
- 'should apply .td-n class': ({pass, fail}) => {
244
- const el = document.createElement('span');
245
- el.className = 'td-n';
246
- document.body.appendChild(el);
247
- const textDecoration = getStyle(el, 'textDecorationLine');
248
- el.remove();
249
- if(textDecoration === 'none'){
250
- pass('.td-n sets text-decoration: none');
251
- } else {
252
- fail(`Expected none, got ${textDecoration}`);
253
- }
254
- }
255
- };
1
+ const getStyle = (el, prop) => getComputedStyle(el)[prop];
2
+
3
+ export const beforeAll = async () => {
4
+ const link = document.createElement('link');
5
+ link.rel = 'stylesheet';
6
+ link.href = '/src/kempo.css';
7
+ document.head.appendChild(link);
8
+ await new Promise(resolve => link.onload = resolve);
9
+ };
10
+
11
+ export default {
12
+ 'should apply small font size with .small': ({pass, fail}) => {
13
+ const el = document.createElement('span');
14
+ el.className = 'small';
15
+ const normal = document.createElement('span');
16
+ document.body.appendChild(el);
17
+ document.body.appendChild(normal);
18
+ const smallSize = parseFloat(getStyle(el, 'fontSize'));
19
+ const normalSize = parseFloat(getStyle(normal, 'fontSize'));
20
+ el.remove();
21
+ normal.remove();
22
+ if(smallSize < normalSize){
23
+ pass(`.small reduces font size (${smallSize}px < ${normalSize}px)`);
24
+ } else {
25
+ fail(`Expected smaller font, got ${smallSize}px vs ${normalSize}px`);
26
+ }
27
+ },
28
+
29
+ 'should apply large font size with .large': ({pass, fail}) => {
30
+ const el = document.createElement('span');
31
+ el.className = 'large';
32
+ const normal = document.createElement('span');
33
+ document.body.appendChild(el);
34
+ document.body.appendChild(normal);
35
+ const largeSize = parseFloat(getStyle(el, 'fontSize'));
36
+ const normalSize = parseFloat(getStyle(normal, 'fontSize'));
37
+ el.remove();
38
+ normal.remove();
39
+ if(largeSize > normalSize){
40
+ pass(`.large increases font size (${largeSize}px > ${normalSize}px)`);
41
+ } else {
42
+ fail(`Expected larger font, got ${largeSize}px vs ${normalSize}px`);
43
+ }
44
+ },
45
+
46
+ 'should apply bold font weight to headings': ({pass, fail}) => {
47
+ const h1 = document.createElement('h1');
48
+ document.body.appendChild(h1);
49
+ const weight = getStyle(h1, 'fontWeight');
50
+ h1.remove();
51
+ if(parseInt(weight) >= 700){
52
+ pass(`Headings are bold (weight: ${weight})`);
53
+ } else {
54
+ fail(`Expected bold weight >= 700, got ${weight}`);
55
+ }
56
+ },
57
+
58
+ 'should apply heading font sizes in descending order': ({pass, fail}) => {
59
+ const sizes = [];
60
+ for(let i = 1; i <= 6; i++){
61
+ const h = document.createElement(`h${i}`);
62
+ document.body.appendChild(h);
63
+ sizes.push(parseFloat(getStyle(h, 'fontSize')));
64
+ h.remove();
65
+ }
66
+ let descending = true;
67
+ for(let i = 0; i < sizes.length - 1; i++){
68
+ if(sizes[i] <= sizes[i + 1]){
69
+ descending = false;
70
+ break;
71
+ }
72
+ }
73
+ if(descending){
74
+ pass(`Heading sizes descend: ${sizes.join(' > ')}`);
75
+ } else {
76
+ fail(`Expected descending sizes, got: ${sizes.join(', ')}`);
77
+ }
78
+ },
79
+
80
+ 'should apply heading classes .h1-.h6': ({pass, fail}) => {
81
+ const failed = [];
82
+ for(let i = 1; i <= 6; i++){
83
+ const div = document.createElement('div');
84
+ div.className = `h${i}`;
85
+ const h = document.createElement(`h${i}`);
86
+ document.body.appendChild(div);
87
+ document.body.appendChild(h);
88
+ const divSize = getStyle(div, 'fontSize');
89
+ const hSize = getStyle(h, 'fontSize');
90
+ div.remove();
91
+ h.remove();
92
+ if(divSize !== hSize){
93
+ failed.push(`h${i}: ${divSize} vs ${hSize}`);
94
+ }
95
+ }
96
+ if(failed.length === 0){
97
+ pass('.h1-.h6 classes match heading sizes');
98
+ } else {
99
+ fail(`Size mismatches: ${failed.join(', ')}`);
100
+ }
101
+ },
102
+
103
+ 'should apply monospace font to code': ({pass, fail}) => {
104
+ const code = document.createElement('code');
105
+ document.body.appendChild(code);
106
+ const fontFamily = getStyle(code, 'fontFamily');
107
+ code.remove();
108
+ if(fontFamily.toLowerCase().includes('mono') || fontFamily.toLowerCase().includes('consolas')){
109
+ pass(`Code uses monospace font: ${fontFamily}`);
110
+ } else {
111
+ fail(`Expected monospace font, got ${fontFamily}`);
112
+ }
113
+ },
114
+
115
+ 'should apply background to code': ({pass, fail}) => {
116
+ const code = document.createElement('code');
117
+ code.textContent = 'test';
118
+ document.body.appendChild(code);
119
+ const bg = getStyle(code, 'backgroundColor');
120
+ code.remove();
121
+ if(bg && bg !== 'rgba(0, 0, 0, 0)' && bg !== 'transparent'){
122
+ pass(`Code has background: ${bg}`);
123
+ } else {
124
+ fail('Code should have a background color');
125
+ }
126
+ },
127
+
128
+ 'should style pre code as block': ({pass, fail}) => {
129
+ const pre = document.createElement('pre');
130
+ const code = document.createElement('code');
131
+ pre.appendChild(code);
132
+ document.body.appendChild(pre);
133
+ const display = getStyle(code, 'display');
134
+ pre.remove();
135
+ if(display === 'block'){
136
+ pass('pre code displays as block');
137
+ } else {
138
+ fail(`Expected block display, got ${display}`);
139
+ }
140
+ },
141
+
142
+ 'should apply text alignment classes': ({pass, fail}) => {
143
+ const tests = [
144
+ {className: 'ta-left', expected: 'left'},
145
+ {className: 'ta-center', expected: 'center'},
146
+ {className: 'ta-right', expected: 'right'}
147
+ ];
148
+ const failed = [];
149
+ tests.forEach(({className, expected}) => {
150
+ const el = document.createElement('div');
151
+ el.className = className;
152
+ document.body.appendChild(el);
153
+ const align = getStyle(el, 'textAlign');
154
+ el.remove();
155
+ if(align !== expected && align !== `${expected}`){
156
+ failed.push(`${className}: ${align}`);
157
+ }
158
+ });
159
+ if(failed.length === 0){
160
+ pass('Text alignment classes work correctly');
161
+ } else {
162
+ fail(`Alignment issues: ${failed.join(', ')}`);
163
+ }
164
+ },
165
+
166
+ 'should style links with color': ({pass, fail}) => {
167
+ const a = document.createElement('a');
168
+ a.href = '#';
169
+ document.body.appendChild(a);
170
+ const color = getStyle(a, 'color');
171
+ a.remove();
172
+ if(color && color !== 'rgb(0, 0, 0)'){
173
+ pass(`Links have color: ${color}`);
174
+ } else {
175
+ fail('Links should have a distinct color');
176
+ }
177
+ },
178
+
179
+ 'should apply .link class styling': ({pass, fail}) => {
180
+ const span = document.createElement('span');
181
+ span.className = 'link';
182
+ document.body.appendChild(span);
183
+ const color = getStyle(span, 'color');
184
+ span.remove();
185
+ if(color && color !== 'rgb(0, 0, 0)'){
186
+ pass(`.link class applies link color: ${color}`);
187
+ } else {
188
+ fail('.link should have link color');
189
+ }
190
+ },
191
+
192
+ 'should style blockquote with left border': ({pass, fail}) => {
193
+ const bq = document.createElement('blockquote');
194
+ document.body.appendChild(bq);
195
+ const borderLeft = getStyle(bq, 'borderLeftWidth');
196
+ bq.remove();
197
+ if(parseFloat(borderLeft) > 0){
198
+ pass(`Blockquote has left border: ${borderLeft}`);
199
+ } else {
200
+ fail('Blockquote should have left border');
201
+ }
202
+ },
203
+
204
+ 'should style hr as border': ({pass, fail}) => {
205
+ const hr = document.createElement('hr');
206
+ document.body.appendChild(hr);
207
+ const borderTop = getStyle(hr, 'borderTopWidth');
208
+ hr.remove();
209
+ if(parseFloat(borderTop) > 0){
210
+ pass(`hr has top border: ${borderTop}`);
211
+ } else {
212
+ fail('hr should have top border');
213
+ }
214
+ },
215
+
216
+ 'should apply .ff-mono class': ({pass, fail}) => {
217
+ const el = document.createElement('span');
218
+ el.className = 'ff-mono';
219
+ document.body.appendChild(el);
220
+ const fontFamily = getStyle(el, 'fontFamily');
221
+ el.remove();
222
+ if(fontFamily.toLowerCase().includes('mono') || fontFamily.toLowerCase().includes('consolas')){
223
+ pass(`.ff-mono applies monospace: ${fontFamily}`);
224
+ } else {
225
+ fail(`Expected monospace, got ${fontFamily}`);
226
+ }
227
+ },
228
+
229
+ 'should apply .no-link class': ({pass, fail}) => {
230
+ const a = document.createElement('a');
231
+ a.className = 'no-link';
232
+ a.href = '#';
233
+ document.body.appendChild(a);
234
+ const textDecoration = getStyle(a, 'textDecorationLine');
235
+ a.remove();
236
+ if(textDecoration === 'none'){
237
+ pass('.no-link removes text decoration');
238
+ } else {
239
+ fail(`Expected no decoration, got ${textDecoration}`);
240
+ }
241
+ },
242
+
243
+ 'should apply .td-n class': ({pass, fail}) => {
244
+ const el = document.createElement('span');
245
+ el.className = 'td-n';
246
+ document.body.appendChild(el);
247
+ const textDecoration = getStyle(el, 'textDecorationLine');
248
+ el.remove();
249
+ if(textDecoration === 'none'){
250
+ pass('.td-n sets text-decoration: none');
251
+ } else {
252
+ fail(`Expected none, got ${textDecoration}`);
253
+ }
254
+ }
255
+ };
@@ -1,39 +0,0 @@
1
- name: Publish Major Version to npmjs
2
-
3
- on:
4
- workflow_dispatch:
5
-
6
- jobs:
7
- publish:
8
- runs-on: ubuntu-latest
9
- permissions:
10
- contents: write
11
- id-token: write # enables npm provenance
12
- steps:
13
- - uses: actions/checkout@v4
14
- with:
15
- token: ${{ secrets.GITHUB_TOKEN }}
16
-
17
- # Setup Node and create an .npmrc that uses the token from NODE_AUTH_TOKEN
18
- - uses: actions/setup-node@v4
19
- with:
20
- node-version: '20.x'
21
- registry-url: 'https://registry.npmjs.org'
22
-
23
- - run: npm ci
24
-
25
- # Auto-increment major version, commit, and push
26
- - name: Bump major version
27
- run: |
28
- git config --global user.name "github-actions"
29
- git config --global user.email "github-actions@github.com"
30
- npm version major --no-git-tag-version
31
- git add package.json package-lock.json || true
32
- git commit -m "ci: bump major version [skip ci]" || echo "No changes to commit"
33
- git push origin HEAD:main || echo "No changes to push"
34
- env:
35
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36
-
37
- - run: npm publish --provenance --access public
38
- env:
39
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -1,39 +0,0 @@
1
- name: Publish Minor Version to npmjs
2
-
3
- on:
4
- workflow_dispatch:
5
-
6
- jobs:
7
- publish:
8
- runs-on: ubuntu-latest
9
- permissions:
10
- contents: write
11
- id-token: write # enables npm provenance
12
- steps:
13
- - uses: actions/checkout@v4
14
- with:
15
- token: ${{ secrets.GITHUB_TOKEN }}
16
-
17
- # Setup Node and create an .npmrc that uses the token from NODE_AUTH_TOKEN
18
- - uses: actions/setup-node@v4
19
- with:
20
- node-version: '20.x'
21
- registry-url: 'https://registry.npmjs.org'
22
-
23
- - run: npm ci
24
-
25
- # Auto-increment minor version, commit, and push
26
- - name: Bump minor version
27
- run: |
28
- git config --global user.name "github-actions"
29
- git config --global user.email "github-actions@github.com"
30
- npm version minor --no-git-tag-version
31
- git add package.json package-lock.json || true
32
- git commit -m "ci: bump minor version [skip ci]" || echo "No changes to commit"
33
- git push origin HEAD:main || echo "No changes to push"
34
- env:
35
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36
-
37
- - run: npm publish --provenance --access public
38
- env:
39
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -1,45 +0,0 @@
1
-
2
- name: Publish Patch Version to npmjs
3
-
4
- on:
5
- push:
6
- branches:
7
- - main
8
- workflow_dispatch:
9
-
10
- jobs:
11
- publish:
12
- runs-on: ubuntu-latest
13
- permissions:
14
- contents: write
15
- id-token: write # enables npm provenance
16
- steps:
17
- - uses: actions/checkout@v4
18
- with:
19
- token: ${{ secrets.GITHUB_TOKEN }}
20
-
21
- # Setup Node and create an .npmrc that uses the token from NODE_AUTH_TOKEN
22
- - uses: actions/setup-node@v4
23
- with:
24
- node-version: '20.x'
25
- registry-url: 'https://registry.npmjs.org'
26
-
27
- - run: npm ci
28
-
29
- # Auto-increment patch version, commit, and push
30
- - name: Bump patch version
31
- run: |
32
- git config --global user.name "github-actions"
33
- git config --global user.email "github-actions@github.com"
34
- npm version patch --no-git-tag-version
35
- git add package.json package-lock.json || true
36
- git commit -m "ci: bump patch version [skip ci]" || echo "No changes to commit"
37
- git push origin HEAD:main || echo "No changes to push"
38
- env:
39
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40
-
41
- # If your package is public and scoped (e.g., @scope/name), keep --access public.
42
- # For unscoped public packages, you can omit --access.
43
- - run: npm publish --provenance --access public
44
- env:
45
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}