y-icons 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 hamayou-61
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # y-icons
2
+
3
+ MDI に不足するアイコンを **簡単に作って・簡単に使う** ための独自アイコンパッケージ。
4
+
5
+ **1 つの真実の源(`icons/` 配下の SVG)** から、Vue/Vuetify・Web/ERB・Figma の **3 経路すべて** を
6
+ 自動生成・配布する。
7
+
8
+ ```
9
+ icons/<name>.svg ← 真実の源(SoT)。1 枚置くだけ
10
+ │ npm run build
11
+ ├─ コード(Vuetify) … y: アイコンセット(<v-icon icon="y:name"> など全 icon プロパティ)
12
+ ├─ コード(Web/ERB) … アイコンフォント(<i class="yicon yicon-name">)
13
+ ├─ Figma … Storybook からコピー&ペースト(グリフ or SVG)
14
+ └─ 安定コードポイント(codepoints.json・追記専用)
15
+ ```
16
+
17
+ ---
18
+
19
+ ## クイックスタート
20
+
21
+ ```bash
22
+ npm install
23
+ npm run build # build:set + build:font + tsc
24
+
25
+ npm run storybook # ギャラリー・候補・利用例・フォントDL を閲覧
26
+ ```
27
+
28
+ ---
29
+
30
+ ## アイコンを追加する
31
+
32
+ 1. **作る**:`icons/<name>.svg` を置く。
33
+ - デザイナーは Figma で作図 → SVG 書き出し(下記「設計仕様」準拠)。
34
+ - 開発者は **`/create-icon <要望>`** スキルで AI 叩き台を 10 案生成 → Storybook `icons/Candidates` で
35
+ MDI と見比べて選定 → `icons/` へ昇格。
36
+ 2. **ビルド**:`npm run build`(`build:set` が仕様+バウンディングボックスを検証)。
37
+ 3. **配布**:CI がフォント/npm を生成・配布(後述)。
38
+
39
+ ---
40
+
41
+ ## 使い方(3 経路)
42
+
43
+ ### 1. Vue / Vuetify
44
+
45
+ ```ts
46
+ import { vuetifyIcons } from 'y-icons/vuetify'
47
+ createVuetify({ icons: vuetifyIcons })
48
+ ```
49
+
50
+ ```vue
51
+ <v-icon icon="y:inventory-transfer" />
52
+ <!-- v-icon 以外の全 icon プロパティでも同じ書き方で動く -->
53
+ <v-text-field prepend-icon="y:inventory-transfer" />
54
+ <v-btn :icon="'y:inventory-transfer'" />
55
+ ```
56
+
57
+ FW 非依存に使う場合:`import { yIconPaths } from 'y-icons'` / 個別 SVG は `y-icons/svg/<name>.svg`。
58
+
59
+ ### 2. Web の生 class / Rails ERB(Vuetify を介さない場所)
60
+
61
+ `dist/font/y-icons.css` を読み込み:
62
+
63
+ ```html
64
+ <i class="yicon yicon-inventory-transfer"></i> <!-- クラス -->
65
+ <span class="yicon">inventory-transfer</span> <!-- 名前リガチャ(ブラウザのみ) -->
66
+ ```
67
+
68
+ ### 3. Figma(Storybook からコピー&ペースト)
69
+
70
+ Storybook `icons/CustomIcons` の各アイコンに 2 つのコピーボタン。MDI(pictogrammers) と同じ運用:
71
+
72
+ | ボタン | コピー内容 | Figma 結果 | フォント要否 |
73
+ |---|---|---|---|
74
+ | **グリフをコピー** | PUA 文字+`font-family: y-icons` | テキスト(y-icons フォント)= MDI の Copy Glyph と同じ | **要インストール** |
75
+ | **SVGをコピー** | `<svg fill="currentColor">` | ベクター図形 | 不要 |
76
+
77
+ フォントは `icons/DownloadFont` ストーリーからダウンロードしてインストール。
78
+ 詳細なデザイナー手順は [`docs/figma-guide.md`](docs/figma-guide.md)。
79
+
80
+ > Figma のリガチャ(名前を打つと変換)は信頼性が低いため使わない。リガチャは Web/ERB(ブラウザ)専用。
81
+
82
+ ---
83
+
84
+ ## Storybook(運用の入口)
85
+
86
+ | ストーリー | 役割 |
87
+ |---|---|
88
+ | `icons/CustomIcons` | 一覧 + グリフ/SVG コピー(Figma 貼付) |
89
+ | `icons/Candidates` | 候補プレビュー + MDI 参照(採点) |
90
+ | `icons/VuetifyUsage` | `y:` が全 Vuetify icon プロパティで効く実証 |
91
+ | `icons/DownloadFont` | フォント一式(ttf/woff/css/cheatsheet)を DL |
92
+
93
+ ---
94
+
95
+ ## 設計仕様(Material Design アイコン規格準拠:24dp グリッド/キーライン)
96
+
97
+ | 項目 | 値 |
98
+ |---|---|
99
+ | グリッド | 24×24 dp(viewBox `0 0 24 24` 固定) |
100
+ | ライブエリア / 余白 | 中身 ~20×20dp(座標 2〜22)、外周 2dp padding |
101
+ | ストローク幅 | 2dp(2dp 以下は角を丸めない) |
102
+ | 角丸 | 既定 2dp |
103
+ | キーラインシェイプ | 円⌀20 / 正方形18 / 縦長16×20 / 横長20×16 |
104
+
105
+ 形式:**単一 `<path>`**(`<g>`・`transform`・複数 path 不可)/**`fill` を書かない**(`currentColor`)/
106
+ `stroke` 不使用(中空は外形+内形の逆回りサブパス、帯幅 2dp 一貫)/座標 0.5dp 刻み。
107
+ `npm run build:set` が SVGO 正規化+仕様+bbox を検証(違反で停止)。
108
+
109
+ ---
110
+
111
+ ## 成果物とリポ構成
112
+
113
+ | パス | 内容 |
114
+ |---|---|
115
+ | `icons/*.svg` | **SoT**(デザイナーが置く) |
116
+ | `candidates/*.svg` | 採用前の候補(`/create-icon` が書き込む下書き) |
117
+ | `src/registry.generated.ts` | 自動生成(name→d) |
118
+ | `src/vuetify.ts` | Vuetify アダプタ(`vuetifyIcons` / `yIconSet`) |
119
+ | `scripts/build-set.mjs` / `build-font.mjs` | 生成(registry/svg ・ フォント) |
120
+ | `dist/` | 配布物(gitignore。CI/publish 時に生成) |
121
+ | `codepoints.json` | 名前→コードポイントの固定割当(**コミット対象・追記専用**) |
122
+
123
+ `package.json` の exports:`.`(FW 非依存)/`./vuetify`/`./font/*`/`./svg/*`。
124
+
125
+ ---
126
+
127
+ ## CI
128
+
129
+ - **push / PR**(`.github/workflows/ci.yml`):`npm run build` + **生成物ドリフト検査** +
130
+ **アイコンフォントを成果物としてアップロード**(各実行からダウンロード可)。
131
+ - **Release 公開**(`.github/workflows/release.yml`):`y-icons` を publish + フォントを Releases に添付。
132
+
133
+ 稼働前 TODO:registry 確定(GitHub Packages 等)、`package.json` の `private` 解除+`publishConfig` 設定。
@@ -0,0 +1,4 @@
1
+ {
2
+ "sample": 61697,
3
+ "inventory-transfer": 61698
4
+ }
@@ -0,0 +1,23 @@
1
+ @font-face {
2
+ font-family: "y-icons";
3
+ src: url("./y-icons.woff2") format("woff2"),
4
+ url("./y-icons.woff") format("woff"),
5
+ url("./y-icons.ttf") format("truetype");
6
+ font-weight: normal;
7
+ font-style: normal;
8
+ }
9
+ .yicon {
10
+ font-family: "y-icons";
11
+ font-style: normal;
12
+ font-weight: normal;
13
+ line-height: 1;
14
+ text-transform: none;
15
+ letter-spacing: normal;
16
+ /* リガチャを有効化(名前を打つとアイコンに変わる) */
17
+ font-feature-settings: "liga" 1;
18
+ -webkit-font-feature-settings: "liga" 1;
19
+ text-rendering: optimizeLegibility;
20
+ -webkit-font-smoothing: antialiased;
21
+ }
22
+ .yicon-inventory-transfer:before { content: "\f102"; }
23
+ .yicon-sample:before { content: "\f101"; }
@@ -0,0 +1,35 @@
1
+ <!doctype html>
2
+ <html lang="ja">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>y-icons cheatsheet</title>
7
+ <link rel="stylesheet" href="./y-icons.css" />
8
+ <style>
9
+ body { font-family: system-ui, sans-serif; margin: 2rem; color: #222; }
10
+ h1 { font-size: 1.25rem; }
11
+ h1 small { color: #999; font-weight: normal; }
12
+ p { color: #666; }
13
+ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 1rem; }
14
+ figure { margin: 0; padding: 1rem; border: 1px solid #eee; border-radius: 8px; text-align: center; }
15
+ .glyph { font-size: 2.5rem; line-height: 1; }
16
+ figcaption { margin-top: .5rem; display: flex; flex-direction: column; gap: .2rem; }
17
+ code { font-size: .8rem; word-break: break-all; }
18
+ small { color: #999; font-size: .7rem; }
19
+ </style>
20
+ </head>
21
+ <body>
22
+ <h1>y-icons <small>(2 icons)</small></h1>
23
+ <p>Figma/エディタで名前(例: <code>inventory-transfer</code>)を打つとアイコンに変わります(リガチャ)。</p>
24
+ <div class="grid">
25
+ <figure>
26
+ <span class="glyph yicon yicon-inventory-transfer"></span>
27
+ <figcaption><code>inventory-transfer</code><small>U+F102</small></figcaption>
28
+ </figure>
29
+ <figure>
30
+ <span class="glyph yicon yicon-sample"></span>
31
+ <figcaption><code>sample</code><small>U+F101</small></figcaption>
32
+ </figure>
33
+ </div>
34
+ </body>
35
+ </html>
Binary file
Binary file
Binary file
@@ -0,0 +1,10 @@
1
+ /**
2
+ * `y-icons` のフレームワーク非依存エントリ。
3
+ *
4
+ * - `yIconPaths`: name → SVG path の `d`(24×24・currentColor 前提)
5
+ * - 個別の生 SVG は `y-icons/svg/<name>.svg` から参照できる
6
+ * - Vuetify 用アダプタは `y-icons/vuetify` を使う
7
+ */
8
+ export { yIconPaths } from './registry.generated.js';
9
+ export type { YIconName } from './registry.generated.js';
10
+ export declare const yIconNames: string[];
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * `y-icons` のフレームワーク非依存エントリ。
3
+ *
4
+ * - `yIconPaths`: name → SVG path の `d`(24×24・currentColor 前提)
5
+ * - 個別の生 SVG は `y-icons/svg/<name>.svg` から参照できる
6
+ * - Vuetify 用アダプタは `y-icons/vuetify` を使う
7
+ */
8
+ export { yIconPaths } from './registry.generated.js';
9
+ /** 登録済みアイコン名の一覧 */
10
+ import { yIconPaths } from './registry.generated.js';
11
+ export const yIconNames = Object.keys(yIconPaths);
@@ -0,0 +1,2 @@
1
+ export declare const yIconPaths: Record<string, string>;
2
+ export type YIconName = keyof typeof yIconPaths;
@@ -0,0 +1,6 @@
1
+ /* 自動生成ファイル。直接編集しないこと(SoT は icons/ 配下の SVG)。
2
+ * 生成: npm run build:set */
3
+ export const yIconPaths = {
4
+ "inventory-transfer": "M2 7h11v9H2Zm2 2v5h7V9Zm10 2h2.5l2.5 2.5V16h-5Zm-9.6 6.5a1.6 1.6 0 1 0 3.2 0 1.6 1.6 0 1 0-3.2 0m10 0a1.6 1.6 0 1 0 3.2 0 1.6 1.6 0 1 0-3.2 0",
5
+ "sample": "M12 2 4 6v12l8 4 8-4V6zm0 2.18L17.66 7 12 9.82 6.34 7zM6 8.62l5 2.5v7.26l-5-2.5zm12 0v7.26l-5 2.5v-7.26z",
6
+ };
@@ -0,0 +1,4 @@
1
+ {
2
+ "inventory-transfer": "M2 7h11v9H2Zm2 2v5h7V9Zm10 2h2.5l2.5 2.5V16h-5Zm-9.6 6.5a1.6 1.6 0 1 0 3.2 0 1.6 1.6 0 1 0-3.2 0m10 0a1.6 1.6 0 1 0 3.2 0 1.6 1.6 0 1 0-3.2 0",
3
+ "sample": "M12 2 4 6v12l8 4 8-4V6zm0 2.18L17.66 7 12 9.82 6.34 7zM6 8.62l5 2.5v7.26l-5-2.5zm12 0v7.26l-5 2.5v-7.26z"
4
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M2 7h11v9H2Zm2 2v5h7V9Zm10 2h2.5l2.5 2.5V16h-5Zm-9.6 6.5a1.6 1.6 0 1 0 3.2 0 1.6 1.6 0 1 0-3.2 0m10 0a1.6 1.6 0 1 0 3.2 0 1.6 1.6 0 1 0-3.2 0"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2 4 6v12l8 4 8-4V6zm0 2.18L17.66 7 12 9.82 6.34 7zM6 8.62l5 2.5v7.26l-5-2.5zm12 0v7.26l-5 2.5v-7.26z"/></svg>
@@ -0,0 +1,8 @@
1
+ import type { IconSet, VuetifyOptions } from 'vuetify';
2
+ /** `y:` カスタムアイコンセット */
3
+ export declare const yIconSet: IconSet;
4
+ /**
5
+ * createVuetify にそのまま渡せるアイコン設定。
6
+ * 既定セットは MDI フォント、`y:` でカスタム SVG を共存させる。
7
+ */
8
+ export declare const vuetifyIcons: VuetifyOptions['icons'];
@@ -0,0 +1,44 @@
1
+ /**
2
+ * `y-icons` の Vuetify アダプタ。
3
+ *
4
+ * `y:` プレフィックスのカスタムアイコン(例: `y:sample`)を解決し、Vuetify 公式の
5
+ * `VSvgIcon` に委譲して描画する。公式 `mdi-svg` セットと同じ描画経路を通るため、
6
+ * `<svg class="v-icon__svg">` のマークアップが Vuetify 標準と一致し、size / color / tag がそのまま効く。
7
+ *
8
+ * 使い方(消費側):
9
+ * import { vuetifyIcons } from 'y-icons/vuetify'
10
+ * createVuetify({ icons: vuetifyIcons })
11
+ * // テンプレート: <v-icon icon="y:sample" />
12
+ *
13
+ * 既存の `@mdi/font`(フォント)アイコンとは独立して共存する。
14
+ */
15
+ import { h } from 'vue';
16
+ import { VSvgIcon } from 'vuetify/components';
17
+ import { aliases, mdi } from 'vuetify/iconsets/mdi';
18
+ import { yIconPaths } from './registry.generated.js';
19
+ /** `y:` カスタムアイコンセット */
20
+ export const yIconSet = {
21
+ component: (props) => {
22
+ const name = String(props.icon);
23
+ const path = yIconPaths[name];
24
+ if (path === undefined &&
25
+ typeof process !== 'undefined' &&
26
+ process.env?.NODE_ENV !== 'production') {
27
+ // eslint-disable-next-line no-console
28
+ console.warn(`[y-icons] Unknown custom icon: "y:${name}"`);
29
+ }
30
+ return h(VSvgIcon, { ...props, icon: path ?? '' });
31
+ },
32
+ };
33
+ /**
34
+ * createVuetify にそのまま渡せるアイコン設定。
35
+ * 既定セットは MDI フォント、`y:` でカスタム SVG を共存させる。
36
+ */
37
+ export const vuetifyIcons = {
38
+ defaultSet: 'mdi',
39
+ aliases,
40
+ sets: {
41
+ mdi,
42
+ y: yIconSet,
43
+ },
44
+ };
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "y-icons",
3
+ "version": "0.1.0",
4
+ "description": "独自アイコン(MDI互換)。単一の真実の源(icons/ 配下のSVG群)から、Vue/Vuetify用アイコンセット・生SVG/d-map・Figma用アイコンフォントを生成・配布する。",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/hamayou-61/y-icons.git"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js"
18
+ },
19
+ "./vuetify": {
20
+ "types": "./dist/vuetify.d.ts",
21
+ "import": "./dist/vuetify.js"
22
+ },
23
+ "./font/*": "./dist/font/*",
24
+ "./svg/*": "./dist/svg/*"
25
+ },
26
+ "scripts": {
27
+ "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
28
+ "prebuild": "npm run clean",
29
+ "build": "node scripts/build-set.mjs && node scripts/build-font.mjs && tsc -p tsconfig.build.json",
30
+ "build:set": "node scripts/build-set.mjs",
31
+ "build:font": "node scripts/build-font.mjs",
32
+ "storybook": "storybook dev -p 6007",
33
+ "build-storybook": "storybook build",
34
+ "prepublishOnly": "npm run build"
35
+ },
36
+ "peerDependencies": {
37
+ "vue": ">=3.4",
38
+ "vuetify": ">=3.5"
39
+ },
40
+ "peerDependenciesMeta": {
41
+ "vue": {
42
+ "optional": true
43
+ },
44
+ "vuetify": {
45
+ "optional": true
46
+ }
47
+ },
48
+ "devDependencies": {
49
+ "@storybook/addon-essentials": "^8.6.14",
50
+ "@storybook/vue3-vite": "^8.6.14",
51
+ "@types/node": "^20.19.43",
52
+ "storybook": "^8.6.14",
53
+ "svg-path-bounds": "^1.0.2",
54
+ "svg2ttf": "^6.1.0",
55
+ "svgicons2svgfont": "^12.0.0",
56
+ "svgo": "^3.3.2",
57
+ "ttf2woff": "^3.0.0",
58
+ "ttf2woff2": "^5.0.0",
59
+ "typescript": "^5.4.0",
60
+ "vite": "^5.4.0",
61
+ "vue": "^3.5.13",
62
+ "vuetify": "^3.5.0"
63
+ }
64
+ }