nest: UIモックアップの作成

とりあえずFluent UI2でモックアップを作っていきたい。以前ビルド不要なPreact + Fluent UIは検討したのでそれを使う。

ベースのHTML
上部のナビゲーション部とアプリケーション部分は事前に分けておくことにした。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Index</title>
<style>
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
margin: 0;
display: grid;
grid-template-rows: auto minmax(0, 1fr);
height: 100vh;
height: 100dvh;
overflow: hidden;
}
header {
position: relative;
height: 56px;
display: flex;
align-items: center;
gap: 12px;
padding: 0 16px;
padding-top: env(safe-area-inset-top);
border-bottom: 1px solid rgba(255,255,255,.08);
z-index: 1;
}
main {
overflow: auto;
padding: 16px;
scrollbar-gutter: stable;
}
</style>
<script type="importmap">
{
"imports": {
"preact": "https://esm.sh/preact@10.27.1",
"preact/": "https://esm.sh/preact@10.27.1/",
"react": "https://esm.sh/preact@10.27.1/compat",
"react/": "https://esm.sh/preact@10.27.1/compat/",
"react-dom": "https://esm.sh/preact@10.27.1/compat",
"fluentui": "https://esm.sh/@fluentui/react-components@9.69.0?external=react,react-dom"
}
}
</script>
</head>
<body>
<header id="fnest-header"></header>
<main id="fnest-main"></main>
<script type="module">
import { h, render } from "preact";
import { FluentProvider, Button, webLightTheme } from "fluentui";
import { test_component } from "./testcomponent.mjs";
let app = h(FluentProvider, {theme: webLightTheme}, [h(test_component, null, null)]);
let appEl = document.getElementById("fnest-main");
render(app, appEl);
</script>
</body>
JSXは使わないので、コンポーネント名を大文字で始める必要はない。

コンポーネントの.mjs
外部ファイルに分けるためにはhttpサーバーが必要。。(ローカルファイルだとCORSできないので)
import { Button } from "fluentui";
import { h } from "preact";
export function test_component(props){
return h(Button, null, "Hello!");
}

作らないといけないのは?
そもそもどういう画面が必要なのかを先に考えないといけない。
ナビゲーションバー
[:::] LOGO [App] [App] [App] [c][c][c] [User]
起動中のアプリを切り替えられる奴。 [c]
は接続セッション。WebRTC接続やGitHub等。LOGOはスピードダイアルを表示。 [:::]
はお気に入り..?
スピードダイアル
登録した外部アプリを一覧表示/検索するやつ。Okta等のトップページと同じやつ。並び換えとかセクション区切り機能が必要か。。
接続セッションアイコン
接続セッションの情報を表示するやつ。API残量とか出せると良いかなと思ったけど、無駄に更新しても負荷上がるだけなので無くて良いか。Fluentに円形プログレスバー無いっぽいし。
ユーザーアイコン
非表示にした接続セッションアイコンや設定などがココ。

アイコンコンポーネント
色替えに対応したsimple iconsコンポーネントを手作りする。そのうちダークテーマ対応したいので。。
import { h } from "preact";
export function sicon({
size = 24,
color = "#b00",
icon,
...rest
} = {}){
const uri =
`https://cdn.jsdelivr.net/npm/simple-icons@v15/icons/${icon}.svg`;
const styles = {
width: size,
height: size,
display: "inline-block",
backgroundColor: color,
maskImage: `url("${uri}")`,
maskRepeat: "no-repeat",
maskPosition: "center",
maskSize: "contain"
};
// FIXME: Fill ARIA attributes
return h("span", {"aria-hidden": true, style: styles});
}
あんまり効率良くないけど、まぁ大量に表示するわけじゃないし別に良いんじゃないか説。
ARIA属性はFluent UIのiconコンポーネントに合わせるのが良いかな。

データベースエディタ
GitDBのブラウザとエディタをコンポーネントにしたい。 ...といってもこれは流石に1つのコンポーネントで何でもかんでもカバーするのは無理だから、どういう設計が良いのかをじっくり考えたい。
SQLite3のWeb版は既に存在する https://www.npmjs.com/package/@sqlite.org/sqlite-wasm ので、検索等はindexerがたまに走ってSQLite3 DBに保存 + indexerがインデックスしていない部分はローカルで追加みたいな感じで良いかな。