Skip to content

Commit 712cf55

Browse files
committed
Add getCookiesString
1 parent 16d8f87 commit 712cf55

5 files changed

Lines changed: 47 additions & 182 deletions

File tree

packages/cookies/README.md

Lines changed: 25 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
<p>
2-
<img width="100%" src="https://assets.solidjs.com/banner?type=Primitives&background=tiles&project=start" alt="Solid Primitives start">
2+
<img width="100%" src="https://assets.solidjs.com/banner?type=Primitives&background=tiles&project=cookies" alt="Solid Primitives cookies">
33
</p>
44

5-
# @solid-primitives/start
5+
# @solid-primitives/cookies
66

77
[![turborepo](https://img.shields.io/badge/built%20with-turborepo-cc00ff.svg?style=for-the-badge&logo=turborepo)](https://turborepo.org/)
8-
[![size](https://img.shields.io/bundlephobia/minzip/@solid-primitives/start?style=for-the-badge&label=size)](https://bundlephobia.com/package/@solid-primitives/start)
9-
[![version](https://img.shields.io/npm/v/@solid-primitives/start?style=for-the-badge)](https://www.npmjs.com/package/@solid-primitives/start)
8+
[![size](https://img.shields.io/bundlephobia/minzip/@solid-primitives/cookies?style=for-the-badge&label=size)](https://bundlephobia.com/package/@solid-primitives/cookies)
9+
[![version](https://img.shields.io/npm/v/@solid-primitives/cookies?style=for-the-badge)](https://www.npmjs.com/package/@solid-primitives/cookies)
1010
[![stage](https://img.shields.io/endpoint?style=for-the-badge&url=https%3A%2F%2Fraw.githubusercontent.com%2Fsolidjs-community%2Fsolid-primitives%2Fmain%2Fassets%2Fbadges%2Fstage-0.json)](https://github.com/solidjs-community/solid-primitives#contribution-process)
1111

12-
A set of primitives for Solid Start
12+
A set of primitives for handling cookies in solid
1313

1414
- [`createServerCookie`](#createservercookie) - Provides a getter and setter for a reactive cookie, which works isomorphically.
1515
- [`createUserTheme`](#createusertheme) - Creates a Server Cookie providing a type safe way to store a theme and access it on the server or client.
16-
- [`getUserAgent`](#getuseragent) - Creates a Server Cookie providing a type safe way to store a theme and access it on the server or client.
16+
- [`getCookiesString`](#getCookiesString) - A primitive that allows for the cookie string to be accessed isomorphically on the client, or on the server
1717

1818
## Installation
1919

2020
```bash
21-
npm install @solid-primitives/start
21+
npm install @solid-primitives/cookies
2222
# or
23-
yarn add @solid-primitives/start
23+
yarn add @solid-primitives/cookies
2424
# or
25-
pnpm add @solid-primitives/start
25+
pnpm add @solid-primitives/cookies
2626
```
2727

2828
## How to use it
@@ -32,6 +32,8 @@ pnpm add @solid-primitives/start
3232
A primitive for creating a cookie that can be accessed isomorphically on the client, or the server.
3333

3434
```ts
35+
import { createServerCookie } from "@solid-primitives/cookies"
36+
3537
const [cookie, setCookie] = createServerCookie("cookieName");
3638

3739
cookie(); // => string | undefined
@@ -42,6 +44,8 @@ cookie(); // => string | undefined
4244
Custom cookie serializers and deserializers can also be implemented
4345

4446
```ts
47+
import { createServerCookie } from "@solid-primitives/cookies"
48+
4549
const [serverCookie, setServerCookie] = createServerCookie("coolCookie", {
4650
deserialize: str => (str ? str.split(" ") : []), // Deserializes cookie into a string[]
4751
serialize: val => (val ? val.join(" ") : ""), // serializes the value back into a string
@@ -55,6 +59,8 @@ serverCookie(); // => string[]
5559
Composes `createServerCookie` to provide a type safe way to store a theme and access it on the server or client.
5660

5761
```ts
62+
import { createUserTheme } from "@solid-primitives/cookies"
63+
5864
const [theme, setTheme] = createUserTheme("cookieName");
5965

6066
theme(); // => "light" | "dark" | undefined
@@ -63,130 +69,30 @@ theme(); // => "light" | "dark" | undefined
6369
const [theme, setTheme] = createUserTheme("cookieName", {
6470
defaultValue: "light",
6571
});
66-
```
6772

6873
theme(); // => "light" | "dark"
74+
```
6975

70-
## `getUserAgent`
76+
## `getCookiesString`
7177

72-
Provides the value of the `userAgent` string isomorphically on the client or server
78+
A primitive that allows for the cookie string to be accessed isomorphically on the client, or on the server.
79+
Uses `getRequestEvent` on the server and `document.cookie` on the client.
7380

7481
```ts
75-
const userAgent: string | null = getUserAgent();
76-
```
82+
import { getCookiesString, parseCookie } from "@solid-primitives/cookies"
7783

78-
## Examples
79-
80-
### `root.tsx`
81-
82-
This is the main entry file for SolidStart demonstrating usage of the `createUserTheme` function.
83-
84-
- Initializes the theme with the `createUserTheme` function.
85-
- Toggles between the "dark" and "light" themes using a button.
86-
- Sets the `data-theme` attribute adding compatibility between `createUserTheme` and libraries like [DaisyUI](https://daisyui.com/).
87-
- Includes a clean implementation of theming through a `Body` class.
88-
- Provides additional examples on using variant classes to style components.
89-
90-
```tsx
91-
import { Suspense } from "solid-js";
92-
import {
93-
A,
94-
Body,
95-
ErrorBoundary,
96-
FileRoutes,
97-
Head,
98-
Html,
99-
Meta,
100-
Routes,
101-
Scripts,
102-
Title,
103-
} from "solid-start";
104-
import Counter from "./components/Counter";
105-
import "./root.css";
106-
import { createUserTheme } from "~/primitives/start";
107-
108-
export default function Root() {
109-
const [theme, setTheme] = createUserTheme("dark-light-theme", { defaultValue: "dark" });
110-
const toggleTheme = () => setTheme(currentTheme => (currentTheme === "dark" ? "light" : "dark"));
111-
112-
return (
113-
// Set data-theme when using libraries like Daisyui:
114-
<Html lang="en" data-theme={theme()}>
115-
<Head>
116-
<Title>SolidStart - Bare</Title>
117-
<Meta charset="utf-8" />
118-
<Meta name="viewport" content="width=device-width, initial-scale=1" />
119-
</Head>
120-
// Apply theme as a class to the Body element:
121-
<Body class={theme()}>
122-
<div>
123-
<Counter
124-
classList={{
125-
// Within components apply theme-dependent classes/variants:
126-
"dark-variant": theme() !== "light",
127-
"light-variant": theme() === "light",
128-
}}
129-
/>
130-
<button onClick={toggleTheme}>
131-
<span>Toggle Theme</span>
132-
</button>
133-
</div>
134-
<Scripts />
135-
</Body>
136-
</Html>
137-
);
138-
}
139-
```
140-
141-
### `root.css`
142-
143-
Here is an absolute basic CSS file to demonstrate styling with the themes.
144-
145-
- The `body` selector has general styles.
146-
- The `.dark` and `.light` classes provide specific styles for each theme.
147-
- The `.dark span` and `.light span` selectors show how to style specific elements based on the theme.
148-
149-
```css
150-
body {
151-
font-family: Gordita, Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
152-
height: "100vh";
153-
width: "100vh";
154-
}
155-
156-
body.dark {
157-
background-color: black;
158-
color: aliceblue;
159-
}
160-
body.light {
161-
background-color: aliceblue;
162-
color: black;
163-
}
164-
165-
.dark span {
166-
color: #b1d4ff;
167-
}
168-
.light span {
169-
color: #003677;
170-
}
84+
const string = getCookiesString()
85+
const cookie = parseCookie(string, "cookie_name")
17186
```
17287

173-
### `Counter.css`
17488

175-
Continuation of the basic CSS scoped to the component using variant classes.
176-
177-
```css
178-
.dark-variant {
179-
border: 2px solid #569cf3;
180-
}
89+
## Examples
18190

182-
.light-variant {
183-
border: 2px solid #05ff22;
184-
}
185-
```
91+
PRs welcome :)
18692

18793
## Demo
18894

189-
You can view a demo of this primitive here: <https://codesandbox.io/p/sandbox/amazing-easley-wqk38i?file=%2Fsrc%2Fstart_primitive%2Findex.ts%3A36%2C20>
95+
You can view a demo of this primitive here: <https://codesandbox.io/p/sandbox/amazing-easley-wqk38i?file=%2Fsrc%2Fcookies_primitive%2Findex.ts%3A36%2C20>
19096

19197
## Changelog
19298

packages/cookies/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"list": [
2323
"createServerCookie",
2424
"createUserTheme",
25-
"getUserAgent"
25+
"getCookiesString"
2626
],
2727
"category": "Solid Start"
2828
},

packages/cookies/src/index.ts

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,6 @@
11
import { createSignal, createEffect, Signal } from "solid-js";
22
import { getRequestEvent, isServer } from "solid-js/web";
33

4-
export type MaxAgeOptions = {
5-
/**
6-
* The maximum age of the cookie in seconds. Defaults to 1 year.
7-
*/
8-
cookieMaxAge?: number;
9-
};
10-
11-
export type ServerCookieOptions<T = string> = MaxAgeOptions & {
12-
/**
13-
* A function to deserialize the cookie value to be used as signal value
14-
*/
15-
deserialize?: (str: string | undefined) => T;
16-
/**
17-
* A function to serialize the signal value to be used as cookie value
18-
*/
19-
serialize?: (value: T) => string;
20-
};
21-
224
const YEAR = 365 * 24 * 60 * 60;
235

246
/*
@@ -34,16 +16,28 @@ export function parseCookie(cookie: string, key: string): string | undefined {
3416
}
3517

3618
/**
37-
* A primitive that allows for the user agent string to be accessed isomorphically on the client, or on the server
38-
* @return Returns the user agent string, or null
19+
* A primitive that allows for the cookie string to be accessed isomorphically on the client, or on the server
20+
* @return Returns the cookie string
3921
*/
40-
export function getUserAgent(): string | null {
22+
export function getCookiesString(): string {
4123
if (isServer) {
42-
return getRequestEvent()?.request.headers.get("user-agent") ?? null
24+
return getRequestEvent()?.request.headers.get("cookie") ?? ""
4325
}
44-
return navigator.userAgent
26+
return document.cookie
4527
}
4628

29+
export type MaxAgeOptions = {
30+
/** The maximum age of the cookie in seconds. Defaults to 1 year. */
31+
cookieMaxAge?: number;
32+
};
33+
34+
export type ServerCookieOptions<T = string> = MaxAgeOptions & {
35+
/** A function to deserialize the cookie value to be used as signal value */
36+
deserialize?: (str: string | undefined) => T;
37+
/** A function to serialize the signal value to be used as cookie value */
38+
serialize?: (value: T) => string;
39+
};
40+
4741
/**
4842
* A primitive for creating a cookie that can be accessed isomorphically on the client, or the server
4943
*
@@ -72,14 +66,7 @@ export function createServerCookie<T>(
7266
cookieMaxAge = YEAR,
7367
} = options ?? {};
7468

75-
const [cookie, setCookie] = createSignal(
76-
deserialize(
77-
parseCookie(
78-
isServer ? getRequestEvent()?.request.headers.get("cookie") ?? "" : document.cookie,
79-
name,
80-
),
81-
),
82-
);
69+
const [cookie, setCookie] = createSignal(deserialize(parseCookie(getCookiesString(), name)));
8370

8471
createEffect(p => {
8572
const string = serialize(cookie());
@@ -113,10 +100,10 @@ export function createUserTheme(
113100
name?: string,
114101
options?: UserThemeOptions,
115102
): Signal<Theme | undefined>;
116-
export function createUserTheme(name = "theme", options?: UserThemeOptions): Signal<any> {
117-
const defaultValue = options?.defaultValue;
103+
export function createUserTheme(name = "theme", options: UserThemeOptions = {}): Signal<any> {
104+
const {defaultValue, cookieMaxAge} = options;
118105
return createServerCookie(name, {
119-
...options,
106+
cookieMaxAge,
120107
deserialize: str => (str === "light" || str === "dark" ? str : defaultValue),
121108
serialize: String,
122109
});

packages/cookies/test/index.test.ts

Lines changed: 0 additions & 19 deletions
This file was deleted.

packages/cookies/test/server.test.ts

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)