Skip to content

Commit 6ee79f2

Browse files
committed
version selector
1 parent e096110 commit 6ee79f2

8 files changed

Lines changed: 265 additions & 16 deletions

File tree

osmium/src/ui/layout/main-header.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ export function MainHeader(_props: MainHeaderProps) {
4949

5050
const project = useProject();
5151

52-
console.log(project());
53-
5452
const { setNavOpen } = useOsmiumThemeState();
5553

5654
if (!isServer) {
@@ -78,7 +76,7 @@ export function MainHeader(_props: MainHeaderProps) {
7876
}}
7977
>
8078
<div class="max-w-8xl mx-auto grid w-full grid-cols-2 items-center px-4 py-2 lg:grid-cols-[1fr_2fr_1fr]">
81-
<div class="flex justify-start gap-2">
79+
<div class="flex items-center justify-start gap-2">
8280
<div class="flex lg:hidden">
8381
<MobileNavigation />
8482
</div>

osmium/src/ui/layout/main-navigation.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
} from "@kobalte/solidbase/client";
1212
import { Collapsible } from "@kobalte/core/collapsible";
1313
import { Tabs } from "@kobalte/core/tabs";
14+
import VersionSelector from "./version-selector";
1415

1516
interface MainNavigationProps {}
1617

@@ -111,6 +112,7 @@ export function MainNavigation(_props: MainNavigationProps) {
111112

112113
return (
113114
<nav class="custom-scrollbar h-full overflow-y-auto pb-20 md:h-[calc(100vh-7rem)]">
115+
<VersionSelector />
114116
<Tabs value={selectedTab()}>
115117
<Tabs.List class="sticky top-0 z-10 grid w-full grid-cols-2 md:bg-slate-50 md:dark:bg-slate-900">
116118
<Tabs.Trigger
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { Popover } from "@kobalte/core/popover";
2+
import { createMemo, createSignal, For, Show } from "solid-js";
3+
import { useRouteConfig } from "../../utils";
4+
import { useSolidBaseRoute } from "@kobalte/solidbase/client";
5+
import {
6+
getSolidBaseRouteFallbackOptions,
7+
SolidBaseRouteOption,
8+
} from "@kobalte/solidbase/config/route";
9+
import { Icon } from "solid-heroicons";
10+
import { chevronUpDown, tag } from "solid-heroicons/solid";
11+
12+
export default function VersionSelector() {
13+
const [open, setOpen] = createSignal(false);
14+
15+
const config = useRouteConfig();
16+
17+
const current = useSolidBaseRoute();
18+
const options = createMemo(() =>
19+
getSolidBaseRouteFallbackOptions(config().routes, "version", current())
20+
);
21+
const currentOption = createMemo(() =>
22+
options().find((option) => option.name === current().version)
23+
);
24+
25+
const getOptionLabel = (option: SolidBaseRouteOption) => {
26+
return typeof option.meta.label === "string"
27+
? option.meta.label
28+
: option.name;
29+
};
30+
31+
return (
32+
<Show when={options().length > 1 && currentOption()}>
33+
{(current) => (
34+
<Popover
35+
open={open()}
36+
onOpenChange={setOpen}
37+
gutter={4}
38+
sameWidth
39+
placement="bottom-start"
40+
>
41+
<div class="mx-1">
42+
<Popover.Trigger
43+
class="flex h-10 w-full items-center justify-between rounded-lg text-left shadow-md ring-1 shadow-black/5 ring-black/90 ring-inset dark:ring-white/10"
44+
aria-label="Change version"
45+
disabled={options().length <= 1}
46+
>
47+
<span class="prose prose-slate flex items-center truncate pl-2 text-lg text-slate-700 dark:text-slate-300">
48+
<Icon
49+
class="mr-2 w-5 fill-slate-700 pl-1 dark:fill-slate-200"
50+
path={tag}
51+
/>
52+
{getOptionLabel(current())}
53+
</span>
54+
55+
<Show when={options().length > 1}>
56+
<Icon
57+
class="mr-2 w-6 fill-slate-700 pl-1 dark:fill-slate-200"
58+
path={chevronUpDown}
59+
/>
60+
</Show>
61+
</Popover.Trigger>
62+
</div>
63+
<Popover.Portal>
64+
<Popover.Content class="z-50 space-y-1 rounded-xl bg-white p-2 text-sm shadow-md ring-1 shadow-black/5 ring-black/5 dark:bg-slate-800 dark:ring-white/5">
65+
<For each={options()}>
66+
{(option) => {
67+
const outbound = () => !!option.href;
68+
69+
return (
70+
<a
71+
class="group flex cursor-pointer items-center rounded-[0.625rem] p-1 select-none hover:bg-slate-200 focus:bg-slate-200 focus:font-medium focus:outline-hidden hover:dark:bg-slate-600 focus:dark:bg-slate-700"
72+
target={outbound() ? "_blank" : undefined}
73+
rel={outbound() ? "noopener noreferrer" : undefined}
74+
aria-current={option === currentOption() || undefined}
75+
href={option.href ?? option.path}
76+
onMouseEnter={(e) => e.currentTarget.focus()}
77+
onClick={() => setOpen(false)}
78+
>
79+
{getOptionLabel(option)}
80+
</a>
81+
);
82+
}}
83+
</For>
84+
</Popover.Content>
85+
</Popover.Portal>
86+
</Popover>
87+
)}
88+
</Show>
89+
);
90+
}

pnpm-lock.yaml

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ packages:
88
- "osmium"
99

1010
catalog:
11-
"@kobalte/solidbase": ^0.6.1
11+
"@kobalte/solidbase": ^0.6.3

src/routes/v2/(0)index.mdx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
title: Overview
3+
titleTemplate: ":title"
4+
mainNavExclude: true
5+
use_cases: >-
6+
getting started, learning solid, understanding framework, first project,
7+
introduction
8+
tags:
9+
- introduction
10+
- overview
11+
- getting-started
12+
- basics
13+
- framework
14+
version: "2.0"
15+
description: >-
16+
Solid is a reactive JavaScript framework for building fast, efficient UIs.
17+
Learn about fine-grained reactivity and modern web development.
18+
---
19+
20+
Solid v2 is currently in beta. Expect more docs to appear here soon!
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
title: createSignal
3+
category: Basic Reactivity
4+
use_cases: >-
5+
state management, reactive values, component state, form inputs, counters,
6+
toggles, any reactive data
7+
tags:
8+
- signals
9+
- state
10+
- reactivity
11+
- core
12+
- primitives
13+
version: "2.0"
14+
description: >-
15+
Create reactive state with createSignal, Solid's fundamental primitive. Track
16+
values that change over time and automatically update your UI when they do.
17+
---
18+
19+
V2 TODO!
20+
21+
22+
Creates a reactive state primitive consisting of a getter (accessor) and a setter function that forms the foundation of Solid's reactivity system.
23+
Signals use a pull-based reactivity model where tracking subscriptions (reads) is lightweight, while updates (writes) trigger dependency tracking and effect re-execution, making them optimized for frequent reads and infrequent writes.
24+
25+
## Import
26+
27+
```typescript
28+
import { createSignal } from "solid-js";
29+
```
30+
31+
## Type signature
32+
33+
```typescript
34+
function createSignal<T>(): Signal<T | undefined>;
35+
function createSignal<T>(value: T, options?: SignalOptions<T>): Signal<T>;
36+
37+
type Signal<T> = [get: Accessor<T>, set: Setter<T>];
38+
39+
type Accessor<T> = () => T;
40+
41+
type Setter<T> = {
42+
<U extends T>(value: Exclude<U, Function> | ((prev: T) => U)): U;
43+
<U extends T>(value: (prev: T) => U): U;
44+
<U extends T>(value: Exclude<U, Function>): U;
45+
<U extends T>(value: Exclude<U, Function> | ((prev: T) => U)): U;
46+
};
47+
48+
interface SignalOptions<T> {
49+
name?: string;
50+
equals?: false | ((prev: T, next: T) => boolean);
51+
internal?: boolean;
52+
}
53+
```
54+
55+
## Parameters
56+
57+
### `value`
58+
59+
- **Type:** `T`
60+
- **Default:** `undefined`
61+
62+
The initial value for the signal.
63+
If no initial value is provided, the signal's type is automatically extended with `undefined`.
64+
65+
### `options`
66+
67+
- **Type:** `SignalOptions<T>`
68+
- **Default:** `undefined`
69+
70+
Configuration object for the signal.
71+
72+
#### `name`
73+
74+
- **Type:** `string`
75+
- **Default:** `undefined`
76+
77+
A name for the signal used by debugging tools like [Solid devtools](https://github.com/thetarnav/solid-devtools).
78+
It works only in development mode and is removed from the production bundle.
79+
80+
#### `equals`
81+
82+
- **Type:** `false | ((prev: T, next: T) => boolean)`
83+
- **Default:** `false`
84+
85+
A custom comparison function to determine when the signal should update.
86+
By default, signals use reference equality (`===`) to compare previous and next values.
87+
When set to `false`, the signal will always update regardless of value equality, which is useful for creating signals that trigger manual updates in the reactive system.
88+
89+
When providing a custom function, it should be pure and return `true` if the values are equal (no update needed) or `false` if they differ (trigger update).
90+
Impure functions can create unexpected side effects and performance issues.
91+
92+
#### `internal`
93+
94+
- **Type:** `boolean`
95+
- **Default:** `false`
96+
97+
Marks the signal as internal, preventing it from appearing in development tools.
98+
This is primarily used by Solid's internal systems.
99+
100+
## Return value
101+
102+
- **Type:** `Signal<T>`
103+
104+
Returns a tuple `[getter, setter]` where:
105+
106+
- **getter**: An accessor function that returns the current value and tracks dependencies when called within a reactive context
107+
- **setter**: A function that updates the signal's value and notifies all dependent computations
108+
109+
## Examples
110+
111+
### Basic usage
112+
113+
```tsx
114+
import { createSignal } from "solid-js";
115+
116+
function Counter() {
117+
const [count, setCount] = createSignal(0);
118+
119+
return (
120+
<div>
121+
<button onClick={() => setCount(count() + 1)}>+</button>
122+
<span>{count()}</span>
123+
</div>
124+
);
125+
}
126+
```

vite.config.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default defineConfig({
2222
siteUrl: "https://docs.solidjs.com",
2323
editPath: "https://github.com/solidjs/solid-docs/edit/main/:path",
2424
routes: {
25-
path: "/{version}/{project}",
25+
path: "/{project}/{version}",
2626
project: {
2727
default: "solid",
2828
values: {
@@ -36,13 +36,13 @@ export default defineConfig({
3636
default: "latest",
3737
values: {
3838
latest: { path: "", label: "Latest" },
39-
v1: { path: "v1", label: "v1" },
39+
v2: { path: "v2", label: "v2" },
4040
},
4141
},
4242
include: [
4343
{
4444
project: "solid",
45-
version: ["latest", "v1"],
45+
version: ["latest", "v2"],
4646
},
4747
{
4848
project: ["router", "start", "meta"],
@@ -72,6 +72,19 @@ export default defineConfig({
7272
sidebar: createFilesystemSidebar("./src/routes/solid-meta"),
7373
},
7474
},
75+
{
76+
project: "solid",
77+
version: "v2",
78+
themeConfig: {
79+
sidebar: createFilesystemSidebar("./src/routes/v2", {
80+
filter: (item) => {
81+
return !["solid-router", "solid-start", "solid-meta"].some(
82+
(project) => item.filePath.includes(`/src/routes/${project}`)
83+
);
84+
},
85+
}),
86+
},
87+
},
7588
],
7689
themeConfig: {
7790
sidebar: createFilesystemSidebar("./src/routes/", {

0 commit comments

Comments
 (0)