@reykjavik/webtools 0.1.11 → 0.1.12

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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,14 @@
4
4
 
5
5
  - ... <!-- Add new lines here. -->
6
6
 
7
+ ## 0.1.12
8
+
9
+ _2024-02-29_
10
+
11
+ - feat: Add `@reykjavik/webtools/next/vanillaExtract` component — with
12
+ plain-CSS injection helpers
13
+ - fix: Mark `peerDependencies` as optional
14
+
7
15
  ## 0.1.11
8
16
 
9
17
  _2024-02-14_
package/README.md CHANGED
@@ -33,6 +33,12 @@ bun add @reykjavik/webtools
33
33
  - [`SiteImprove` component](#siteimprove-component)
34
34
  - [`pingSiteImprove` helper](#pingsiteimprove-helper)
35
35
  - [`pingSiteImproveOutbound` helper](#pingsiteimproveoutbound-helper)
36
+ - [`@reykjavik/webtools/vanillaExtract`](#reykjavikwebtoolsvanillaextract)
37
+ - [`vanillaGlobal`](#vanillaglobal)
38
+ - [`vanillaProps`](#vanillaprops)
39
+ - [`vanillaClass`](#vanillaclass)
40
+ - [`vanillaClassNested`](#vanillaclassnested)
41
+ - [`vanillaNest`](#vanillanest)
36
42
  - [Contributing](#contributing)
37
43
  - [Changelog](#changelog)
38
44
 
@@ -502,6 +508,170 @@ const handleSubmit = () => {
502
508
 
503
509
  ---
504
510
 
511
+ ## `@reykjavik/webtools/vanillaExtract`
512
+
513
+ Contains helpers for writing [vanilla-extract](https://vanilla-extract.style)
514
+ styles using plain CSS styntax.
515
+
516
+ This provides an "escape hatch" into regular CSS, when you're willing to trade
517
+ local type-safety for access to the full features and expressiveness of real
518
+ CSS.
519
+ ([Background info](https://github.com/vanilla-extract-css/vanilla-extract/discussions/898#discussioncomment-7125457).)
520
+
521
+ ### `vanillaGlobal`
522
+
523
+ **Syntax:** `vanillaGlobal: (css: string) => void`
524
+
525
+ Inserts free-form CSS as a vanilla-extract `globalStyle`.
526
+
527
+ ```ts
528
+ import { vanillaGlobal } from '@reykjavik/webtools/vanillaExtract';
529
+
530
+ vanillaGlobal(`
531
+ body {
532
+ background-color: rebeccapurple;
533
+ }
534
+ `);
535
+ ```
536
+
537
+ ### `vanillaProps`
538
+
539
+ **Syntax:** `vanillaProps: (css: string) => GlobalStyleRule`
540
+
541
+ Spreads the return value into a style object, to inject free-form CSS
542
+ properties (or nested blocks)
543
+
544
+ ```ts
545
+ import { style } from '@vanilla-extract/css';
546
+ import { vanillaProps } from '@reykjavik/webtools/vanillaExtract';
547
+
548
+ const myStyle = style({
549
+ color: 'darksalmon',
550
+ // ...other style props...
551
+
552
+ ...vanillaProps(`
553
+ /* Plain CSS that's injected into the "myStyle" style block */
554
+ border-bottom: 1px solid red;
555
+ color: ${theme.color.primary}; /* I can still use typesafe values */
556
+ random-css-prop-normally-rejected-by-vanilla-extract: 'YOLO!';
557
+ `),
558
+ });
559
+ ```
560
+
561
+ ### `vanillaClass`
562
+
563
+ **Syntax:** `vanillaClass: (css: string) => string`
564
+ **Syntax:** `vanillaClass: (debugId: string, css: string) => string`
565
+
566
+ Returns a scoped cssClassName styled with free-form CSS. This function is a
567
+ thin wrapper around vanilla-extract's `style` function.
568
+
569
+ ```ts
570
+ import { vanillaClass } from '@reykjavik/webtools/vanillaExtract';
571
+
572
+ export const myClass = vanillaClass(`
573
+ background-color: #ccc;
574
+ padding: .5em 1em;
575
+ `);
576
+
577
+ export const humanReadableClass = vanillaClass(
578
+ 'HumanReadable',
579
+ `
580
+ border: 1px dashed hotpink;
581
+ cursor: pointer;
582
+ `
583
+ );
584
+ ```
585
+
586
+ ### `vanillaClassNested`
587
+
588
+ **Syntax:** `vanillaClassNested: (css: string) => string`
589
+ **Syntax:** `vanillaClassNested: (debugId: string, css: string) => string`
590
+
591
+ Returns a scoped cssClassName styled with free-form CSS.
592
+
593
+ It also automatically replaces all `&`-tokens with the selector for the
594
+ auto-generated class-name.
595
+
596
+ ```ts
597
+ import { vanillaClassNested } from '@reykjavik/webtools/vanillaExtract';
598
+
599
+ export const myClass = vanillaClassNested(`
600
+ background-color: #ccc;
601
+ padding: .5em 1em;
602
+
603
+ /* Nested blocks begin: */
604
+ &:hover {
605
+ background-color: #666;
606
+ color: white;
607
+ }
608
+ & > strong {
609
+ color: maroon;
610
+ }
611
+ html[data-color-theme="unicorn"] & {
612
+ background-color: pink;
613
+ }
614
+ `);
615
+ ```
616
+
617
+ **NOTE:** All "bare" (un-nested) style properties **must come first**, before
618
+ any nested blocks.
619
+
620
+ **NOTE 2:** `vanillaClassNested` does NOT support deeply nested blocks, or
621
+ anything so fancy. It will also replace `&` characters inside values,
622
+ comments, etc. If you need something more sophisticated, use a custom
623
+ `postcss` config.
624
+
625
+ ### `vanillaNest`
626
+
627
+ **Syntax:** `vanillaNest: (ampSelector: string, css: string) => string`
628
+
629
+ Replaces all `&` tokens with the given selector string, in a direct (read.
630
+ "dumb") way. It's mainly useful when used with style-mixins, etc.
631
+
632
+ This low-level utility function is used internally by
633
+ [`vanillaClassNested`](#vanillaclassnested).
634
+
635
+ ```ts
636
+ import { vanillaNest } from '@reykjavik/webtools/vanillaExtract';
637
+
638
+ const hoverGlow = (ampSelector: string, glowiness?: 'normal' | 'insane') =>
639
+ vanillaNest(
640
+ ampSelector,
641
+ `
642
+ &:hover {
643
+ box-shadow: 0 0 20px 5px ${
644
+ glowiness === 'insane' ? 'hotpink' : 'salmon'
645
+ };
646
+ }
647
+ `
648
+ );
649
+
650
+ // ...then, somewhere else
651
+
652
+ import { vanillaGlobal } from '@reykjavik/webtools/vanillaExtract';
653
+
654
+ vanillaGlobal(`
655
+ .MyComponent {
656
+ border: 1px solid #ccc;
657
+ padding: 1em;
658
+ }
659
+ ${hoverGlow('.MyComponent')}
660
+
661
+ .MyOtherComponent {
662
+ border: 1px solid #ccc;
663
+ padding: 1em;
664
+ }
665
+ ${hoverGlow('.MyOtherComponent', 'insane')}
666
+ `);
667
+ ```
668
+
669
+ **NOTE:** `vanillaNest` does NOT support deeply nested blocks, or anything so
670
+ fancy. It will also replace `&` characters inside values, comments, etc. If
671
+ you need something more sophisticated, use a custom `postcss` config.
672
+
673
+ ---
674
+
505
675
  ## Contributing
506
676
 
507
677
  This project uses the [Bun runtime](https://bun.sh) for development (tests,
@@ -519,3 +689,7 @@ See
519
689
  ```
520
690
 
521
691
  ```
692
+
693
+ ```
694
+
695
+ ```
package/esm/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference path="./vanillaExtract.d.ts" />
1
2
  /// <reference path="./http.d.ts" />
2
3
  /// <reference path="./CookieHubConsent.d.tsx" />
3
4
  /// <reference path="./next/SiteImprove.d.tsx" />
@@ -0,0 +1,46 @@
1
+ import { GlobalStyleRule } from '@vanilla-extract/css';
2
+ /**
3
+ * Adds free-form CSS as a globalStyle
4
+ *
5
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillaglobal
6
+ */
7
+ export declare const vanillaGlobal: (css: string) => void;
8
+ /**
9
+ * Spreads the return value into a style object, to inject free-form CSS
10
+ * properties (or nested blocks)
11
+ *
12
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillaprops
13
+ */
14
+ export declare const vanillaProps: (css: string) => GlobalStyleRule;
15
+ /**
16
+ * Returns a scoped cssClassName styled with free-form CSS
17
+ *
18
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillaclass
19
+ */
20
+ export declare function vanillaClass(css: string): string;
21
+ export declare function vanillaClass(debugId: string, css: string): string;
22
+ /**
23
+ * Replaces all `&` tokens with the given selector string, in a direct
24
+ * (read. "dumb") way. It's mainly useful when used with style-mixins, etc.
25
+ *
26
+ * NOTE: It does NOT support deeply nested blocks, or anything so fancy.
27
+ * It will also replace "&" characters inside values, comments, etc.
28
+ * If you need something more sophisticated, use a custom `postcss` config.
29
+ *
30
+ *
31
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillanest
32
+ */
33
+ export declare const vanillaNest: (ampSelector: string, css: string) => string;
34
+ /**
35
+ * Returns a scoped cssClassName styled with free-form CSS.
36
+ *
37
+ * It also automatically replaces all `&`-tokens with
38
+ * the selector for the auto-generated class-name.
39
+ *
40
+ * NOTE: All "bare" (un-nested) style properties must come first,
41
+ * before any nested blocks.
42
+ *
43
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillaclassnested
44
+ */
45
+ export declare function vanillaClassNested(css: string): string;
46
+ export declare function vanillaClassNested(debugId: string, css: string): string;
@@ -0,0 +1,45 @@
1
+ import { globalStyle, style } from '@vanilla-extract/css';
2
+ /**
3
+ * Adds free-form CSS as a globalStyle
4
+ *
5
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillaglobal
6
+ */
7
+ export const vanillaGlobal = (css) => globalStyle('x', { x: `} ${css} x{x:` });
8
+ // ---------------------------------------------------------------------------
9
+ /**
10
+ * Spreads the return value into a style object, to inject free-form CSS
11
+ * properties (or nested blocks)
12
+ *
13
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillaprops
14
+ */
15
+ export const vanillaProps = (css) => ({ x: `; ${css}` });
16
+ export function vanillaClass(cssOrDebugId, css) {
17
+ const debugId = css != null ? cssOrDebugId : undefined;
18
+ css = css != null ? css : cssOrDebugId;
19
+ return style(vanillaProps(css), debugId);
20
+ }
21
+ // ---------------------------------------------------------------------------
22
+ /**
23
+ * Replaces all `&` tokens with the given selector string, in a direct
24
+ * (read. "dumb") way. It's mainly useful when used with style-mixins, etc.
25
+ *
26
+ * NOTE: It does NOT support deeply nested blocks, or anything so fancy.
27
+ * It will also replace "&" characters inside values, comments, etc.
28
+ * If you need something more sophisticated, use a custom `postcss` config.
29
+ *
30
+ *
31
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillanest
32
+ */
33
+ export const vanillaNest = (ampSelector, css) => css.replace(/&/g, ampSelector);
34
+ export function vanillaClassNested(cssOrDebugId, css) {
35
+ const debugId = css != null ? cssOrDebugId : undefined;
36
+ css = css != null ? css : cssOrDebugId;
37
+ const nestPoint = css.indexOf('&');
38
+ const bareStyles = nestPoint > -1 ? css.slice(0, nestPoint) : css;
39
+ const nestedStyles = nestPoint > -1 ? css.slice(nestPoint) : undefined;
40
+ const className = style(vanillaProps(bareStyles), debugId);
41
+ if (nestedStyles) {
42
+ vanillaGlobal(vanillaNest(`.${className}`, nestedStyles));
43
+ }
44
+ return className;
45
+ }
package/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference path="./vanillaExtract.d.ts" />
1
2
  /// <reference path="./http.d.ts" />
2
3
  /// <reference path="./CookieHubConsent.d.tsx" />
3
4
  /// <reference path="./next/SiteImprove.d.tsx" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reykjavik/webtools",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "description": "Misc. JS/TS helpers used by Reykjavík City's web dev teams.",
5
5
  "main": "index.js",
6
6
  "repository": "ssh://git@github.com:reykjavikcity/webtools.git",
@@ -14,10 +14,25 @@
14
14
  "@reykjavik/hanna-utils": "^0.2.3"
15
15
  },
16
16
  "peerDependencies": {
17
+ "@vanilla-extract/css": "^1.14.1",
17
18
  "next": ">=11",
18
19
  "react": ">=16.8.0",
19
20
  "react-dom": ">=16.8.0"
20
21
  },
22
+ "peerDependenciesMeta": {
23
+ "@vanilla-extract/css": {
24
+ "optional": true
25
+ },
26
+ "next": {
27
+ "optional": true
28
+ },
29
+ "react": {
30
+ "optional": true
31
+ },
32
+ "react-dom": {
33
+ "optional": true
34
+ }
35
+ },
21
36
  "engines": {
22
37
  "node": ">=16"
23
38
  },
@@ -27,6 +42,10 @@
27
42
  "import": "./esm/index.js",
28
43
  "require": "./index.js"
29
44
  },
45
+ "./vanillaExtract": {
46
+ "import": "./esm/vanillaExtract.js",
47
+ "require": "./vanillaExtract.js"
48
+ },
30
49
  "./http": {
31
50
  "import": "./esm/http.js",
32
51
  "require": "./http.js"
@@ -0,0 +1,46 @@
1
+ import { GlobalStyleRule } from '@vanilla-extract/css';
2
+ /**
3
+ * Adds free-form CSS as a globalStyle
4
+ *
5
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillaglobal
6
+ */
7
+ export declare const vanillaGlobal: (css: string) => void;
8
+ /**
9
+ * Spreads the return value into a style object, to inject free-form CSS
10
+ * properties (or nested blocks)
11
+ *
12
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillaprops
13
+ */
14
+ export declare const vanillaProps: (css: string) => GlobalStyleRule;
15
+ /**
16
+ * Returns a scoped cssClassName styled with free-form CSS
17
+ *
18
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillaclass
19
+ */
20
+ export declare function vanillaClass(css: string): string;
21
+ export declare function vanillaClass(debugId: string, css: string): string;
22
+ /**
23
+ * Replaces all `&` tokens with the given selector string, in a direct
24
+ * (read. "dumb") way. It's mainly useful when used with style-mixins, etc.
25
+ *
26
+ * NOTE: It does NOT support deeply nested blocks, or anything so fancy.
27
+ * It will also replace "&" characters inside values, comments, etc.
28
+ * If you need something more sophisticated, use a custom `postcss` config.
29
+ *
30
+ *
31
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillanest
32
+ */
33
+ export declare const vanillaNest: (ampSelector: string, css: string) => string;
34
+ /**
35
+ * Returns a scoped cssClassName styled with free-form CSS.
36
+ *
37
+ * It also automatically replaces all `&`-tokens with
38
+ * the selector for the auto-generated class-name.
39
+ *
40
+ * NOTE: All "bare" (un-nested) style properties must come first,
41
+ * before any nested blocks.
42
+ *
43
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillaclassnested
44
+ */
45
+ export declare function vanillaClassNested(css: string): string;
46
+ export declare function vanillaClassNested(debugId: string, css: string): string;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.vanillaClassNested = exports.vanillaNest = exports.vanillaClass = exports.vanillaProps = exports.vanillaGlobal = void 0;
4
+ const css_1 = require("@vanilla-extract/css");
5
+ /**
6
+ * Adds free-form CSS as a globalStyle
7
+ *
8
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillaglobal
9
+ */
10
+ const vanillaGlobal = (css) => (0, css_1.globalStyle)('x', { x: `} ${css} x{x:` });
11
+ exports.vanillaGlobal = vanillaGlobal;
12
+ // ---------------------------------------------------------------------------
13
+ /**
14
+ * Spreads the return value into a style object, to inject free-form CSS
15
+ * properties (or nested blocks)
16
+ *
17
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillaprops
18
+ */
19
+ const vanillaProps = (css) => ({ x: `; ${css}` });
20
+ exports.vanillaProps = vanillaProps;
21
+ function vanillaClass(cssOrDebugId, css) {
22
+ const debugId = css != null ? cssOrDebugId : undefined;
23
+ css = css != null ? css : cssOrDebugId;
24
+ return (0, css_1.style)((0, exports.vanillaProps)(css), debugId);
25
+ }
26
+ exports.vanillaClass = vanillaClass;
27
+ // ---------------------------------------------------------------------------
28
+ /**
29
+ * Replaces all `&` tokens with the given selector string, in a direct
30
+ * (read. "dumb") way. It's mainly useful when used with style-mixins, etc.
31
+ *
32
+ * NOTE: It does NOT support deeply nested blocks, or anything so fancy.
33
+ * It will also replace "&" characters inside values, comments, etc.
34
+ * If you need something more sophisticated, use a custom `postcss` config.
35
+ *
36
+ *
37
+ * @see https://github.com/reykjavikcity/webtools/tree/v0.1#vanillanest
38
+ */
39
+ const vanillaNest = (ampSelector, css) => css.replace(/&/g, ampSelector);
40
+ exports.vanillaNest = vanillaNest;
41
+ function vanillaClassNested(cssOrDebugId, css) {
42
+ const debugId = css != null ? cssOrDebugId : undefined;
43
+ css = css != null ? css : cssOrDebugId;
44
+ const nestPoint = css.indexOf('&');
45
+ const bareStyles = nestPoint > -1 ? css.slice(0, nestPoint) : css;
46
+ const nestedStyles = nestPoint > -1 ? css.slice(nestPoint) : undefined;
47
+ const className = (0, css_1.style)((0, exports.vanillaProps)(bareStyles), debugId);
48
+ if (nestedStyles) {
49
+ (0, exports.vanillaGlobal)((0, exports.vanillaNest)(`.${className}`, nestedStyles));
50
+ }
51
+ return className;
52
+ }
53
+ exports.vanillaClassNested = vanillaClassNested;