Skip to content

Repository files navigation

Geckou UI

Geckou が自社の制作案件で使う UI コンポーネント集。 ロジックをフレームワーク非依存の core に集約し、Vue と React が同じ core を使う構成になっている。

デモサイト(Vue): https://ui.geckou.net/

パッケージ

パッケージ 内容 npm
@geckou/ui-core フレームワーク非依存のロジック(バリデーション・日付処理・状態管理・型・配色) npm
@geckou/ui-vue Vue 3 用コンポーネント。フォーム系 + 記事一覧(10 レイアウト) npm
@geckou/ui-react React 19 / Next.js 用コンポーネント。フォーム系 npm

記事一覧(ArticleList)は Vue のみに収録している。

なぜ core を分けているか

Vue 版と React 版で同じコンポーネントを別々に実装していた時期に、 同じバグが両方に存在し、片方だけ直って、もう片方に残るという事故が起きた。

  • 数値 0 が必須エラーになる(!value 判定)
  • g / y フラグ付き RegExp で lastIndex が変異し判定が不安定になる
  • 日付が toISOString() でタイムゾーン分ずれる

いずれもフレームワークに依存しない純粋なロジックだったため、 @geckou/ui-core に集約してテストを付けた。以後、この種の修正は一度で両方に効く。

インストール

Vue

yarn add @geckou/ui-vue

React(Next.js)

yarn add @geckou/ui-react

ビルド済みの JavaScript と型定義(dist/)を配布しているため、transpilePackages は要らない。 Tailwind CSS は v4 が必須(コンポーネントが v4 の記法を直書きしている)。 詳細は パッケージの README

core を単体で使う

コンポーネントを使わず、バリデーションや日付処理だけ使いたい場合。

yarn add @geckou/ui-core

このパッケージについて

Geckou が自社の制作案件で使うために開発しているコンポーネント集です。どなたでも自由に使えますが、次の点をご理解のうえでご利用ください。

  • バグ報告・要望は歓迎しますが、対応や後方互換は保証しません
  • 自社案件の都合で API や見た目が変わることがあります。バージョンは当面 0.x のままです
  • Pull Request は歓迎しますが、方針に合わない場合はマージしないことがあります。手早く直したいときは fork してお使いください
  • MIT License("AS IS")で提供しています

Design tokens

各コンポーネントは配色・余白・タイポグラフィを CSS カスタムプロパティで受け取ります。 アプリ側のグローバル CSS で定義してください(未定義でも動作しますが、色や余白が効きません)。

以下は geckou.net のブランドカラーに合わせた例で、デモサイトも同じトークンで組んでいます。

:root {
  /* 配色 */
  --primary-color: #1c4ac9;  /* 見出し・リンク・フォーカス */
  --main-color   : #1c4ac9;  /* カテゴリラベルなどの塗り */
  --link-color   : #1c4ac9;
  --checked-color: #1c4ac9;  /* チェックボックス・ラジオの選択色 */
  --sub-color    : #e7ecfb;  /* Rounded カードのタグ */
  --text-color   : #15143a;
  --gray         : #656a7d;  /* 補助テキスト */
  --light-gray   : #e5e5e5;  /* NoImage の背景 */
  --base-color   : #f3f4f8;  /* CardContainer の背景 */
  --white        : #fff;     /* 画像上の文字色などに使用 */
  --black-rgb    : 0, 8, 26; /* 影の生成に使用 */
  --border-color : rgba(21, 20, 58, .12);
  --light-border-color: rgba(21, 20, 58, .08);
  --disable-text-color: #656a7d;

  /* 余白(--bv を基準値にした 5 段階) */
  --bv       : clamp(.375rem, .144rem + .46vw, .5rem);
  --sp       : var(--bv);
  --sp-min   : calc(var(--sp) / 2);
  --sp-small : var(--sp);
  --sp-medium: calc(var(--sp) * 2);
  --sp-large : calc(var(--sp) * 4);
  --sp-larger: calc(var(--sp) * 8);

  /* タイポグラフィ */
  --fs-small: clamp(.75rem, .519rem + .46vw, .875rem);
  --fs-large: clamp(1rem, .769rem + .46vw, 1.125rem);

  /* アイコン・角丸・アニメーション */
  --icon-small        : calc(var(--bv) * 2);
  --icon-medium       : calc(var(--bv) * 3);
  --radius-size       : 4px;
  --radius-small      : 4px;
  --animation-duration: .3s;

  /* 幅(ModalBox / PopupBox の最大幅) */
  --mobile-lower-width : 320px;
  --desktop-lower-width: 992px;
  --contents-max-width : 1440px;
}
変数 用途
--primary-color / --main-color / --link-color ブランドカラー。見出し、リンク、カテゴリラベルの塗り
--sub-color Rounded カードのタグの背景・アイコン
--text-color / --gray / --disable-text-color 本文・補助テキスト・非活性テキスト
--light-gray / --base-color NoImage の背景、CardContainer の背景
--white / --black-rgb 画像上の文字色、影の生成
--border-color / --light-border-color 枠線
--bv--sp-* 余白の基準値と段階
--fs-small / --fs-large 小さめ・大きめの文字サイズ
--icon-small / --icon-medium アイコンのサイズ
--mobile-lower-width / --desktop-lower-width / --contents-max-width ModalBox の最大幅(size prop で切り替え)。Vue 版に限り --contents-max-widthPopupBox の左右位置、--mobile-lower-widthPopupBox の最大幅(この値の 1/2)にも効く(React 版の PopupBox は固定値)

記事一覧コンポーネントはコンテナクエリでレイアウトを切り替えるため、 親要素に container-type: inline-size を指定してください。

フォーム系コンポーネントは、個別に cssStyle prop(InputBoxStyleForEachStatus など)を渡すと 状態ごとの配色を上書きできます。詳細は下の Types を参照してください。

デモサイトは geckou.net のトンマナ(ダークネイビー #15143a 系、ブルー #1c4ac9、Zen Kaku Gothic Antique、 --bv 起点のクランプスケール)に揃えており、OS の配色設定に応じてライト / ダークが切り替わります。

Development

yarn install
yarn dev          # Vue のデモサイトを起動(http://localhost:5555/)
yarn test         # 全パッケージのテスト
yarn type-check   # 全パッケージの型チェック
yarn lint         # ESLint(.ts / .tsx / .vue)
yarn build        # 各パッケージの配布物を生成
yarn build:demo   # デモサイトを demo-dist に出力

デモサイトは production への push で GitHub Pages に自動デプロイされます(.github/workflows/deploy-demo.yml)。

コミットメッセージは commitlint が検証し、規約違反はコミットをブロックします.husky/commit-msg)。派生プロジェクト向けのテンプレート(geckou/project-starter)は 警告のみですが、このリポジトリはリリース単位が git log の可読性に直結するため止めます。

Release

version を上げる PR を production へマージすれば、それだけで npm へ公開されます。 .github/workflows/publish.ymlproduction への push で走り、 packages/*/package.json の version が npm に載っていないパッケージを全部公開します。 手で叩くコマンドはありません。

タグを打って公開する(通常は不要)

上の自動公開とは別に、タグ(<ディレクトリ名>@<バージョン>)を push しての公開も 引き続きできます。使うのは次の 2 つの場合だけで、通常のリリースでこの手順は要りません

  • リリースの区切りを git のタグとして残したいとき
  • 自動公開が失敗した/検査に引っかかったので、打ち直したいとき
# version を上げる PR をマージしたあと(複数まとめて指定できる)
git checkout production && git pull --ff-only
yarn release core react vue

どちらの経路でも公開されるのは「npm に未公開の version」だけです。 公開済みのものは 対象から外れて publish ジョブごと skip されるので、自動公開の後からタグを打っても 二重に公開されることはありません。

自動公開は、公開済みの型定義との差分検査(check-api-diff.mjs)に引っかかると止まります。 互換の追加だと分かっていて通したい場合は yarn release <パッケージ> --force でタグを打ちます (Actions からの手動実行なら force 入力でも同じことができます)。 タグ起動の実行はこの検査を行いません(release.sh が打つ前に済ませているため)。

比較対象は「これから出す version と同じ major.minor の、公開済みで最大の patch」です。 同じ系列に公開済みの版が無ければ(= 新しい major / minor なら)検査しません。

どこからでも実行する

yarn release はこのリポジトリの中でしか動かない(yarn がスクリプトを引けないため)。 一度だけ次を実行すると、geckou-release がどのディレクトリからでも使える。

bash scripts/install-release-command.sh

リポジトリの絶対パスを ~/.config/geckou/release-repos へ登録し、 scripts/geckou-release~/.local/bin へ置くだけ (場所は XDG_CONFIG_HOME / XDG_BIN_HOME に従う)。

geckou-release core vue

パッケージ名から、それを持つリポジトリを引いて scripts/release.sh に渡す。 検査もタグ打ちも release.sh が行うので、動きは yarn release と変わらない。 geckou の他のリポジトリでも同じように実行しておけば、1 つのコマンドで使い分けられる。

yarn release はタグを打つだけで、version は上げません。 production への直接 push は 禁止しているため、version の変更は通常の PR で入れます。

中断する条件:

  • 未コミットの変更がある
  • production 以外のブランチにいる
  • HEAD が origin/production と一致していない — 手元が古いままタグを打つと、GitHub は 「タグが指すコミットのワークフローファイル」で実行するため、古い publish.yml が動いて 意図しない中身が公開されうるため
  • 指定したパッケージのタグが既に存在する(打つ前に全部検査するので、一部だけタグが付くことはありません)

タグは 1 本ずつ push します(まとめて push すると GitHub がワークフローを起動しないことがあるため)。

公開できる範囲

production に入っているコミットだけが公開できます。 タグも手動実行も任意の ref から 起動できるので、そのままだとレビューを通っていないコードを npm へ出せてしまいます (publish の前に yarn install / yarn build が走るため、その ref の任意のコードが 公開権限を持つジョブ内で実行されます)。ワークフローは公開の前に以下を確認します。

  • 起動元のコミットが origin/production に含まれること
  • タグのバージョン部分が対象 package.jsonversion と一致すること
  • パッケージ名がケバブケースであること(パストラバーサル・注入の防止)

認証(Trusted Publishing)

公開の認証は npm の Trusted Publishing(GitHub Actions の OIDC)で行います。 NPM_TOKEN のような長期シークレットは持ちません。実行のたびに短命なトークンが 発行されるので、盗まれて後から悪用される秘密が存在しません。

そのかわり、npm 側でパッケージごとに Trusted Publisher の登録が必要です。 npmjs.com のパッケージ設定(Settings → Trusted publishing)で以下を登録します。

項目
Provider GitHub Actions
Organization / Repository geckou / ui
Workflow filename publish.yml
Environment npm-publish

Workflow filenameファイル名だけ.github/workflows/ のパスは付けません)。 Organization / Repository / Workflow filename は大文字小文字まで一致する必要があります。 新しいパッケージを足したときは、この登録も 1 回だけ行います。

npm 側の紐付けは「リポジトリ + ワークフロー」単位なので、どの ref から起動されたかまでは npm 側では縛れません。そこは上の production 包含チェックと、npm-publish Environment の 「Deployment branches and tags」で担保しています。許可するのは 2 つ:

ref type パターン 用途
Tag *@* タグを打っての公開(yarn release
Branch production production への push による自動公開と workflow_dispatch

どちらか片方に限定すると、もう一方が Environment 側で弾かれます。

移行が動くことを確認できたら、パッケージ設定の 「Require two-factor authentication and disallow tokens」を有効にします。 以後そのパッケージはトークンでは公開できなくなります。順番を逆にすると公開できなくなるので、 必ず 1 回公開が通ってから有効にしてください。

公開されたパッケージには provenance(どのコミット・どのワークフローから公開されたかの証明) が付きます。

License

MIT

About

Vue components used in forms

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages