Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/[lang]/[pageId]/pageContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export function PageContent(props: PageContentProps) {
<StyledMarkdown
content={section.rawContent.replace(
/-repl\s*\n/,
`-repl:${section.id}`
`-repl:${section.id}\n`
)}
/>
</div>
Expand Down
8 changes: 7 additions & 1 deletion app/[lang]/[pageId]/styledSyntaxHighlighter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
tomorrowNight,
} from "react-syntax-highlighter/dist/esm/styles/hljs";
import { lazy, Suspense, useEffect, useState } from "react";
import clsx from "clsx";

// SyntaxHighlighterはファイルサイズがでかいので & HydrationErrorを起こすので、SSRを無効化する
const SyntaxHighlighter = lazy(() => {
Expand Down Expand Up @@ -136,7 +137,12 @@ export function StyledSyntaxHighlighter(props: {
}
function FallbackPre({ children }: { children: string }) {
return (
<pre className="border-2 border-current/20 mx-2 my-2 rounded-box p-4! bg-base-300! text-base-content!">
<pre
className={clsx(
"border-2 border-current/20 mx-2 my-2 rounded-box p-4! bg-base-300! text-base-content!",
"w-full overflow-auto"
)}
>
{children}
</pre>
);
Expand Down
7 changes: 7 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ mycdark:
@apply border-primary!;
}

.rounded-box-modal {
@apply rounded-box;
@variant max-md {
--radius-box: 0px !important;
}
}

/* CDNからダウンロードするURLを指定したらなんかエラー出るので、npmでインストールしてlayout.tsxでimportすることにした */
@theme {
/*
Expand Down
15 changes: 12 additions & 3 deletions app/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export function Sidebar({ pagesList }: { pagesList: LanguageEntry[] }) {
}, [currentLangIndex]);

return (
<div className="bg-base-200 h-full w-80 overflow-y-auto">
<div className="bg-base-200 h-full w-80 flex flex-col">
<h2 className="hidden lg:flex flex-row items-center p-4 gap-2">
{/* サイドバーが常時表示されているlg以上の場合のみ */}
<Link href="/" className="flex-1 flex items-center">
Expand All @@ -136,7 +136,7 @@ export function Sidebar({ pagesList }: { pagesList: LanguageEntry[] }) {
<label
htmlFor="drawer-toggle"
aria-label="open sidebar"
className="btn btn-ghost"
className="btn btn-ghost w-full justify-start"
>
<svg
className="w-8 h-8"
Expand All @@ -156,7 +156,16 @@ export function Sidebar({ pagesList }: { pagesList: LanguageEntry[] }) {
</label>
</span>

<ul className="menu w-full">
<ul
className="menu w-full h-max flex-nowrap grow-1 overflow-y-auto overflow-x-clip"
style={{
scrollbarGutter: "stable",
// DaisyUIはスクロールバーカラーを変更しているが、sidebarを開いた際にはさらに暗い色に変更してしまう
// ここではsidebarの状態によらずDaisyUIがデフォルトで設定しているスクロールバーカラーを復元
scrollbarColor:
"color-mix(in oklch, currentColor 35%, transparent) transparent",
}}
>
{pagesList.map((group, i) => (
<li key={group.id}>
<details
Expand Down
56 changes: 41 additions & 15 deletions app/terminal/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useChangeTheme } from "@/themeToggle";
import { useEmbedContext } from "./embedContext";
import { langConstants } from "./runtime";
import { MarkdownLang } from "@/[lang]/[pageId]/styledSyntaxHighlighter";
import { MinMaxButton, Modal } from "./modal";

// https://github.com/securingsincity/react-ace/issues/27 により普通のimportができない
const AceEditor = lazy(async () => {
Expand Down Expand Up @@ -104,18 +105,38 @@ export function EditorComponent(props: EditorProps) {
}, [files, props.filename, props.initContent, writeFile]);

const [fontSize, setFontSize] = useState<number>();
const [windowHeight, setWindowHeight] = useState<number>(1000);
const [initAce, setInitAce] = useState(false);
useEffect(() => {
setFontSize(
parseFloat(getComputedStyle(document.documentElement).fontSize)
); // 1rem
setInitAce(true);
const update = () => {
setFontSize(
parseFloat(getComputedStyle(document.documentElement).fontSize)
); // 1rem
setWindowHeight(window.innerHeight);
setInitAce(true);
};
update();
window.addEventListener("resize", update);
return () => window.removeEventListener("resize", update);
}, []);
// 最小8行 or 初期内容+1行
const editorHeight = Math.max(props.initContent.split("\n").length + 1, 8);
// 現在の内容の行数、最小8行、最大50vh
const editorHeight = Math.max(
Math.min(
code.split("\n").length,
Math.floor((windowHeight * 0.5) / ((fontSize || 16) + 1))
),
8
);

const [isModal, setIsModal] = useState(false);

return (
<div className="border border-accent border-2 shadow-md m-2 rounded-box overflow-hidden">
<Modal
id={`edit-${props.filename}`}
className={clsx("overflow-hidden", "flex flex-col")}
open={isModal}
setOpen={setIsModal}
>
<div className="flex flex-row items-center bg-base-200">
<span className="mt-2 mb-1 ml-3 mr-2 text-sm text-left">
<span>
Expand All @@ -127,9 +148,7 @@ export function EditorComponent(props: EditorProps) {
</span>
<button
className={clsx(
"btn btn-xs btn-soft btn-warning mt-1 mb-1",
// btn-warning は文字色を変えるがsvgの色は変えてくれないので、 stroke-warning を追加指定している
"stroke-warning hover:stroke-warning-content active:stroke-warning-content",
"btn btn-sm btn-soft btn-warning my-1",
// codeの内容が変更された場合のみ表示する
(props.readonly || code == props.initContent) && "invisible"
)}
Expand All @@ -140,6 +159,7 @@ export function EditorComponent(props: EditorProps) {
className="w-3 h-3"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<g id="Edit / Undo">
Expand All @@ -153,8 +173,10 @@ export function EditorComponent(props: EditorProps) {
/>
</g>
</svg>
元の内容に戻す
<span className="hidden md:inline">元の内容に戻す</span>
</button>
<div className="flex-1" />
<MinMaxButton open={isModal} id={`edit-${props.filename}`} />
</div>
{fontSize !== undefined && initAce ? (
<Suspense
Expand All @@ -168,7 +190,7 @@ export function EditorComponent(props: EditorProps) {
theme={theme}
tabSize={langConstants(props.language || "text").tabSize}
width="100%"
height={editorHeight * (fontSize + 1) + "px"}
height={isModal ? "100%" : editorHeight * (fontSize + 1) + "px"}
className="font-mono!" // Aceのデフォルトフォントを上書き
readOnly={props.readonly}
fontSize={fontSize}
Expand All @@ -182,26 +204,30 @@ export function EditorComponent(props: EditorProps) {
/>
</Suspense>
) : (
<FallbackPre editorHeight={editorHeight}>{code}</FallbackPre>
<FallbackPre isModal={isModal} editorHeight={editorHeight}>
{code}
</FallbackPre>
)}
</div>
</Modal>
);
}

function FallbackPre({
children,
editorHeight,
isModal,
}: {
children: string;
editorHeight: number;
isModal?: boolean;
}) {
// AceEditorはなぜかline-heightが小さい
// fontSize + 1px になるっぽい?
return (
<pre
className="font-mono overflow-auto bg-base-300 px-2 cursor-wait"
style={{
height: `calc((1em + 1px) * ${editorHeight})`,
height: isModal ? "100%" : `calc((1em + 1px) * ${editorHeight})`,
lineHeight: "calc(1em + 1px)",
}}
>
Expand Down
Loading