Geckou が自社の制作案件で使う UI コンポーネント集。 ロジックをフレームワーク非依存の core に集約し、Vue と React が同じ core を使う構成になっている。
デモサイト(Vue): https://ui.geckou.net/
| パッケージ | 内容 | npm |
|---|---|---|
@geckou/ui-core |
フレームワーク非依存のロジック(バリデーション・日付処理・状態管理・型・配色) | |
@geckou/ui-vue |
Vue 3 用コンポーネント。フォーム系 + 記事一覧(10 レイアウト) | |
@geckou/ui-react |
React 19 / Next.js 用コンポーネント。フォーム系 |
記事一覧(ArticleList)は Vue のみに収録している。
Vue 版と React 版で同じコンポーネントを別々に実装していた時期に、 同じバグが両方に存在し、片方だけ直って、もう片方に残るという事故が起きた。
- 数値
0が必須エラーになる(!value判定) g/yフラグ付き RegExp でlastIndexが変異し判定が不安定になる- 日付が
toISOString()でタイムゾーン分ずれる
いずれもフレームワークに依存しない純粋なロジックだったため、
@geckou/ui-core に集約してテストを付けた。以後、この種の修正は一度で両方に効く。
yarn add @geckou/ui-vueyarn add @geckou/ui-reactビルド済みの JavaScript と型定義(dist/)を配布しているため、transpilePackages は要らない。
Tailwind CSS は v4 が必須(コンポーネントが v4 の記法を直書きしている)。
詳細は パッケージの README。
コンポーネントを使わず、バリデーションや日付処理だけ使いたい場合。
yarn add @geckou/ui-coreGeckou が自社の制作案件で使うために開発しているコンポーネント集です。どなたでも自由に使えますが、次の点をご理解のうえでご利用ください。
- バグ報告・要望は歓迎しますが、対応や後方互換は保証しません
- 自社案件の都合で API や見た目が変わることがあります。バージョンは当面
0.xのままです - Pull Request は歓迎しますが、方針に合わない場合はマージしないことがあります。手早く直したいときは fork してお使いください
- MIT License("AS IS")で提供しています
各コンポーネントは配色・余白・タイポグラフィを 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-width が PopupBox の左右位置、--mobile-lower-width が PopupBox の最大幅(この値の 1/2)にも効く(React 版の PopupBox は固定値) |
記事一覧コンポーネントはコンテナクエリでレイアウトを切り替えるため、
親要素に container-type: inline-size を指定してください。
フォーム系コンポーネントは、個別に cssStyle prop(InputBoxStyleForEachStatus など)を渡すと
状態ごとの配色を上書きできます。詳細は下の Types を参照してください。
デモサイトは geckou.net のトンマナ(ダークネイビー #15143a 系、ブルー #1c4ac9、Zen Kaku Gothic Antique、
--bv 起点のクランプスケール)に揃えており、OS の配色設定に応じてライト / ダークが切り替わります。
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 の可読性に直結するため止めます。
version を上げる PR を production へマージすれば、それだけで npm へ公開されます。
.github/workflows/publish.yml が production への 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.jsonのversionと一致すること - パッケージ名がケバブケースであること(パストラバーサル・注入の防止)
公開の認証は 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(どのコミット・どのワークフローから公開されたかの証明) が付きます。