@ship-ui/core 0.19.1 → 0.19.3
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/assets/mcp/components.json +2797 -2512
- package/bin/ship-fg-scanner +0 -0
- package/bin/ship-fg.mjs +110 -7
- package/bin/src/ship-fg.ts +113 -7
- package/fesm2022/ship-ui-core.mjs +2 -3
- package/fesm2022/ship-ui-core.mjs.map +1 -1
- package/package.json +2 -1
- package/snippets/ship-ui.code-snippets +294 -294
package/bin/ship-fg-scanner
CHANGED
|
Binary file
|
package/bin/ship-fg.mjs
CHANGED
|
@@ -3235,7 +3235,7 @@ import { parseArgs } from "util";
|
|
|
3235
3235
|
// bin/src/ship-fg.ts
|
|
3236
3236
|
import { spawnSync } from "child_process";
|
|
3237
3237
|
import { watch } from "fs";
|
|
3238
|
-
import { readFile as readFile2, writeFile } from "fs/promises";
|
|
3238
|
+
import { readFile as readFile2, writeFile, readdir } from "fs/promises";
|
|
3239
3239
|
import { dirname, join, resolve } from "path";
|
|
3240
3240
|
import { fileURLToPath } from "url";
|
|
3241
3241
|
import { gzipSync } from "zlib";
|
|
@@ -3326,6 +3326,104 @@ function formatFileSize(bytes, dm = 2) {
|
|
|
3326
3326
|
var _dirname = dirname(fileURLToPath(import.meta.url));
|
|
3327
3327
|
var CWD_PATH = process.cwd();
|
|
3328
3328
|
var PHOSPHOR_SRC_PATH = resolve(CWD_PATH, "node_modules", "@phosphor-icons", "web", "src");
|
|
3329
|
+
var jsScannerFallback = async (PROJECT_SRC, shipUiDir, CWD_PATH2) => {
|
|
3330
|
+
const uniqueIcons = new Set;
|
|
3331
|
+
const isValidIcon = (s) => /^[a-z0-9-]+$/.test(s);
|
|
3332
|
+
try {
|
|
3333
|
+
const pkgPath = resolve(shipUiDir, "package.json");
|
|
3334
|
+
const pkgData = JSON.parse(await readFile2(pkgPath, "utf8"));
|
|
3335
|
+
if (pkgData.libraryIcons) {
|
|
3336
|
+
pkgData.libraryIcons.forEach((i) => uniqueIcons.add(i));
|
|
3337
|
+
}
|
|
3338
|
+
} catch (e) {}
|
|
3339
|
+
async function scanDir(dir) {
|
|
3340
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
3341
|
+
for (const entry of entries) {
|
|
3342
|
+
if (entry.name === "node_modules" || entry.name.startsWith("."))
|
|
3343
|
+
continue;
|
|
3344
|
+
const fullPath = resolve(dir, entry.name);
|
|
3345
|
+
if (entry.isDirectory()) {
|
|
3346
|
+
await scanDir(fullPath);
|
|
3347
|
+
} else if (entry.name.endsWith(".html") || entry.name.endsWith(".ts")) {
|
|
3348
|
+
const contents = await readFile2(fullPath, "utf8");
|
|
3349
|
+
const htmlStartMatches = contents.matchAll(/<sh-icon[^>]*icon=['"]([^'"]+)['"][^>]*>/g);
|
|
3350
|
+
for (const m of htmlStartMatches) {
|
|
3351
|
+
const icon = m[1].trim();
|
|
3352
|
+
if (isValidIcon(icon))
|
|
3353
|
+
uniqueIcons.add(icon);
|
|
3354
|
+
}
|
|
3355
|
+
const htmlContentMatches = contents.matchAll(/<sh-icon[^>]*>([^<]+)<\/sh-icon>/g);
|
|
3356
|
+
for (const m of htmlContentMatches) {
|
|
3357
|
+
const icon = m[1].trim();
|
|
3358
|
+
if (isValidIcon(icon))
|
|
3359
|
+
uniqueIcons.add(icon);
|
|
3360
|
+
}
|
|
3361
|
+
const tsMatches = contents.matchAll(/shicon:([^'"]+)['"]/g);
|
|
3362
|
+
for (const m of tsMatches) {
|
|
3363
|
+
const icon = m[1].trim();
|
|
3364
|
+
if (isValidIcon(icon))
|
|
3365
|
+
uniqueIcons.add(icon);
|
|
3366
|
+
}
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
await scanDir(PROJECT_SRC);
|
|
3371
|
+
const variants = ["bold", "thin", "light", "fill", "regular", "duotone"];
|
|
3372
|
+
const glyphMaps = new Map;
|
|
3373
|
+
for (const variant of variants) {
|
|
3374
|
+
try {
|
|
3375
|
+
const selPath = resolve(CWD_PATH2, "node_modules", "@phosphor-icons", "web", "src", variant, "selection.json");
|
|
3376
|
+
const parsed = JSON.parse(await readFile2(selPath, "utf8"));
|
|
3377
|
+
const isDuotone = variant === "duotone";
|
|
3378
|
+
for (const icon of parsed.icons || []) {
|
|
3379
|
+
const hexCode = icon.properties.code.toString(16);
|
|
3380
|
+
const unicodeStr = `U+${hexCode}`;
|
|
3381
|
+
const glyph = String.fromCodePoint(icon.properties.code);
|
|
3382
|
+
let glyphName = isDuotone ? icon.properties.name : icon.properties.ligatures;
|
|
3383
|
+
if (glyphName)
|
|
3384
|
+
glyphMaps.set(glyphName, [glyph, unicodeStr]);
|
|
3385
|
+
}
|
|
3386
|
+
} catch (e) {}
|
|
3387
|
+
}
|
|
3388
|
+
const grouped = {
|
|
3389
|
+
bold: [],
|
|
3390
|
+
thin: [],
|
|
3391
|
+
light: [],
|
|
3392
|
+
fill: [],
|
|
3393
|
+
regular: [],
|
|
3394
|
+
duotone: [],
|
|
3395
|
+
text: [],
|
|
3396
|
+
missing: []
|
|
3397
|
+
};
|
|
3398
|
+
for (const icon of uniqueIcons) {
|
|
3399
|
+
const isBold = icon.endsWith("-bold");
|
|
3400
|
+
const isThin = icon.endsWith("-thin");
|
|
3401
|
+
const isLight = icon.endsWith("-light");
|
|
3402
|
+
const isFill = icon.endsWith("-fill");
|
|
3403
|
+
const isDuotone = icon.endsWith("-duotone");
|
|
3404
|
+
const isRegular = !isBold && !isThin && !isLight && !isFill && !isDuotone;
|
|
3405
|
+
const mapEntry = glyphMaps.get(icon);
|
|
3406
|
+
if (mapEntry) {
|
|
3407
|
+
const tuple1 = [icon, ""];
|
|
3408
|
+
const tuple2 = mapEntry;
|
|
3409
|
+
if (isBold)
|
|
3410
|
+
grouped.bold.push(tuple1, tuple2);
|
|
3411
|
+
else if (isThin)
|
|
3412
|
+
grouped.thin.push(tuple1, tuple2);
|
|
3413
|
+
else if (isLight)
|
|
3414
|
+
grouped.light.push(tuple1, tuple2);
|
|
3415
|
+
else if (isFill)
|
|
3416
|
+
grouped.fill.push(tuple1, tuple2);
|
|
3417
|
+
else if (isDuotone)
|
|
3418
|
+
grouped.duotone.push(tuple1, tuple2);
|
|
3419
|
+
else
|
|
3420
|
+
grouped.regular.push(tuple1, tuple2);
|
|
3421
|
+
} else {
|
|
3422
|
+
grouped.missing.push(icon);
|
|
3423
|
+
}
|
|
3424
|
+
}
|
|
3425
|
+
return grouped;
|
|
3426
|
+
};
|
|
3329
3427
|
var writtenCssSize = 0;
|
|
3330
3428
|
var compressedCssSize = 0;
|
|
3331
3429
|
var watchers = [];
|
|
@@ -3339,15 +3437,20 @@ var run = async (PROJECT_SRC, PROJECT_PUBLIC, TARGET_FONT_TYPE, values) => {
|
|
|
3339
3437
|
try {
|
|
3340
3438
|
const proc = spawnSync(scannerPath, [PROJECT_SRC, shipUiDir, CWD_PATH]);
|
|
3341
3439
|
if (proc.error || proc.status !== 0) {
|
|
3342
|
-
console.error("Error running scanner:", proc.stderr?.toString() || proc.error);
|
|
3343
3440
|
throw new Error("Native scanner failed");
|
|
3344
3441
|
}
|
|
3345
|
-
const
|
|
3346
|
-
groupedIcons =
|
|
3347
|
-
missingIconsArray =
|
|
3442
|
+
const { missing, ...rest } = JSON.parse(proc.stdout?.toString() || "{}");
|
|
3443
|
+
groupedIcons = rest;
|
|
3444
|
+
missingIconsArray = missing || [];
|
|
3348
3445
|
} catch (err) {
|
|
3349
|
-
|
|
3350
|
-
|
|
3446
|
+
try {
|
|
3447
|
+
const { missing, ...rest } = await jsScannerFallback(PROJECT_SRC, shipUiDir, CWD_PATH);
|
|
3448
|
+
groupedIcons = rest;
|
|
3449
|
+
missingIconsArray = missing || [];
|
|
3450
|
+
} catch (fallbackErr) {
|
|
3451
|
+
console.error("Failed to run high-performance zig scanner and the javascript fallback failed:", fallbackErr);
|
|
3452
|
+
throw err;
|
|
3453
|
+
}
|
|
3351
3454
|
}
|
|
3352
3455
|
if (missingIconsArray.length) {
|
|
3353
3456
|
console.log(`Following icons does not exist in font:
|
package/bin/src/ship-fg.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { spawnSync } from 'child_process';
|
|
4
4
|
import { FSWatcher, watch } from 'fs';
|
|
5
|
-
import { readFile, writeFile } from 'fs/promises';
|
|
5
|
+
import { readFile, writeFile, readdir } from 'fs/promises';
|
|
6
6
|
import { dirname, join, resolve } from 'path';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
8
|
import { gzipSync } from 'zlib';
|
|
@@ -16,6 +16,107 @@ import { formatFileSize, InputArguments, SupportedFontTypes } from './utilities'
|
|
|
16
16
|
const CWD_PATH = process.cwd();
|
|
17
17
|
const PHOSPHOR_SRC_PATH = resolve(CWD_PATH, 'node_modules', '@phosphor-icons', 'web', 'src');
|
|
18
18
|
|
|
19
|
+
const jsScannerFallback = async (PROJECT_SRC: string, shipUiDir: string, CWD_PATH: string) => {
|
|
20
|
+
const uniqueIcons = new Set<string>();
|
|
21
|
+
|
|
22
|
+
const isValidIcon = (s: string) => /^[a-z0-9-]+$/.test(s);
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const pkgPath = resolve(shipUiDir, 'package.json');
|
|
26
|
+
const pkgData = JSON.parse(await readFile(pkgPath, 'utf8'));
|
|
27
|
+
if (pkgData.libraryIcons) {
|
|
28
|
+
pkgData.libraryIcons.forEach((i: string) => uniqueIcons.add(i));
|
|
29
|
+
}
|
|
30
|
+
} catch (e) {}
|
|
31
|
+
|
|
32
|
+
async function scanDir(dir: string) {
|
|
33
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
34
|
+
for (const entry of entries) {
|
|
35
|
+
if (entry.name === 'node_modules' || entry.name.startsWith('.')) continue;
|
|
36
|
+
const fullPath = resolve(dir, entry.name);
|
|
37
|
+
if (entry.isDirectory()) {
|
|
38
|
+
await scanDir(fullPath);
|
|
39
|
+
} else if (entry.name.endsWith('.html') || entry.name.endsWith('.ts')) {
|
|
40
|
+
const contents = await readFile(fullPath, 'utf8');
|
|
41
|
+
|
|
42
|
+
const htmlStartMatches = contents.matchAll(/<sh-icon[^>]*icon=['"]([^'"]+)['"][^>]*>/g);
|
|
43
|
+
for (const m of htmlStartMatches) {
|
|
44
|
+
const icon = m[1].trim();
|
|
45
|
+
if (isValidIcon(icon)) uniqueIcons.add(icon);
|
|
46
|
+
}
|
|
47
|
+
const htmlContentMatches = contents.matchAll(/<sh-icon[^>]*>([^<]+)<\/sh-icon>/g);
|
|
48
|
+
for (const m of htmlContentMatches) {
|
|
49
|
+
const icon = m[1].trim();
|
|
50
|
+
if (isValidIcon(icon)) uniqueIcons.add(icon);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const tsMatches = contents.matchAll(/shicon:([^'"]+)['"]/g);
|
|
54
|
+
for (const m of tsMatches) {
|
|
55
|
+
const icon = m[1].trim();
|
|
56
|
+
if (isValidIcon(icon)) uniqueIcons.add(icon);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
await scanDir(PROJECT_SRC);
|
|
62
|
+
|
|
63
|
+
const variants = ['bold', 'thin', 'light', 'fill', 'regular', 'duotone'];
|
|
64
|
+
const glyphMaps = new Map<string, [string, string]>();
|
|
65
|
+
|
|
66
|
+
for (const variant of variants) {
|
|
67
|
+
try {
|
|
68
|
+
const selPath = resolve(CWD_PATH, 'node_modules', '@phosphor-icons', 'web', 'src', variant, 'selection.json');
|
|
69
|
+
const parsed = JSON.parse(await readFile(selPath, 'utf8'));
|
|
70
|
+
const isDuotone = variant === 'duotone';
|
|
71
|
+
|
|
72
|
+
for (const icon of parsed.icons || []) {
|
|
73
|
+
const hexCode = icon.properties.code.toString(16);
|
|
74
|
+
const unicodeStr = `U+${hexCode}`;
|
|
75
|
+
const glyph = String.fromCodePoint(icon.properties.code);
|
|
76
|
+
|
|
77
|
+
let glyphName = isDuotone ? icon.properties.name : icon.properties.ligatures;
|
|
78
|
+
if (glyphName) glyphMaps.set(glyphName, [glyph, unicodeStr]);
|
|
79
|
+
}
|
|
80
|
+
} catch (e) {}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const grouped = {
|
|
84
|
+
bold: [] as [string, string][],
|
|
85
|
+
thin: [] as [string, string][],
|
|
86
|
+
light: [] as [string, string][],
|
|
87
|
+
fill: [] as [string, string][],
|
|
88
|
+
regular: [] as [string, string][],
|
|
89
|
+
duotone: [] as [string, string][],
|
|
90
|
+
text: [] as [string, string][],
|
|
91
|
+
missing: [] as string[],
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
for (const icon of uniqueIcons) {
|
|
95
|
+
const isBold = icon.endsWith('-bold');
|
|
96
|
+
const isThin = icon.endsWith('-thin');
|
|
97
|
+
const isLight = icon.endsWith('-light');
|
|
98
|
+
const isFill = icon.endsWith('-fill');
|
|
99
|
+
const isDuotone = icon.endsWith('-duotone');
|
|
100
|
+
const isRegular = !isBold && !isThin && !isLight && !isFill && !isDuotone;
|
|
101
|
+
|
|
102
|
+
const mapEntry = glyphMaps.get(icon);
|
|
103
|
+
if (mapEntry) {
|
|
104
|
+
const tuple1: [string, string] = [icon, ''];
|
|
105
|
+
const tuple2 = mapEntry; // [glyph, unicodeStr]
|
|
106
|
+
if (isBold) grouped.bold.push(tuple1, tuple2);
|
|
107
|
+
else if (isThin) grouped.thin.push(tuple1, tuple2);
|
|
108
|
+
else if (isLight) grouped.light.push(tuple1, tuple2);
|
|
109
|
+
else if (isFill) grouped.fill.push(tuple1, tuple2);
|
|
110
|
+
else if (isDuotone) grouped.duotone.push(tuple1, tuple2);
|
|
111
|
+
else grouped.regular.push(tuple1, tuple2);
|
|
112
|
+
} else {
|
|
113
|
+
grouped.missing.push(icon);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return grouped;
|
|
118
|
+
};
|
|
119
|
+
|
|
19
120
|
let writtenCssSize = 0;
|
|
20
121
|
let compressedCssSize = 0;
|
|
21
122
|
let watchers: FSWatcher[] = [];
|
|
@@ -37,16 +138,21 @@ const run = async (
|
|
|
37
138
|
try {
|
|
38
139
|
const proc = spawnSync(scannerPath, [PROJECT_SRC, shipUiDir, CWD_PATH]);
|
|
39
140
|
if (proc.error || proc.status !== 0) {
|
|
40
|
-
console.error('Error running scanner:', proc.stderr?.toString() || proc.error);
|
|
41
141
|
throw new Error('Native scanner failed');
|
|
42
142
|
}
|
|
43
143
|
|
|
44
|
-
const
|
|
45
|
-
groupedIcons =
|
|
46
|
-
missingIconsArray =
|
|
144
|
+
const { missing, ...rest } = JSON.parse(proc.stdout?.toString() || '{}');
|
|
145
|
+
groupedIcons = rest;
|
|
146
|
+
missingIconsArray = missing || [];
|
|
47
147
|
} catch (err) {
|
|
48
|
-
|
|
49
|
-
|
|
148
|
+
try {
|
|
149
|
+
const { missing, ...rest } = await jsScannerFallback(PROJECT_SRC, shipUiDir, CWD_PATH);
|
|
150
|
+
groupedIcons = rest;
|
|
151
|
+
missingIconsArray = missing || [];
|
|
152
|
+
} catch (fallbackErr) {
|
|
153
|
+
console.error('Failed to run high-performance zig scanner and the javascript fallback failed:', fallbackErr);
|
|
154
|
+
throw err;
|
|
155
|
+
}
|
|
50
156
|
}
|
|
51
157
|
|
|
52
158
|
if (missingIconsArray.length) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { InjectionToken, inject, computed, ElementRef, Renderer2, input, ChangeDetectionStrategy, Component, viewChild, effect, HostListener, NgModule, signal, Injectable, DOCUMENT, model, output, ApplicationRef, OutputEmitterRef, TemplateRef, createComponent, isSignal, DestroyRef, PLATFORM_ID, ViewChild, booleanAttribute, Directive, untracked, contentChild, contentChildren, afterNextRender, Injector, HostBinding, runInInjectionContext, ChangeDetectorRef, viewChildren, ViewContainerRef, EnvironmentInjector } from '@angular/core';
|
|
3
3
|
import { isPlatformBrowser, JsonPipe, DatePipe, isPlatformServer, NgTemplateOutlet } from '@angular/common';
|
|
4
|
-
import { ShipButton as ShipButton$1 } from 'ship-ui';
|
|
5
4
|
import { NgModel } from '@angular/forms';
|
|
6
5
|
import { isObservable, firstValueFrom } from 'rxjs';
|
|
7
6
|
|
|
@@ -3660,13 +3659,13 @@ class ShipColorPickerInput {
|
|
|
3660
3659
|
}
|
|
3661
3660
|
</div>
|
|
3662
3661
|
</sh-form-field-popover>
|
|
3663
|
-
`, isInline: true, dependencies: [{ kind: "component", type: ShipFormFieldPopover, selector: "sh-form-field-popover", inputs: ["isOpen", "color", "variant", "size", "readonly"], outputs: ["isOpenChange", "closed"] }, { kind: "component", type: ShipColorPicker, selector: "sh-color-picker", inputs: ["showDarkColors", "renderingType", "gridSize", "hue", "direction", "selectedColor", "alpha"], outputs: ["hueChange", "selectedColorChange", "alphaChange", "currentColor"] }, { kind: "component", type: ShipIcon, selector: "sh-icon", inputs: ["color", "size"] }, { kind: "component", type: ShipButton
|
|
3662
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ShipFormFieldPopover, selector: "sh-form-field-popover", inputs: ["isOpen", "color", "variant", "size", "readonly"], outputs: ["isOpenChange", "closed"] }, { kind: "component", type: ShipColorPicker, selector: "sh-color-picker", inputs: ["showDarkColors", "renderingType", "gridSize", "hue", "direction", "selectedColor", "alpha"], outputs: ["hueChange", "selectedColorChange", "alphaChange", "currentColor"] }, { kind: "component", type: ShipIcon, selector: "sh-icon", inputs: ["color", "size"] }, { kind: "component", type: ShipButton, selector: "[shButton]", inputs: ["color", "variant", "size", "readonly"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3664
3663
|
}
|
|
3665
3664
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: ShipColorPickerInput, decorators: [{
|
|
3666
3665
|
type: Component,
|
|
3667
3666
|
args: [{
|
|
3668
3667
|
selector: 'sh-color-picker-input',
|
|
3669
|
-
imports: [ShipFormFieldPopover, ShipColorPicker, ShipIcon, ShipButton
|
|
3668
|
+
imports: [ShipFormFieldPopover, ShipColorPicker, ShipIcon, ShipButton],
|
|
3670
3669
|
template: `
|
|
3671
3670
|
<sh-form-field-popover
|
|
3672
3671
|
(closed)="close()"
|