Open6

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

okuokuokuoku

ベースの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は使わないので、コンポーネント名を大文字で始める必要はない。

okuokuokuoku

コンポーネントの.mjs

外部ファイルに分けるためにはhttpサーバーが必要。。(ローカルファイルだとCORSできないので)

import { Button } from "fluentui";
import { h } from "preact";

export function test_component(props){
    return h(Button, null, "Hello!");
}
okuokuokuoku

作らないといけないのは?

そもそもどういう画面が必要なのかを先に考えないといけない。

ナビゲーションバー

[:::] LOGO [App] [App] [App]         [c][c][c] [User]

起動中のアプリを切り替えられる奴。 [c] は接続セッション。WebRTC接続やGitHub等。LOGOはスピードダイアルを表示。 [:::] はお気に入り..?

スピードダイアル

登録した外部アプリを一覧表示/検索するやつ。Okta等のトップページと同じやつ。並び換えとかセクション区切り機能が必要か。。

接続セッションアイコン

接続セッションの情報を表示するやつ。API残量とか出せると良いかなと思ったけど、無駄に更新しても負荷上がるだけなので無くて良いか。Fluentに円形プログレスバー無いっぽいし。

ユーザーアイコン

非表示にした接続セッションアイコンや設定などがココ。

okuokuokuoku

アイコンコンポーネント

色替えに対応したsimple iconsコンポーネントを手作りする。そのうちダークテーマ対応したいので。。

https://github.com/simple-icons/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コンポーネントに合わせるのが良いかな。

okuokuokuoku

データベースエディタ

GitDBのブラウザとエディタをコンポーネントにしたい。 ...といってもこれは流石に1つのコンポーネントで何でもかんでもカバーするのは無理だから、どういう設計が良いのかをじっくり考えたい。

SQLite3のWeb版は既に存在する https://www.npmjs.com/package/@sqlite.org/sqlite-wasm ので、検索等はindexerがたまに走ってSQLite3 DBに保存 + indexerがインデックスしていない部分はローカルで追加みたいな感じで良いかな。