Skip to content

Commit a7dccf8

Browse files
committed
js/ts toggle
1 parent b2b96a2 commit a7dccf8

File tree

8 files changed

+119
-10
lines changed

8 files changed

+119
-10
lines changed

app.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export default defineConfig(
7676
cursorColor: "var(--twoslash-cursor)",
7777
},
7878
},
79+
languageSwitcher: true,
7980
},
8081
toc: {
8182
minDepth: 2,
@@ -136,6 +137,7 @@ export default defineConfig(
136137

137138
import { readFile } from "node:fs/promises";
138139
import { codeToHtml } from "shiki";
140+
import defaultTheme from "@kobalte/solidbase/default-theme";
139141

140142
function heroCodeSnippet() {
141143
const virtualModuleId = "solid:hero-code-snippet";

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"@solid-primitives/marker": "^0.2.2",
2424
"@solid-primitives/media": "^2.3.3",
2525
"@solid-primitives/platform": "^0.2.1",
26+
"@solid-primitives/storage": "^4.3.3",
2627
"@solidjs/meta": "^0.29.4",
2728
"@solidjs/router": "^0.15.3",
2829
"@solidjs/start": "^1.2.0",

pnpm-lock.yaml

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

src/solidbase-theme/mdx-components.tsx

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
For,
33
Match,
44
type ParentProps,
5+
Show,
56
Switch,
67
children,
78
createMemo,
@@ -11,7 +12,8 @@ import { isServer } from "solid-js/web";
1112

1213
import { A } from "~/ui/i18n-anchor";
1314
import { Callout } from "~/ui/callout";
14-
import { Tabs, TabList, TabPanel, Tab } from "~/ui/tabs";
15+
import { Tabs, TabList, TabPanel, Tab, TSJSToggle } from "~/ui/tabs";
16+
import { usePreferredLanguage } from "@kobalte/solidbase/client";
1517

1618
export { EditPageLink } from "~/ui/edit-page-link";
1719
export { PageIssueLink } from "~/ui/page-issue-link";
@@ -27,10 +29,12 @@ export const DirectiveContainer = (
2729
title?: string;
2830
codeGroup?: string;
2931
tabNames?: string;
32+
withTsJsToggle?: string;
3033
} & ParentProps
3134
) => {
3235
const _children = children(() => props.children).toArray();
3336
const tabNames = createMemo(() => props.tabNames?.split("\0") ?? []);
37+
const [preferredLanguage] = usePreferredLanguage();
3438

3539
return (
3640
<Switch
@@ -47,8 +51,27 @@ export const DirectiveContainer = (
4751
<Tabs>
4852
<TabList>
4953
<For each={tabNames()}>
50-
{(title) => <Tab value={title}>{title}</Tab>}
54+
{(title) => {
55+
const jsTitle = title.replace(/\.tsx?$/, (ext) => {
56+
if (ext === ".tsx") {
57+
return ".jsx";
58+
}
59+
if (ext === ".ts") {
60+
return ".js";
61+
}
62+
return ext;
63+
});
64+
65+
return (
66+
<Tab value={title}>
67+
{preferredLanguage() === "ts" ? title : jsTitle}
68+
</Tab>
69+
);
70+
}}
5171
</For>
72+
<Show when={props.withTsJsToggle}>
73+
<TSJSToggle />
74+
</Show>
5275
</TabList>
5376
<For each={tabNames()}>
5477
{(title, idx) => (

src/styles.css

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,74 @@
104104
left: -1rem;
105105
}
106106
}
107+
108+
.sb-ts-js-toggle,
109+
.expressive-code .sb-ts-js-toggle {
110+
@apply my-auto rounded-md;
111+
appearance: none;
112+
display: flex;
113+
align-items: center;
114+
height: full;
115+
outline-offset: 0;
116+
padding: 0.2rem 0.4rem;
117+
margin-left: auto;
118+
margin-right: 4px;
119+
font-size: 0.875rem;
120+
121+
&:hover {
122+
@apply cursor-pointer bg-slate-200 dark:bg-slate-950/60;
123+
}
124+
125+
&::before,
126+
&::after {
127+
width: 1.5rem;
128+
display: flex;
129+
justify-content: center;
130+
align-items: center;
131+
font-size: 0.9rem;
132+
color: inherit;
133+
}
134+
135+
&::before {
136+
content: "JS";
137+
}
138+
139+
&::after {
140+
content: "TS";
141+
border-left: none;
142+
opacity: 0.4;
143+
}
144+
145+
&:checked {
146+
&::before {
147+
opacity: 0.4;
148+
}
149+
150+
&::after {
151+
opacity: 1;
152+
}
153+
}
154+
}
155+
156+
html[data-preferred-language="ts"] .sb-language-group {
157+
figure:last-of-type {
158+
display: none;
159+
}
160+
161+
pre + pre {
162+
display: none;
163+
}
164+
}
165+
166+
html[data-preferred-language="js"] .sb-language-group {
167+
figure:first-of-type {
168+
display: none;
169+
}
170+
171+
pre:has(+ pre) {
172+
display: none;
173+
}
174+
}
107175
}
108176

109177
h1 {

src/ui/docs-layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export const DocsLayout = (props: DocsLayoutProps) => {
4444
<Show when={titles()?.title} fallback={<Title>SolidDocs</Title>}>
4545
{(title) => <Title>{`${title()} - ${projectTitle()}`}</Title>}
4646
</Show>
47-
<article class="expressive-code-overrides mx-auto w-full max-w-2xl overflow-hidden pb-16">
47+
<article class="mx-auto w-full max-w-2xl overflow-hidden pb-16">
4848
<Show when={titles()?.parent}>
4949
{(t) => (
5050
<span class="my-1 text-sm font-semibold text-blue-700 dark:text-blue-300">

src/ui/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ export const Layout: ParentComponent<{ isError?: boolean }> = (props) => {
162162
when={!useCurrentRouteMetaData().isProjectRoot}
163163
keyed
164164
fallback={
165-
<article class="expressive-code-overrides overflow-y-auto px-2 md:px-10">
165+
<article class="overflow-y-auto px-2 md:px-10">
166166
{props.children}
167167
</article>
168168
}

src/ui/tabs.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function TabList(props: TabListProps) {
2626
<div class="custom-scrollbar flex overflow-x-auto overflow-y-hidden">
2727
<KobalteTabs.List
2828
{...props}
29-
class="z-1 flex w-full border-b border-blue-200 dark:border-slate-800"
29+
class="z-1 flex h-full w-full rounded-t-md bg-slate-200 dark:bg-slate-800/50"
3030
/>
3131
</div>
3232
);
@@ -41,7 +41,7 @@ export function Tab(props: TabProps) {
4141
return (
4242
<KobalteTabs.Trigger
4343
{...props}
44-
class="z-2 aria-selected-before:w-full aria-selected:before:border-blue relative top-0.5 appearance-none bg-none px-[16px] py-[4px] outline-none transition-colors duration-150 aria-selected:h-full aria-selected:bg-slate-200 aria-selected:text-black aria-selected:before:absolute aria-selected:before:inset-0 aria-selected:before:border-t aria-selected:before:border-blue-600 aria-selected:dark:bg-slate-800 aria-selected:dark:text-white aria-selected:before:dark:border-blue-200"
44+
class="z-2 aria-selected-before:w-full relative appearance-none bg-none px-[16px] py-[4px] outline-none transition-colors duration-150 aria-selected:h-full aria-selected:rounded-t-md aria-selected:border-t aria-selected:border-blue-400 aria-selected:bg-white aria-selected:text-black aria-selected:before:absolute aria-selected:before:inset-0 aria-selected:dark:bg-slate-950 aria-selected:dark:text-white"
4545
/>
4646
);
4747
}
@@ -59,3 +59,15 @@ export function TabPanel(props: TabPanelProps) {
5959
/>
6060
);
6161
}
62+
63+
export function TSJSToggle() {
64+
return (
65+
<input
66+
type="checkbox"
67+
checked
68+
title="Toggle language"
69+
aria-label="Toggle TS/JS"
70+
class="sb-ts-js-toggle"
71+
/>
72+
);
73+
}

0 commit comments

Comments
 (0)