@shival99/z-ui 2.1.6 → 2.1.7
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/fesm2022/shival99-z-ui-components-z-icon.mjs +96 -0
- package/fesm2022/shival99-z-ui-components-z-icon.mjs.map +1 -1
- package/package.json +8 -4
- package/scripts/z-init-project.mjs +645 -0
- package/types/shival99-z-ui-components-z-autocomplete.d.ts +1 -1
- package/types/shival99-z-ui-components-z-editor.d.ts +1 -1
- package/types/shival99-z-ui-components-z-gallery.d.ts +4 -4
- package/types/shival99-z-ui-components-z-icon.d.ts +17 -1
- package/types/shival99-z-ui-components-z-modal.d.ts +1 -1
- package/types/shival99-z-ui-components-z-popover.d.ts +1 -1
- package/types/shival99-z-ui-components-z-select.d.ts +1 -1
- package/types/shival99-z-ui-components-z-table.d.ts +1 -1
- package/types/shival99-z-ui-components-z-upload.d.ts +3 -3
|
@@ -254,6 +254,51 @@ function normalizeLucideSvg(svg) {
|
|
|
254
254
|
const cssVar = 'style="stroke-width: var(--ng-icon__stroke-width, 2)"';
|
|
255
255
|
return svg.replace(/stroke-width="[^"]*"/gi, cssVar);
|
|
256
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* Phosphor SVGs already ship with fill="currentColor" and no stroke-width,
|
|
259
|
+
* so no normalization is required. Kept as an explicit passthrough for parity
|
|
260
|
+
* with the other icon families.
|
|
261
|
+
*/
|
|
262
|
+
function normalizePhosphorSvg(svg) {
|
|
263
|
+
return svg;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* HugeIcons ships each icon as an ESM module exporting a path-array
|
|
267
|
+
* (e.g. `const HeartIcon = [["path", { d: "...", stroke: "currentColor", strokeWidth: "1.5" }]]`),
|
|
268
|
+
* not a ready-made SVG. This converts that module source into an `<svg>` string
|
|
269
|
+
* suitable for ng-icon, mapping camelCase attributes to kebab-case and wiring
|
|
270
|
+
* stroke-width to the ng-icon CSS variable.
|
|
271
|
+
*/
|
|
272
|
+
function normalizeHugeIconModule(moduleSource) {
|
|
273
|
+
const elements = [];
|
|
274
|
+
const elementRegex = /\[\s*"([a-zA-Z]+)"\s*,\s*\{([^}]*)\}\s*\]/g;
|
|
275
|
+
let match;
|
|
276
|
+
while ((match = elementRegex.exec(moduleSource)) !== null) {
|
|
277
|
+
const tag = match[1];
|
|
278
|
+
const attrsBody = match[2];
|
|
279
|
+
const attrs = [];
|
|
280
|
+
const attrRegex = /([a-zA-Z]+)\s*:\s*"([^"]*)"/g;
|
|
281
|
+
let attrMatch;
|
|
282
|
+
while ((attrMatch = attrRegex.exec(attrsBody)) !== null) {
|
|
283
|
+
const rawKey = attrMatch[1];
|
|
284
|
+
const value = attrMatch[2];
|
|
285
|
+
if (rawKey === 'key') {
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (rawKey === 'strokeWidth') {
|
|
289
|
+
attrs.push(`style="stroke-width:var(--ng-icon__stroke-width, ${value})"`);
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
const attrName = rawKey.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
|
293
|
+
attrs.push(`${attrName}="${value}"`);
|
|
294
|
+
}
|
|
295
|
+
elements.push(`<${tag} ${attrs.join(' ')}></${tag}>`);
|
|
296
|
+
}
|
|
297
|
+
if (elements.length === 0) {
|
|
298
|
+
return '';
|
|
299
|
+
}
|
|
300
|
+
return `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">${elements.join('')}</svg>`;
|
|
301
|
+
}
|
|
257
302
|
function getFallbackIcon(name) {
|
|
258
303
|
const icon = Z_ICONS[name];
|
|
259
304
|
if (icon) {
|
|
@@ -307,8 +352,49 @@ function convertIconSaxIconName(name) {
|
|
|
307
352
|
.replace(/--+/g, '-');
|
|
308
353
|
return { style: styleFolder, iconName };
|
|
309
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* Converts ng-icons Phosphor icon name to CDN format.
|
|
357
|
+
* Phosphor weights map to folders, and every weight except "regular" carries a
|
|
358
|
+
* file-name suffix (e.g. heart-bold.svg), while regular is just heart.svg.
|
|
359
|
+
* Examples:
|
|
360
|
+
* - phosphorHeart -> regular/heart
|
|
361
|
+
* - phosphorHeartBold -> bold/heart-bold
|
|
362
|
+
* - phosphorHeartFill -> fill/heart-fill
|
|
363
|
+
* - phosphorHeartDuotone -> duotone/heart-duotone
|
|
364
|
+
* - phosphorAddressBookTabsLight -> light/address-book-tabs-light
|
|
365
|
+
*/
|
|
366
|
+
function convertPhosphorIconName(name) {
|
|
367
|
+
let iconPart = name.replace(/^phosphor/, '');
|
|
368
|
+
const weightMatch = iconPart.match(/(Bold|Fill|Light|Thin|Duotone)$/);
|
|
369
|
+
const weight = weightMatch ? weightMatch[1].toLowerCase() : 'regular';
|
|
370
|
+
if (weightMatch) {
|
|
371
|
+
iconPart = iconPart.replace(/(Bold|Fill|Light|Thin|Duotone)$/, '');
|
|
372
|
+
}
|
|
373
|
+
const kebab = iconPart
|
|
374
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
375
|
+
.replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
|
|
376
|
+
.toLowerCase()
|
|
377
|
+
.replace(/^-/, '')
|
|
378
|
+
.replace(/--+/g, '-');
|
|
379
|
+
const iconName = weight === 'regular' ? kebab : `${kebab}-${weight}`;
|
|
380
|
+
return { weight, iconName };
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Converts ng-icons-style Huge icon name to the @hugeicons/core-free-icons
|
|
384
|
+
* CDN module name. We expose icons with a `huge` prefix over the original
|
|
385
|
+
* PascalCase export name, so we just strip the prefix and append `Icon`.
|
|
386
|
+
* Examples:
|
|
387
|
+
* - hugeHeart -> HeartIcon
|
|
388
|
+
* - hugeHome01 -> Home01Icon
|
|
389
|
+
* - hugeFirstBracketCircle -> FirstBracketCircleIcon
|
|
390
|
+
*/
|
|
391
|
+
function convertHugeIconName(name) {
|
|
392
|
+
return `${name.replace(/^huge/, '')}Icon`;
|
|
393
|
+
}
|
|
310
394
|
const LUCIDE_CDN_URL = 'https://cdn.jsdelivr.net/npm/lucide-static@latest/icons';
|
|
311
395
|
const SAX_CDN_URL = 'https://cdn.jsdelivr.net/gh/placetopay-org/iconsax-vue@main/src/Base';
|
|
396
|
+
const PHOSPHOR_CDN_URL = 'https://cdn.jsdelivr.net/npm/@phosphor-icons/core@latest/assets';
|
|
397
|
+
const HUGE_CDN_URL = 'https://cdn.jsdelivr.net/npm/@hugeicons/core-free-icons@4.2.1/dist/esm';
|
|
312
398
|
/**
|
|
313
399
|
* Provides hybrid icon loading from CDN with fallback to bundled icons:
|
|
314
400
|
* - Primary: Load icons from CDN (Lucide & Iconsax)
|
|
@@ -354,6 +440,16 @@ function provideZIconLoader() {
|
|
|
354
440
|
const url = `${LUCIDE_CDN_URL}/${iconName}.svg`;
|
|
355
441
|
return loadWithCache(name, url, http, normalizeLucideSvg);
|
|
356
442
|
}
|
|
443
|
+
if (name.startsWith('phosphor')) {
|
|
444
|
+
const { weight, iconName } = convertPhosphorIconName(name);
|
|
445
|
+
const url = `${PHOSPHOR_CDN_URL}/${weight}/${iconName}.svg`;
|
|
446
|
+
return loadWithCache(name, url, http, normalizePhosphorSvg);
|
|
447
|
+
}
|
|
448
|
+
if (name.startsWith('huge')) {
|
|
449
|
+
const moduleName = convertHugeIconName(name);
|
|
450
|
+
const url = `${HUGE_CDN_URL}/${moduleName}.js`;
|
|
451
|
+
return loadWithCache(name, url, http, normalizeHugeIconModule);
|
|
452
|
+
}
|
|
357
453
|
// console.warn(`[ZIcon] Unknown icon: "${name}"`);
|
|
358
454
|
return of(getFallbackIcon(name));
|
|
359
455
|
}, withCaching()),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shival99-z-ui-components-z-icon.mjs","sources":["../../../../libs/core-ui/components/z-icon/z-animated-icons.ts","../../../../libs/core-ui/components/z-icon/z-icon-cache.ts","../../../../libs/core-ui/components/z-icon/z-icon.variants.ts","../../../../libs/core-ui/components/z-icon/z-icon.component.ts","../../../../libs/core-ui/components/z-icon/z-icon.component.html","../../../../libs/core-ui/components/z-icon/z-icons.ts","../../../../libs/core-ui/components/z-icon/z-icon-loader.provider.ts","../../../../libs/core-ui/components/z-icon/shival99-z-ui-components-z-icon.ts"],"sourcesContent":["import { type Type } from '@angular/core';\nimport * as animatedIcons from 'ng-animated-icons';\n\ntype ZAnimatedIconExport = Extract<keyof typeof animatedIcons, `${string}Icon`>;\ntype ZBrokenAnimatedIconExport = 'AudioLinesIcon';\ntype ZSafeAnimatedIconExport = Exclude<ZAnimatedIconExport, ZBrokenAnimatedIconExport>;\n\ntype ZStripIconSuffix<T extends string> = T extends `${infer Name}Icon` ? Name : T;\n\ntype ZKebabCase<T extends string, Previous extends string = ''> = T extends `${infer Head}${infer Tail}`\n ? Tail extends Uncapitalize<Tail>\n ? Head extends `${number}`\n ? Previous extends '' | '-' | `${number}`\n ? `${Head}${ZKebabCase<Tail, Head>}`\n : `-${Head}${ZKebabCase<Tail, Head>}`\n : `${Lowercase<Head>}${ZKebabCase<Tail, Head>}`\n : `${Lowercase<Head>}-${ZKebabCase<Tail, '-'>}`\n : T;\n\ntype ZAnimatedIconName = ZKebabCase<ZStripIconSuffix<ZSafeAnimatedIconExport>>;\n\nexport type ZAnimatedIcon = ZAnimatedIconName;\n\nconst ANIMATED_ICONS = animatedIcons as unknown as Record<ZAnimatedIconExport, Type<unknown>>;\nconst BROKEN_ANIMATED_ICON_EXPORTS = new Set<ZAnimatedIconExport>(['AudioLinesIcon']);\n\nexport const Z_ANIMATED_ICONS = Object.fromEntries(\n (\n Object.entries(ANIMATED_ICONS).filter(\n ([exportName]) =>\n exportName.endsWith('Icon') && !BROKEN_ANIMATED_ICON_EXPORTS.has(exportName as ZAnimatedIconExport)\n ) as [ZSafeAnimatedIconExport, Type<unknown>][]\n ).map(([exportName, icon]) => [toKebabIconName(exportName), icon])\n) as Record<ZAnimatedIcon, Type<unknown>>;\n\nexport function getZAnimatedIconComponent(iconName: ZAnimatedIcon): Type<unknown> | null {\n return Z_ANIMATED_ICONS[iconName] ?? null;\n}\n\nfunction toKebabIconName(exportName: string): ZAnimatedIcon {\n const iconName = exportName.endsWith('Icon') ? exportName.slice(0, -4) : exportName;\n\n return iconName\n .replace(/([a-z])([0-9])/g, '$1-$2')\n .replace(/([0-9])([A-Z])/g, '$1-$2')\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase() as ZAnimatedIcon;\n}\n","import { isDevMode } from '@angular/core';\nimport { ZIndexDbService } from '@shival99/z-ui/services';\n\nexport const Z_ICON_CACHE_DB_NAME = 'ZIconCache';\nexport const Z_ICON_CACHE_STORE = 'zIcons';\n\nexport const zIconCacheDb = new ZIndexDbService({\n dbName: Z_ICON_CACHE_DB_NAME,\n version: 1,\n stores: [{ name: Z_ICON_CACHE_STORE, encrypt: !isDevMode() }],\n defaultStore: Z_ICON_CACHE_STORE,\n});\n","import { cva, type VariantProps } from 'class-variance-authority';\n\nconst zIconSizeVariants = Object.fromEntries(\n Array.from({ length: 100 - 10 + 1 }, (_, index) => {\n const size = String(10 + index);\n return [size, `size-${size}`];\n })\n);\n\nexport const zIconVariants = cva('', {\n variants: {\n zSize: zIconSizeVariants,\n },\n defaultVariants: {\n zSize: '16',\n },\n});\n\nexport type ZIconSize = `${number}`;\nexport type ZIconVariants = VariantProps<typeof zIconVariants>;\n","import { NgComponentOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n input,\n signal,\n type Type,\n ViewEncapsulation,\n} from '@angular/core';\nimport { NgIconComponent as NgIcon } from '@ng-icons/core';\nimport { zMergeClasses } from '@shival99/z-ui/utils';\nimport type { ClassValue } from 'clsx';\nimport { getZAnimatedIconComponent, type ZAnimatedIcon } from './z-animated-icons';\nimport { Z_ICON_CACHE_STORE, zIconCacheDb } from './z-icon-cache';\nimport { zIconVariants, type ZIconVariants } from './z-icon.variants';\nimport { type ZIcon } from './z-icons';\n\nexport type ZIconAnimationTrigger = 'manual' | 'hover' | 'focus' | 'interaction' | 'always';\n\n@Component({\n selector: 'z-icon, [z-icon]',\n imports: [NgIcon, NgComponentOutlet],\n standalone: true,\n templateUrl: './z-icon.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'zClasses()',\n '[style.width]': 'normalizedSize() + \"px\"',\n '[style.height]': 'normalizedSize() + \"px\"',\n '(mouseenter)': 'setHoverActive(true)',\n '(mouseleave)': 'setHoverActive(false)',\n '(focusin)': 'setFocusActive(true)',\n '(focusout)': 'setFocusActive(false)',\n '(touchstart)': 'setTouchActive(true)',\n '(touchend)': 'setTouchActive(false)',\n },\n})\nexport class ZIconComponent {\n public readonly class = input<ClassValue>('');\n public readonly zType = input<ZIcon>();\n public readonly zAnimatedType = input<ZAnimatedIcon>();\n public readonly zAnimate = input(false);\n public readonly zAnimationTrigger = input<ZIconAnimationTrigger>('manual');\n public readonly zSize = input<ZIconVariants['zSize']>('16');\n public readonly zStrokeWidth = input<number>(2);\n public readonly zSvg = input<string>('');\n protected readonly resolvedSvg = signal('');\n protected readonly isHoverActive = signal(false);\n protected readonly isFocusActive = signal(false);\n protected readonly isTouchActive = signal(false);\n protected readonly normalizedSize = computed(() => {\n const size = this.zSize();\n if (size === null || size === undefined || size === '') {\n return '16';\n }\n\n return String(size);\n });\n\n private readonly _svgFetchError = signal<string>('');\n\n protected readonly zClasses = computed(() =>\n zMergeClasses(\n zIconVariants({ zSize: this.zSize() }),\n this.class(),\n this.zStrokeWidth() === 0 ? 'stroke-none' : '',\n 'inline-flex shrink-0'\n )\n );\n\n protected readonly animatedIcon = computed<Type<unknown> | null>(() => {\n const animatedType = this.zAnimatedType();\n if (!animatedType) {\n return null;\n }\n\n return getZAnimatedIconComponent(animatedType);\n });\n\n protected readonly animatedIconInputs = computed<Record<string, unknown>>(() => ({\n animate: this.shouldAnimate(),\n color: 'currentColor',\n size: Number(this.normalizedSize()),\n strokeWidth: this.zStrokeWidth(),\n }));\n\n protected readonly shouldAnimate = computed(() => {\n const trigger = this.zAnimationTrigger();\n if (trigger === 'always' || this.zAnimate()) {\n return true;\n }\n\n if (trigger === 'hover') {\n return this.isHoverActive() || this.isTouchActive();\n }\n\n if (trigger === 'focus') {\n return this.isFocusActive();\n }\n\n if (trigger === 'interaction') {\n return this.isHoverActive() || this.isFocusActive() || this.isTouchActive();\n }\n\n return false;\n });\n\n constructor() {\n effect(onCleanup => {\n const svgInput = this.zSvg().trim();\n if (!svgInput) {\n this.resolvedSvg.set('');\n this._svgFetchError.set('');\n return;\n }\n\n if (this._isRawSvg(svgInput)) {\n this.resolvedSvg.set(this._normalizeCustomSvg(svgInput));\n this._svgFetchError.set('');\n return;\n }\n\n if (!this._isSvgPath(svgInput)) {\n this.resolvedSvg.set('');\n this._svgFetchError.set('Unsupported SVG input format.');\n return;\n }\n\n const controller = new AbortController();\n onCleanup(() => controller.abort());\n\n const cacheKey = `zsvg:path:${svgInput}`;\n void zIconCacheDb\n .get<string>(cacheKey, { storeName: Z_ICON_CACHE_STORE })\n .then(cachedSvg => {\n if (controller.signal.aborted) {\n return null;\n }\n if (cachedSvg && this._isRawSvg(cachedSvg.trim())) {\n this.resolvedSvg.set(this._normalizeCustomSvg(cachedSvg));\n this._svgFetchError.set('');\n return null;\n }\n\n return fetch(svgInput, { signal: controller.signal }).then(response => {\n if (!response.ok) {\n throw new Error(`Failed to fetch SVG from \"${svgInput}\"`);\n }\n return response.text();\n });\n })\n .then(svgContent => {\n if (controller.signal.aborted || !svgContent) {\n return;\n }\n\n if (!this._isRawSvg(svgContent.trim())) {\n throw new Error(`Invalid SVG content loaded from \"${svgInput}\"`);\n }\n\n const normalizedSvg = this._normalizeCustomSvg(svgContent);\n this.resolvedSvg.set(normalizedSvg);\n this._svgFetchError.set('');\n void zIconCacheDb.set(cacheKey, normalizedSvg, { storeName: Z_ICON_CACHE_STORE }).catch(console.error);\n })\n .catch(error => {\n if (controller.signal.aborted) {\n return;\n }\n console.error('[z-icon] Failed to load zSvg path:', error);\n this.resolvedSvg.set('');\n this._svgFetchError.set('Unable to load SVG path.');\n });\n });\n }\n\n private _isRawSvg(value: string): boolean {\n return value.startsWith('<svg');\n }\n\n protected setHoverActive(isActive: boolean): void {\n this.isHoverActive.set(isActive);\n }\n\n protected setFocusActive(isActive: boolean): void {\n this.isFocusActive.set(isActive);\n }\n\n protected setTouchActive(isActive: boolean): void {\n this.isTouchActive.set(isActive);\n }\n\n private _isSvgPath(value: string): boolean {\n return value.endsWith('.svg') || value.includes('/');\n }\n\n private _normalizeCustomSvg(svg: string): string {\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(svg, 'image/svg+xml');\n const svgEl = doc.documentElement;\n if (svgEl.tagName.toLowerCase() !== 'svg') {\n return svg;\n }\n\n const width = svgEl.getAttribute('width');\n const height = svgEl.getAttribute('height');\n if (\n !svgEl.getAttribute('viewBox') &&\n width &&\n height &&\n !Number.isNaN(Number(width)) &&\n !Number.isNaN(Number(height))\n ) {\n svgEl.setAttribute('viewBox', `0 0 ${width} ${height}`);\n }\n\n svgEl.removeAttribute('width');\n svgEl.removeAttribute('height');\n\n const allNodes = [svgEl, ...Array.from(svgEl.querySelectorAll('*'))];\n allNodes.forEach(node => {\n const fill = node.getAttribute('fill');\n if (fill && fill !== 'none' && fill !== 'currentColor') {\n node.setAttribute('fill', 'currentColor');\n }\n\n const stroke = node.getAttribute('stroke');\n if (stroke && stroke !== 'none' && stroke !== 'currentColor') {\n node.setAttribute('stroke', 'currentColor');\n }\n\n if (node.hasAttribute('stroke-width')) {\n node.removeAttribute('stroke-width');\n const currentStyle = node.getAttribute('style') ?? '';\n const normalizedStyle = currentStyle.trim();\n const strokeWidthStyle = 'stroke-width: var(--ng-icon__stroke-width, 2)';\n node.setAttribute('style', normalizedStyle ? `${normalizedStyle}; ${strokeWidthStyle}` : strokeWidthStyle);\n }\n });\n\n return svgEl.outerHTML;\n } catch {\n return svg;\n }\n }\n}\n","@if (animatedIcon()) {\n <ng-container [ngComponentOutlet]=\"animatedIcon()\" [ngComponentOutletInputs]=\"animatedIconInputs()\" />\n} @else if (resolvedSvg()) {\n <ng-icon [svg]=\"resolvedSvg()\" [size]=\"normalizedSize()\" [strokeWidth]=\"zStrokeWidth()\" />\n} @else if (!zSvg()) {\n <ng-icon [name]=\"zType()\" [size]=\"normalizedSize()\" [strokeWidth]=\"zStrokeWidth()\" />\n}\n","import { type IconType } from '@ng-icons/core';\nimport type * as saxBoldIcons from '@ng-icons/iconsax/bold';\nimport type * as saxOutlineIcons from '@ng-icons/iconsax/outline';\nimport type * as lucideIcons from '@ng-icons/lucide';\n\ntype ZLucideIcon = Extract<keyof typeof lucideIcons, `lucide${string}`>;\ntype ZSaxIcon = Extract<keyof typeof saxBoldIcons | keyof typeof saxOutlineIcons, `sax${string}`>;\n\nexport const Z_ICONS = {} as const satisfies Record<string, IconType>;\n\nexport type ZIcon = ZLucideIcon | ZSaxIcon;\n","import { HttpClient } from '@angular/common/http';\nimport { type EnvironmentProviders, inject, makeEnvironmentProviders } from '@angular/core';\nimport { provideNgIconLoader, withCaching } from '@ng-icons/core';\nimport { catchError, from, map, type Observable, of, switchMap, tap } from 'rxjs';\nimport { Z_ICON_CACHE_STORE, zIconCacheDb } from './z-icon-cache';\nimport { Z_ICONS } from './z-icons';\n\n/**\n * Normalizes Sax SVG to use currentColor and CSS variable for stroke-width.\n * This allows the icon to inherit color and strokeWidth from ng-icon props.\n */\nfunction normalizeSaxSvg(svg: string): string {\n const cssVar = 'style=\"stroke-width: var(--ng-icon__stroke-width, 2)\"';\n const normalized = svg.replace(/fill=\"#292D32\"/gi, 'fill=\"currentColor\"');\n return normalized.replace(/stroke-width=\"[^\"]*\"/gi, cssVar);\n}\n\n/**\n * Normalizes Lucide SVG to use CSS variable for stroke-width.\n * This allows ng-icon strokeWidth prop to work correctly.\n * Replaces hardcoded stroke-width with var(--ng-icon__stroke-width, 2).\n */\nfunction normalizeLucideSvg(svg: string): string {\n const cssVar = 'style=\"stroke-width: var(--ng-icon__stroke-width, 2)\"';\n return svg.replace(/stroke-width=\"[^\"]*\"/gi, cssVar);\n}\n\nfunction getFallbackIcon(name: string): string {\n const icon = Z_ICONS[name as keyof typeof Z_ICONS];\n if (icon) {\n // console.warn(`[ZIcon] Using bundled fallback for \"${name}\"`);\n return icon;\n }\n return '';\n}\n\n/**\n * Converts ng-icons icon name to Lucide CDN format.\n * Examples:\n * - lucideArrowLeft -> arrow-left\n * - lucideAlertCircle -> alert-circle\n * - lucideTrash2 -> trash-2\n * - lucideGrid3x3 -> grid-3-x-3\n */\nfunction convertLucideIconName(name: string): string {\n return name\n .replace(/^lucide/, '')\n .replace(/([A-Z])/g, '-$1')\n .replace(/(\\d+)/g, '-$1')\n .replace(/(\\d)([a-z])/g, '$1-$2')\n .toLowerCase()\n .replace(/^-/, '')\n .replace(/--+/g, '-');\n}\n\n/**\n * Converts ng-icons Sax icon name to CDN format.\n * Examples:\n * - saxCloudChangeBold -> bold/cloud-change\n * - saxPauseBold -> bold/pause\n * - saxRefreshBold -> bold/refresh\n * - saxHomeOutline -> outline/home\n * - saxUserLinear -> linear/user\n */\nfunction convertIconSaxIconName(name: string): { style: string; iconName: string } | null {\n let iconPart = name.replace(/^sax/, '');\n // Extract style suffix (Bold, Outline, Linear, Bulk, Broken, TwoTone)\n const styleMatch = iconPart.match(/(Bold|Outline|Linear|Bulk|Broken|TwoTone)$/i);\n if (!styleMatch) {\n return null;\n }\n\n const style = styleMatch[1].toLowerCase();\n const styleFolder = style === 'twotone' ? 'twotone' : style;\n iconPart = iconPart.replace(/(Bold|Outline|Linear|Bulk|Broken|TwoTone)$/i, '');\n const iconName = iconPart\n .replace(/([A-Z])/g, '-$1')\n .replace(/(\\d+)/g, '-$1')\n .toLowerCase()\n .replace(/^-/, '')\n .replace(/--+/g, '-');\n\n return { style: styleFolder, iconName };\n}\n\nconst LUCIDE_CDN_URL = 'https://cdn.jsdelivr.net/npm/lucide-static@latest/icons';\nconst SAX_CDN_URL = 'https://cdn.jsdelivr.net/gh/placetopay-org/iconsax-vue@main/src/Base';\n\n/**\n * Provides hybrid icon loading from CDN with fallback to bundled icons:\n * - Primary: Load icons from CDN (Lucide & Iconsax)\n * - Fallback: Use bundled icons from Z_ICONS if CDN fails\n *\n * @example\n * ```typescript\n * // app.config.ts\n * providers: [\n * provideHttpClient(),\n * provideZIconLoader(),\n * ]\n * ```\n */\nfunction loadWithCache(\n name: string,\n url: string,\n http: HttpClient,\n normalizer: (svg: string) => string\n): Observable<string> {\n return from(zIconCacheDb.get<string>(name, { storeName: Z_ICON_CACHE_STORE })).pipe(\n switchMap(cached => {\n if (cached) {\n return of(cached);\n }\n\n return http.get(url, { responseType: 'text' }).pipe(\n map(normalizer),\n tap(svg => {\n void zIconCacheDb.set(name, svg, { storeName: Z_ICON_CACHE_STORE });\n }),\n catchError(error => {\n console.error(`[ZIcon] Failed to load \"${name}\" from ${url}`, error);\n return of(getFallbackIcon(name));\n })\n );\n }),\n catchError(() => of(getFallbackIcon(name)))\n );\n}\n\nexport function provideZIconLoader(): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideNgIconLoader(name => {\n const http = inject(HttpClient);\n if (name.startsWith('sax')) {\n const parsed = convertIconSaxIconName(name);\n if (!parsed) {\n console.warn(`[ZIcon] Invalid Sax icon name: \"${name}\"`);\n return of(getFallbackIcon(name));\n }\n\n const url = `${SAX_CDN_URL}/${parsed.style}/${parsed.iconName}.svg`;\n return loadWithCache(name, url, http, normalizeSaxSvg);\n }\n\n if (name.startsWith('lucide')) {\n const iconName = convertLucideIconName(name);\n const url = `${LUCIDE_CDN_URL}/${iconName}.svg`;\n return loadWithCache(name, url, http, normalizeLucideSvg);\n }\n\n // console.warn(`[ZIcon] Unknown icon: \"${name}\"`);\n return of(getFallbackIcon(name));\n }, withCaching()),\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["NgIcon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shival99-z-ui-components-z-icon.mjs","sources":["../../../../libs/core-ui/components/z-icon/z-animated-icons.ts","../../../../libs/core-ui/components/z-icon/z-icon-cache.ts","../../../../libs/core-ui/components/z-icon/z-icon.variants.ts","../../../../libs/core-ui/components/z-icon/z-icon.component.ts","../../../../libs/core-ui/components/z-icon/z-icon.component.html","../../../../libs/core-ui/components/z-icon/z-icons.ts","../../../../libs/core-ui/components/z-icon/z-icon-loader.provider.ts","../../../../libs/core-ui/components/z-icon/shival99-z-ui-components-z-icon.ts"],"sourcesContent":["import { type Type } from '@angular/core';\nimport * as animatedIcons from 'ng-animated-icons';\n\ntype ZAnimatedIconExport = Extract<keyof typeof animatedIcons, `${string}Icon`>;\ntype ZBrokenAnimatedIconExport = 'AudioLinesIcon';\ntype ZSafeAnimatedIconExport = Exclude<ZAnimatedIconExport, ZBrokenAnimatedIconExport>;\n\ntype ZStripIconSuffix<T extends string> = T extends `${infer Name}Icon` ? Name : T;\n\ntype ZKebabCase<T extends string, Previous extends string = ''> = T extends `${infer Head}${infer Tail}`\n ? Tail extends Uncapitalize<Tail>\n ? Head extends `${number}`\n ? Previous extends '' | '-' | `${number}`\n ? `${Head}${ZKebabCase<Tail, Head>}`\n : `-${Head}${ZKebabCase<Tail, Head>}`\n : `${Lowercase<Head>}${ZKebabCase<Tail, Head>}`\n : `${Lowercase<Head>}-${ZKebabCase<Tail, '-'>}`\n : T;\n\ntype ZAnimatedIconName = ZKebabCase<ZStripIconSuffix<ZSafeAnimatedIconExport>>;\n\nexport type ZAnimatedIcon = ZAnimatedIconName;\n\nconst ANIMATED_ICONS = animatedIcons as unknown as Record<ZAnimatedIconExport, Type<unknown>>;\nconst BROKEN_ANIMATED_ICON_EXPORTS = new Set<ZAnimatedIconExport>(['AudioLinesIcon']);\n\nexport const Z_ANIMATED_ICONS = Object.fromEntries(\n (\n Object.entries(ANIMATED_ICONS).filter(\n ([exportName]) =>\n exportName.endsWith('Icon') && !BROKEN_ANIMATED_ICON_EXPORTS.has(exportName as ZAnimatedIconExport)\n ) as [ZSafeAnimatedIconExport, Type<unknown>][]\n ).map(([exportName, icon]) => [toKebabIconName(exportName), icon])\n) as Record<ZAnimatedIcon, Type<unknown>>;\n\nexport function getZAnimatedIconComponent(iconName: ZAnimatedIcon): Type<unknown> | null {\n return Z_ANIMATED_ICONS[iconName] ?? null;\n}\n\nfunction toKebabIconName(exportName: string): ZAnimatedIcon {\n const iconName = exportName.endsWith('Icon') ? exportName.slice(0, -4) : exportName;\n\n return iconName\n .replace(/([a-z])([0-9])/g, '$1-$2')\n .replace(/([0-9])([A-Z])/g, '$1-$2')\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase() as ZAnimatedIcon;\n}\n","import { isDevMode } from '@angular/core';\nimport { ZIndexDbService } from '@shival99/z-ui/services';\n\nexport const Z_ICON_CACHE_DB_NAME = 'ZIconCache';\nexport const Z_ICON_CACHE_STORE = 'zIcons';\n\nexport const zIconCacheDb = new ZIndexDbService({\n dbName: Z_ICON_CACHE_DB_NAME,\n version: 1,\n stores: [{ name: Z_ICON_CACHE_STORE, encrypt: !isDevMode() }],\n defaultStore: Z_ICON_CACHE_STORE,\n});\n","import { cva, type VariantProps } from 'class-variance-authority';\n\nconst zIconSizeVariants = Object.fromEntries(\n Array.from({ length: 100 - 10 + 1 }, (_, index) => {\n const size = String(10 + index);\n return [size, `size-${size}`];\n })\n);\n\nexport const zIconVariants = cva('', {\n variants: {\n zSize: zIconSizeVariants,\n },\n defaultVariants: {\n zSize: '16',\n },\n});\n\nexport type ZIconSize = `${number}`;\nexport type ZIconVariants = VariantProps<typeof zIconVariants>;\n","import { NgComponentOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n input,\n signal,\n type Type,\n ViewEncapsulation,\n} from '@angular/core';\nimport { NgIconComponent as NgIcon } from '@ng-icons/core';\nimport { zMergeClasses } from '@shival99/z-ui/utils';\nimport type { ClassValue } from 'clsx';\nimport { getZAnimatedIconComponent, type ZAnimatedIcon } from './z-animated-icons';\nimport { Z_ICON_CACHE_STORE, zIconCacheDb } from './z-icon-cache';\nimport { zIconVariants, type ZIconVariants } from './z-icon.variants';\nimport { type ZIcon } from './z-icons';\n\nexport type ZIconAnimationTrigger = 'manual' | 'hover' | 'focus' | 'interaction' | 'always';\n\n@Component({\n selector: 'z-icon, [z-icon]',\n imports: [NgIcon, NgComponentOutlet],\n standalone: true,\n templateUrl: './z-icon.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'zClasses()',\n '[style.width]': 'normalizedSize() + \"px\"',\n '[style.height]': 'normalizedSize() + \"px\"',\n '(mouseenter)': 'setHoverActive(true)',\n '(mouseleave)': 'setHoverActive(false)',\n '(focusin)': 'setFocusActive(true)',\n '(focusout)': 'setFocusActive(false)',\n '(touchstart)': 'setTouchActive(true)',\n '(touchend)': 'setTouchActive(false)',\n },\n})\nexport class ZIconComponent {\n public readonly class = input<ClassValue>('');\n public readonly zType = input<ZIcon>();\n public readonly zAnimatedType = input<ZAnimatedIcon>();\n public readonly zAnimate = input(false);\n public readonly zAnimationTrigger = input<ZIconAnimationTrigger>('manual');\n public readonly zSize = input<ZIconVariants['zSize']>('16');\n public readonly zStrokeWidth = input<number>(2);\n public readonly zSvg = input<string>('');\n protected readonly resolvedSvg = signal('');\n protected readonly isHoverActive = signal(false);\n protected readonly isFocusActive = signal(false);\n protected readonly isTouchActive = signal(false);\n protected readonly normalizedSize = computed(() => {\n const size = this.zSize();\n if (size === null || size === undefined || size === '') {\n return '16';\n }\n\n return String(size);\n });\n\n private readonly _svgFetchError = signal<string>('');\n\n protected readonly zClasses = computed(() =>\n zMergeClasses(\n zIconVariants({ zSize: this.zSize() }),\n this.class(),\n this.zStrokeWidth() === 0 ? 'stroke-none' : '',\n 'inline-flex shrink-0'\n )\n );\n\n protected readonly animatedIcon = computed<Type<unknown> | null>(() => {\n const animatedType = this.zAnimatedType();\n if (!animatedType) {\n return null;\n }\n\n return getZAnimatedIconComponent(animatedType);\n });\n\n protected readonly animatedIconInputs = computed<Record<string, unknown>>(() => ({\n animate: this.shouldAnimate(),\n color: 'currentColor',\n size: Number(this.normalizedSize()),\n strokeWidth: this.zStrokeWidth(),\n }));\n\n protected readonly shouldAnimate = computed(() => {\n const trigger = this.zAnimationTrigger();\n if (trigger === 'always' || this.zAnimate()) {\n return true;\n }\n\n if (trigger === 'hover') {\n return this.isHoverActive() || this.isTouchActive();\n }\n\n if (trigger === 'focus') {\n return this.isFocusActive();\n }\n\n if (trigger === 'interaction') {\n return this.isHoverActive() || this.isFocusActive() || this.isTouchActive();\n }\n\n return false;\n });\n\n constructor() {\n effect(onCleanup => {\n const svgInput = this.zSvg().trim();\n if (!svgInput) {\n this.resolvedSvg.set('');\n this._svgFetchError.set('');\n return;\n }\n\n if (this._isRawSvg(svgInput)) {\n this.resolvedSvg.set(this._normalizeCustomSvg(svgInput));\n this._svgFetchError.set('');\n return;\n }\n\n if (!this._isSvgPath(svgInput)) {\n this.resolvedSvg.set('');\n this._svgFetchError.set('Unsupported SVG input format.');\n return;\n }\n\n const controller = new AbortController();\n onCleanup(() => controller.abort());\n\n const cacheKey = `zsvg:path:${svgInput}`;\n void zIconCacheDb\n .get<string>(cacheKey, { storeName: Z_ICON_CACHE_STORE })\n .then(cachedSvg => {\n if (controller.signal.aborted) {\n return null;\n }\n if (cachedSvg && this._isRawSvg(cachedSvg.trim())) {\n this.resolvedSvg.set(this._normalizeCustomSvg(cachedSvg));\n this._svgFetchError.set('');\n return null;\n }\n\n return fetch(svgInput, { signal: controller.signal }).then(response => {\n if (!response.ok) {\n throw new Error(`Failed to fetch SVG from \"${svgInput}\"`);\n }\n return response.text();\n });\n })\n .then(svgContent => {\n if (controller.signal.aborted || !svgContent) {\n return;\n }\n\n if (!this._isRawSvg(svgContent.trim())) {\n throw new Error(`Invalid SVG content loaded from \"${svgInput}\"`);\n }\n\n const normalizedSvg = this._normalizeCustomSvg(svgContent);\n this.resolvedSvg.set(normalizedSvg);\n this._svgFetchError.set('');\n void zIconCacheDb.set(cacheKey, normalizedSvg, { storeName: Z_ICON_CACHE_STORE }).catch(console.error);\n })\n .catch(error => {\n if (controller.signal.aborted) {\n return;\n }\n console.error('[z-icon] Failed to load zSvg path:', error);\n this.resolvedSvg.set('');\n this._svgFetchError.set('Unable to load SVG path.');\n });\n });\n }\n\n private _isRawSvg(value: string): boolean {\n return value.startsWith('<svg');\n }\n\n protected setHoverActive(isActive: boolean): void {\n this.isHoverActive.set(isActive);\n }\n\n protected setFocusActive(isActive: boolean): void {\n this.isFocusActive.set(isActive);\n }\n\n protected setTouchActive(isActive: boolean): void {\n this.isTouchActive.set(isActive);\n }\n\n private _isSvgPath(value: string): boolean {\n return value.endsWith('.svg') || value.includes('/');\n }\n\n private _normalizeCustomSvg(svg: string): string {\n try {\n const parser = new DOMParser();\n const doc = parser.parseFromString(svg, 'image/svg+xml');\n const svgEl = doc.documentElement;\n if (svgEl.tagName.toLowerCase() !== 'svg') {\n return svg;\n }\n\n const width = svgEl.getAttribute('width');\n const height = svgEl.getAttribute('height');\n if (\n !svgEl.getAttribute('viewBox') &&\n width &&\n height &&\n !Number.isNaN(Number(width)) &&\n !Number.isNaN(Number(height))\n ) {\n svgEl.setAttribute('viewBox', `0 0 ${width} ${height}`);\n }\n\n svgEl.removeAttribute('width');\n svgEl.removeAttribute('height');\n\n const allNodes = [svgEl, ...Array.from(svgEl.querySelectorAll('*'))];\n allNodes.forEach(node => {\n const fill = node.getAttribute('fill');\n if (fill && fill !== 'none' && fill !== 'currentColor') {\n node.setAttribute('fill', 'currentColor');\n }\n\n const stroke = node.getAttribute('stroke');\n if (stroke && stroke !== 'none' && stroke !== 'currentColor') {\n node.setAttribute('stroke', 'currentColor');\n }\n\n if (node.hasAttribute('stroke-width')) {\n node.removeAttribute('stroke-width');\n const currentStyle = node.getAttribute('style') ?? '';\n const normalizedStyle = currentStyle.trim();\n const strokeWidthStyle = 'stroke-width: var(--ng-icon__stroke-width, 2)';\n node.setAttribute('style', normalizedStyle ? `${normalizedStyle}; ${strokeWidthStyle}` : strokeWidthStyle);\n }\n });\n\n return svgEl.outerHTML;\n } catch {\n return svg;\n }\n }\n}\n","@if (animatedIcon()) {\n <ng-container [ngComponentOutlet]=\"animatedIcon()\" [ngComponentOutletInputs]=\"animatedIconInputs()\" />\n} @else if (resolvedSvg()) {\n <ng-icon [svg]=\"resolvedSvg()\" [size]=\"normalizedSize()\" [strokeWidth]=\"zStrokeWidth()\" />\n} @else if (!zSvg()) {\n <ng-icon [name]=\"zType()\" [size]=\"normalizedSize()\" [strokeWidth]=\"zStrokeWidth()\" />\n}\n","import type * as hugeIcons from '@hugeicons/core-free-icons';\nimport { type IconType } from '@ng-icons/core';\nimport type * as saxBoldIcons from '@ng-icons/iconsax/bold';\nimport type * as saxOutlineIcons from '@ng-icons/iconsax/outline';\nimport type * as lucideIcons from '@ng-icons/lucide';\nimport type * as phosphorBoldIcons from '@ng-icons/phosphor-icons/bold';\nimport type * as phosphorDuotoneIcons from '@ng-icons/phosphor-icons/duotone';\nimport type * as phosphorFillIcons from '@ng-icons/phosphor-icons/fill';\nimport type * as phosphorLightIcons from '@ng-icons/phosphor-icons/light';\nimport type * as phosphorRegularIcons from '@ng-icons/phosphor-icons/regular';\nimport type * as phosphorThinIcons from '@ng-icons/phosphor-icons/thin';\n\ntype ZLucideIcon = Extract<keyof typeof lucideIcons, `lucide${string}`>;\ntype ZSaxIcon = Extract<keyof typeof saxBoldIcons | keyof typeof saxOutlineIcons, `sax${string}`>;\ntype ZPhosphorIcon = Extract<\n | keyof typeof phosphorRegularIcons\n | keyof typeof phosphorBoldIcons\n | keyof typeof phosphorFillIcons\n | keyof typeof phosphorLightIcons\n | keyof typeof phosphorThinIcons\n | keyof typeof phosphorDuotoneIcons,\n `phosphor${string}`\n>;\n\n/**\n * HugeIcons exports are PascalCase with an `Icon` suffix (e.g. `HeartIcon`,\n * `Home01Icon`). We re-expose them with a `huge` prefix to stay consistent\n * with the other families (e.g. `hugeHeart`, `hugeHome01`).\n */\ntype ZHugeIcon = {\n [K in keyof typeof hugeIcons as K extends `${infer Name}Icon` ? `huge${Name}` : never]: true;\n} extends infer M\n ? Extract<keyof M, `huge${string}`>\n : never;\n\nexport const Z_ICONS = {} as const satisfies Record<string, IconType>;\n\nexport type ZIcon = ZLucideIcon | ZSaxIcon | ZPhosphorIcon | ZHugeIcon;\n","import { HttpClient } from '@angular/common/http';\nimport { type EnvironmentProviders, inject, makeEnvironmentProviders } from '@angular/core';\nimport { provideNgIconLoader, withCaching } from '@ng-icons/core';\nimport { catchError, from, map, type Observable, of, switchMap, tap } from 'rxjs';\nimport { Z_ICON_CACHE_STORE, zIconCacheDb } from './z-icon-cache';\nimport { Z_ICONS } from './z-icons';\n\n/**\n * Normalizes Sax SVG to use currentColor and CSS variable for stroke-width.\n * This allows the icon to inherit color and strokeWidth from ng-icon props.\n */\nfunction normalizeSaxSvg(svg: string): string {\n const cssVar = 'style=\"stroke-width: var(--ng-icon__stroke-width, 2)\"';\n const normalized = svg.replace(/fill=\"#292D32\"/gi, 'fill=\"currentColor\"');\n return normalized.replace(/stroke-width=\"[^\"]*\"/gi, cssVar);\n}\n\n/**\n * Normalizes Lucide SVG to use CSS variable for stroke-width.\n * This allows ng-icon strokeWidth prop to work correctly.\n * Replaces hardcoded stroke-width with var(--ng-icon__stroke-width, 2).\n */\nfunction normalizeLucideSvg(svg: string): string {\n const cssVar = 'style=\"stroke-width: var(--ng-icon__stroke-width, 2)\"';\n return svg.replace(/stroke-width=\"[^\"]*\"/gi, cssVar);\n}\n\n/**\n * Phosphor SVGs already ship with fill=\"currentColor\" and no stroke-width,\n * so no normalization is required. Kept as an explicit passthrough for parity\n * with the other icon families.\n */\nfunction normalizePhosphorSvg(svg: string): string {\n return svg;\n}\n\n/**\n * HugeIcons ships each icon as an ESM module exporting a path-array\n * (e.g. `const HeartIcon = [[\"path\", { d: \"...\", stroke: \"currentColor\", strokeWidth: \"1.5\" }]]`),\n * not a ready-made SVG. This converts that module source into an `<svg>` string\n * suitable for ng-icon, mapping camelCase attributes to kebab-case and wiring\n * stroke-width to the ng-icon CSS variable.\n */\nfunction normalizeHugeIconModule(moduleSource: string): string {\n const elements: string[] = [];\n const elementRegex = /\\[\\s*\"([a-zA-Z]+)\"\\s*,\\s*\\{([^}]*)\\}\\s*\\]/g;\n let match: RegExpExecArray | null;\n\n while ((match = elementRegex.exec(moduleSource)) !== null) {\n const tag = match[1];\n const attrsBody = match[2];\n const attrs: string[] = [];\n const attrRegex = /([a-zA-Z]+)\\s*:\\s*\"([^\"]*)\"/g;\n let attrMatch: RegExpExecArray | null;\n\n while ((attrMatch = attrRegex.exec(attrsBody)) !== null) {\n const rawKey = attrMatch[1];\n const value = attrMatch[2];\n if (rawKey === 'key') {\n continue;\n }\n if (rawKey === 'strokeWidth') {\n attrs.push(`style=\"stroke-width:var(--ng-icon__stroke-width, ${value})\"`);\n continue;\n }\n const attrName = rawKey.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n attrs.push(`${attrName}=\"${value}\"`);\n }\n\n elements.push(`<${tag} ${attrs.join(' ')}></${tag}>`);\n }\n\n if (elements.length === 0) {\n return '';\n }\n\n return `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\">${elements.join('')}</svg>`;\n}\n\nfunction getFallbackIcon(name: string): string {\n const icon = Z_ICONS[name as keyof typeof Z_ICONS];\n if (icon) {\n // console.warn(`[ZIcon] Using bundled fallback for \"${name}\"`);\n return icon;\n }\n return '';\n}\n\n/**\n * Converts ng-icons icon name to Lucide CDN format.\n * Examples:\n * - lucideArrowLeft -> arrow-left\n * - lucideAlertCircle -> alert-circle\n * - lucideTrash2 -> trash-2\n * - lucideGrid3x3 -> grid-3-x-3\n */\nfunction convertLucideIconName(name: string): string {\n return name\n .replace(/^lucide/, '')\n .replace(/([A-Z])/g, '-$1')\n .replace(/(\\d+)/g, '-$1')\n .replace(/(\\d)([a-z])/g, '$1-$2')\n .toLowerCase()\n .replace(/^-/, '')\n .replace(/--+/g, '-');\n}\n\n/**\n * Converts ng-icons Sax icon name to CDN format.\n * Examples:\n * - saxCloudChangeBold -> bold/cloud-change\n * - saxPauseBold -> bold/pause\n * - saxRefreshBold -> bold/refresh\n * - saxHomeOutline -> outline/home\n * - saxUserLinear -> linear/user\n */\nfunction convertIconSaxIconName(name: string): { style: string; iconName: string } | null {\n let iconPart = name.replace(/^sax/, '');\n // Extract style suffix (Bold, Outline, Linear, Bulk, Broken, TwoTone)\n const styleMatch = iconPart.match(/(Bold|Outline|Linear|Bulk|Broken|TwoTone)$/i);\n if (!styleMatch) {\n return null;\n }\n\n const style = styleMatch[1].toLowerCase();\n const styleFolder = style === 'twotone' ? 'twotone' : style;\n iconPart = iconPart.replace(/(Bold|Outline|Linear|Bulk|Broken|TwoTone)$/i, '');\n const iconName = iconPart\n .replace(/([A-Z])/g, '-$1')\n .replace(/(\\d+)/g, '-$1')\n .toLowerCase()\n .replace(/^-/, '')\n .replace(/--+/g, '-');\n\n return { style: styleFolder, iconName };\n}\n\n/**\n * Converts ng-icons Phosphor icon name to CDN format.\n * Phosphor weights map to folders, and every weight except \"regular\" carries a\n * file-name suffix (e.g. heart-bold.svg), while regular is just heart.svg.\n * Examples:\n * - phosphorHeart -> regular/heart\n * - phosphorHeartBold -> bold/heart-bold\n * - phosphorHeartFill -> fill/heart-fill\n * - phosphorHeartDuotone -> duotone/heart-duotone\n * - phosphorAddressBookTabsLight -> light/address-book-tabs-light\n */\nfunction convertPhosphorIconName(name: string): { weight: string; iconName: string } {\n let iconPart = name.replace(/^phosphor/, '');\n const weightMatch = iconPart.match(/(Bold|Fill|Light|Thin|Duotone)$/);\n const weight = weightMatch ? weightMatch[1].toLowerCase() : 'regular';\n if (weightMatch) {\n iconPart = iconPart.replace(/(Bold|Fill|Light|Thin|Duotone)$/, '');\n }\n\n const kebab = iconPart\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')\n .toLowerCase()\n .replace(/^-/, '')\n .replace(/--+/g, '-');\n\n const iconName = weight === 'regular' ? kebab : `${kebab}-${weight}`;\n\n return { weight, iconName };\n}\n\n/**\n * Converts ng-icons-style Huge icon name to the @hugeicons/core-free-icons\n * CDN module name. We expose icons with a `huge` prefix over the original\n * PascalCase export name, so we just strip the prefix and append `Icon`.\n * Examples:\n * - hugeHeart -> HeartIcon\n * - hugeHome01 -> Home01Icon\n * - hugeFirstBracketCircle -> FirstBracketCircleIcon\n */\nfunction convertHugeIconName(name: string): string {\n return `${name.replace(/^huge/, '')}Icon`;\n}\n\nconst LUCIDE_CDN_URL = 'https://cdn.jsdelivr.net/npm/lucide-static@latest/icons';\nconst SAX_CDN_URL = 'https://cdn.jsdelivr.net/gh/placetopay-org/iconsax-vue@main/src/Base';\nconst PHOSPHOR_CDN_URL = 'https://cdn.jsdelivr.net/npm/@phosphor-icons/core@latest/assets';\nconst HUGE_CDN_URL = 'https://cdn.jsdelivr.net/npm/@hugeicons/core-free-icons@4.2.1/dist/esm';\n\n/**\n * Provides hybrid icon loading from CDN with fallback to bundled icons:\n * - Primary: Load icons from CDN (Lucide & Iconsax)\n * - Fallback: Use bundled icons from Z_ICONS if CDN fails\n *\n * @example\n * ```typescript\n * // app.config.ts\n * providers: [\n * provideHttpClient(),\n * provideZIconLoader(),\n * ]\n * ```\n */\nfunction loadWithCache(\n name: string,\n url: string,\n http: HttpClient,\n normalizer: (svg: string) => string\n): Observable<string> {\n return from(zIconCacheDb.get<string>(name, { storeName: Z_ICON_CACHE_STORE })).pipe(\n switchMap(cached => {\n if (cached) {\n return of(cached);\n }\n\n return http.get(url, { responseType: 'text' }).pipe(\n map(normalizer),\n tap(svg => {\n void zIconCacheDb.set(name, svg, { storeName: Z_ICON_CACHE_STORE });\n }),\n catchError(error => {\n console.error(`[ZIcon] Failed to load \"${name}\" from ${url}`, error);\n return of(getFallbackIcon(name));\n })\n );\n }),\n catchError(() => of(getFallbackIcon(name)))\n );\n}\n\nexport function provideZIconLoader(): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideNgIconLoader(name => {\n const http = inject(HttpClient);\n if (name.startsWith('sax')) {\n const parsed = convertIconSaxIconName(name);\n if (!parsed) {\n console.warn(`[ZIcon] Invalid Sax icon name: \"${name}\"`);\n return of(getFallbackIcon(name));\n }\n\n const url = `${SAX_CDN_URL}/${parsed.style}/${parsed.iconName}.svg`;\n return loadWithCache(name, url, http, normalizeSaxSvg);\n }\n\n if (name.startsWith('lucide')) {\n const iconName = convertLucideIconName(name);\n const url = `${LUCIDE_CDN_URL}/${iconName}.svg`;\n return loadWithCache(name, url, http, normalizeLucideSvg);\n }\n\n if (name.startsWith('phosphor')) {\n const { weight, iconName } = convertPhosphorIconName(name);\n const url = `${PHOSPHOR_CDN_URL}/${weight}/${iconName}.svg`;\n return loadWithCache(name, url, http, normalizePhosphorSvg);\n }\n\n if (name.startsWith('huge')) {\n const moduleName = convertHugeIconName(name);\n const url = `${HUGE_CDN_URL}/${moduleName}.js`;\n return loadWithCache(name, url, http, normalizeHugeIconModule);\n }\n\n // console.warn(`[ZIcon] Unknown icon: \"${name}\"`);\n return of(getFallbackIcon(name));\n }, withCaching()),\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["NgIcon"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shival99/z-ui",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.7",
|
|
4
4
|
"description": "Z-UI: Modern Angular UI Component Library - A comprehensive, high-performance design system built with Angular 20+, featuring 40+ customizable components with dark mode, accessibility, and enterprise-ready features.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"z-ui-init": "./scripts/z-init-project.mjs"
|
|
7
|
+
},
|
|
5
8
|
"keywords": [
|
|
6
9
|
"angular",
|
|
7
10
|
"angular-ui",
|
|
@@ -46,6 +49,7 @@
|
|
|
46
49
|
"@ng-icons/core": ">=33.0.0",
|
|
47
50
|
"@ng-icons/iconsax": ">=33.0.0",
|
|
48
51
|
"@ng-icons/lucide": ">=33.0.0",
|
|
52
|
+
"@ng-icons/phosphor-icons": ">=33.0.0",
|
|
49
53
|
"@ngx-translate/core": ">=17.0.0",
|
|
50
54
|
"@shival99/angular-virtual": ">=4.0.10",
|
|
51
55
|
"@shival99/ngx-sonner": ">=3.0.0",
|
|
@@ -73,9 +77,9 @@
|
|
|
73
77
|
"rxjs": ">=7.8.0",
|
|
74
78
|
"tailwind-merge": ">=3.0.0",
|
|
75
79
|
"xlsx": "^0.18.5",
|
|
76
|
-
"@tiptap/extension-bubble-menu": "3.
|
|
77
|
-
"@tiptap/extension-text-style": "3.
|
|
78
|
-
"@tiptap/pm": "
|
|
80
|
+
"@tiptap/extension-bubble-menu": ">=3.0.0",
|
|
81
|
+
"@tiptap/extension-text-style": ">=3.0.0",
|
|
82
|
+
"@tiptap/pm": ">=3.0.0",
|
|
79
83
|
"tiptap-extension-resize-image": "^1.4.0"
|
|
80
84
|
},
|
|
81
85
|
"peerDependenciesMeta": {
|
|
@@ -0,0 +1,645 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* z-init-project — bootstrap an Angular project to consume @shival99/z-ui.
|
|
4
|
+
*
|
|
5
|
+
* Run this from the ROOT of the target Angular project (the one you want to set
|
|
6
|
+
* up), NOT from inside z-ui. It will:
|
|
7
|
+
* 1. Detect whether the target is an Nx monorepo (project.json) or a single
|
|
8
|
+
* Angular app (angular.json), and which project to configure.
|
|
9
|
+
* 2. Install the required dependencies (z-ui, Tailwind v4, PostCSS, icons).
|
|
10
|
+
* 3. Wire up Tailwind v4 + the chosen z-ui theme into the build styles array.
|
|
11
|
+
* 4. Create .postcssrc.json.
|
|
12
|
+
* 5. Inject the Be Vietnam Pro + Inter Tight Google Fonts <link> into index.html.
|
|
13
|
+
* 6. Create/patch src styles (font-sans variable).
|
|
14
|
+
* 7. Patch app.config.ts with z-ui providers (icon loader, toast, translate, theme).
|
|
15
|
+
* 8. Patch the root standalone component to preloadTheme(<theme>) on init.
|
|
16
|
+
*
|
|
17
|
+
* Usage:
|
|
18
|
+
* node z-init-project.mjs # interactive
|
|
19
|
+
* node z-init-project.mjs --theme neutral --project my-app --yes
|
|
20
|
+
* node z-init-project.mjs --dry-run # show what would change, write nothing
|
|
21
|
+
*
|
|
22
|
+
* Flags:
|
|
23
|
+
* --theme <name> one of the available themes (default: neutral)
|
|
24
|
+
* --project <name> project name (monorepo only; defaults to the single/first app)
|
|
25
|
+
* --no-install skip dependency installation
|
|
26
|
+
* --yes, -y accept defaults, no prompts
|
|
27
|
+
* --dry-run print planned changes without writing
|
|
28
|
+
* --cwd <path> target project root (default: current directory)
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import { execSync } from 'node:child_process';
|
|
32
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
33
|
+
import { createInterface } from 'node:readline';
|
|
34
|
+
import { dirname, join, relative, resolve } from 'node:path';
|
|
35
|
+
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// Constants
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
|
|
40
|
+
const Z_UI_PKG = '@shival99/z-ui';
|
|
41
|
+
|
|
42
|
+
const AVAILABLE_THEMES = ['neutral', 'gray', 'slate', 'stone', 'zinc', 'green', 'orange', 'violet', 'hospital'];
|
|
43
|
+
|
|
44
|
+
const DEFAULT_THEME = 'neutral';
|
|
45
|
+
|
|
46
|
+
/** Runtime deps a consuming app needs. Versions track attendance-pull's setup. */
|
|
47
|
+
const DEPENDENCIES = [
|
|
48
|
+
`${Z_UI_PKG}@latest`,
|
|
49
|
+
'tailwindcss@^4.3.0',
|
|
50
|
+
'@tailwindcss/postcss@^4.3.0',
|
|
51
|
+
'postcss@^8.5.15',
|
|
52
|
+
'autoprefixer@^10.5.0',
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
const FONT_LINK_HREF =
|
|
56
|
+
'https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Inter+Tight:ital,wght@0,100..900;1,100..900&display=swap';
|
|
57
|
+
|
|
58
|
+
const FONT_LINK_TAG = ` <link\n href="${FONT_LINK_HREF}"\n rel="stylesheet"\n />`;
|
|
59
|
+
|
|
60
|
+
const STYLES_CSS_CONTENT = `:root {
|
|
61
|
+
--font-sans: 'Be Vietnam Pro', 'Inter Tight', 'IBM Plex Sans', system-ui, -apple-system, sans-serif;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
* {
|
|
65
|
+
font-family: var(--font-sans) !important;
|
|
66
|
+
}
|
|
67
|
+
`;
|
|
68
|
+
|
|
69
|
+
const POSTCSS_CONTENT = `${JSON.stringify({ plugins: { '@tailwindcss/postcss': {} } }, null, 2)}\n`;
|
|
70
|
+
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Tiny CLI helpers
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
|
|
75
|
+
const C = {
|
|
76
|
+
reset: '\x1b[0m',
|
|
77
|
+
dim: '\x1b[2m',
|
|
78
|
+
bold: '\x1b[1m',
|
|
79
|
+
green: '\x1b[32m',
|
|
80
|
+
yellow: '\x1b[33m',
|
|
81
|
+
red: '\x1b[31m',
|
|
82
|
+
cyan: '\x1b[36m',
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const log = {
|
|
86
|
+
step: m => console.log(`${C.cyan}▸${C.reset} ${m}`),
|
|
87
|
+
ok: m => console.log(`${C.green}✓${C.reset} ${m}`),
|
|
88
|
+
warn: m => console.log(`${C.yellow}!${C.reset} ${m}`),
|
|
89
|
+
err: m => console.error(`${C.red}✗${C.reset} ${m}`),
|
|
90
|
+
info: m => console.log(`${C.dim}${m}${C.reset}`),
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
function parseArgs(argv) {
|
|
94
|
+
const args = { _: [] };
|
|
95
|
+
for (let i = 0; i < argv.length; i++) {
|
|
96
|
+
const a = argv[i];
|
|
97
|
+
if (a === '--yes' || a === '-y') args.yes = true;
|
|
98
|
+
else if (a === '--dry-run') args.dryRun = true;
|
|
99
|
+
else if (a === '--no-install') args.noInstall = true;
|
|
100
|
+
else if (a === '--theme') args.theme = argv[++i];
|
|
101
|
+
else if (a === '--project') args.project = argv[++i];
|
|
102
|
+
else if (a === '--cwd') args.cwd = argv[++i];
|
|
103
|
+
else if (a === '--help' || a === '-h') args.help = true;
|
|
104
|
+
else args._.push(a);
|
|
105
|
+
}
|
|
106
|
+
return args;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function printHelp() {
|
|
110
|
+
console.log(`${C.bold}z-ui-init${C.reset} — set up an Angular project to consume ${Z_UI_PKG}
|
|
111
|
+
|
|
112
|
+
${C.bold}Usage${C.reset}
|
|
113
|
+
npx ${Z_UI_PKG} z-ui-init [options] ${C.dim}# in your project root${C.reset}
|
|
114
|
+
z-ui-init [options]
|
|
115
|
+
|
|
116
|
+
${C.bold}Options${C.reset}
|
|
117
|
+
--theme <name> theme to wire in (default: ${DEFAULT_THEME})
|
|
118
|
+
${C.dim}${AVAILABLE_THEMES.join(', ')}${C.reset}
|
|
119
|
+
--project <name> project to configure (monorepo; defaults to the single/first app)
|
|
120
|
+
--cwd <path> target project root (default: current directory)
|
|
121
|
+
--no-install skip dependency installation
|
|
122
|
+
--yes, -y accept defaults, no prompts
|
|
123
|
+
--dry-run print planned changes without writing
|
|
124
|
+
--help, -h show this help`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function prompt(question) {
|
|
128
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
129
|
+
return new Promise(res =>
|
|
130
|
+
rl.question(question, ans => {
|
|
131
|
+
rl.close();
|
|
132
|
+
res(ans.trim());
|
|
133
|
+
})
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function chooseTheme(yes, preselected) {
|
|
138
|
+
if (preselected) {
|
|
139
|
+
if (!AVAILABLE_THEMES.includes(preselected)) {
|
|
140
|
+
log.err(`Unknown theme "${preselected}". Available: ${AVAILABLE_THEMES.join(', ')}`);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
return preselected;
|
|
144
|
+
}
|
|
145
|
+
if (yes) return DEFAULT_THEME;
|
|
146
|
+
|
|
147
|
+
console.log(`\n${C.bold}Choose a theme:${C.reset}`);
|
|
148
|
+
AVAILABLE_THEMES.forEach((t, i) => {
|
|
149
|
+
const marker = t === DEFAULT_THEME ? `${C.dim}(default)${C.reset}` : '';
|
|
150
|
+
console.log(` ${i + 1}) ${t} ${marker}`);
|
|
151
|
+
});
|
|
152
|
+
const ans = await prompt(`Theme [1-${AVAILABLE_THEMES.length} or name, Enter=${DEFAULT_THEME}]: `);
|
|
153
|
+
if (!ans) return DEFAULT_THEME;
|
|
154
|
+
const byIndex = AVAILABLE_THEMES[Number(ans) - 1];
|
|
155
|
+
if (byIndex) return byIndex;
|
|
156
|
+
if (AVAILABLE_THEMES.includes(ans)) return ans;
|
|
157
|
+
log.warn(`"${ans}" not recognized, falling back to ${DEFAULT_THEME}.`);
|
|
158
|
+
return DEFAULT_THEME;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
// File utilities
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
|
|
165
|
+
let DRY_RUN = false;
|
|
166
|
+
|
|
167
|
+
function read(file) {
|
|
168
|
+
return readFileSync(file, 'utf8');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function write(file, content) {
|
|
172
|
+
if (DRY_RUN) {
|
|
173
|
+
log.info(`[dry-run] would write ${file}`);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
177
|
+
writeFileSync(file, content);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function readJson(file) {
|
|
181
|
+
return JSON.parse(read(file));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function writeJson(file, obj) {
|
|
185
|
+
write(file, `${JSON.stringify(obj, null, 2)}\n`);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Find the first existing path among candidates. */
|
|
189
|
+
function firstExisting(paths) {
|
|
190
|
+
return paths.find(p => existsSync(p)) ?? null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** Absolute filesystem path inside the project's source root. */
|
|
194
|
+
function absSrc(ws, ...parts) {
|
|
195
|
+
return join(ws.root, ws.sourceRoot, ...parts);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
// Workspace detection
|
|
200
|
+
// ---------------------------------------------------------------------------
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Resolve the target project: its name, the config file that owns its build
|
|
204
|
+
* target (angular.json or project.json), and the source root + index/styles.
|
|
205
|
+
*/
|
|
206
|
+
function detectWorkspace(root, requestedProject) {
|
|
207
|
+
const nxJson = join(root, 'nx.json');
|
|
208
|
+
const angularJson = join(root, 'angular.json');
|
|
209
|
+
const isNx = existsSync(nxJson);
|
|
210
|
+
|
|
211
|
+
if (isNx) {
|
|
212
|
+
log.step('Detected Nx monorepo (nx.json present).');
|
|
213
|
+
const projects = discoverNxProjects(root);
|
|
214
|
+
if (projects.length === 0) {
|
|
215
|
+
log.err('No project.json with an Angular application target found under apps/* or libs/*.');
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
let project = projects[0];
|
|
219
|
+
if (requestedProject) {
|
|
220
|
+
const found = projects.find(p => p.name === requestedProject);
|
|
221
|
+
if (!found) {
|
|
222
|
+
log.err(`Project "${requestedProject}" not found. Available: ${projects.map(p => p.name).join(', ')}`);
|
|
223
|
+
process.exit(1);
|
|
224
|
+
}
|
|
225
|
+
project = found;
|
|
226
|
+
} else if (projects.length > 1) {
|
|
227
|
+
log.warn(
|
|
228
|
+
`Multiple projects found, using "${project.name}". Pass --project to pick another: ${projects
|
|
229
|
+
.map(p => p.name)
|
|
230
|
+
.join(', ')}`
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
return { kind: 'nx', root, ...project };
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (existsSync(angularJson)) {
|
|
237
|
+
log.step('Detected single Angular workspace (angular.json present).');
|
|
238
|
+
const cfg = readJson(angularJson);
|
|
239
|
+
const names = Object.keys(cfg.projects || {});
|
|
240
|
+
const appNames = names.filter(n => cfg.projects[n].projectType !== 'library');
|
|
241
|
+
if (appNames.length === 0) {
|
|
242
|
+
log.err('No application project found in angular.json.');
|
|
243
|
+
process.exit(1);
|
|
244
|
+
}
|
|
245
|
+
const name = requestedProject || cfg.defaultProject || appNames[0];
|
|
246
|
+
if (!cfg.projects[name]) {
|
|
247
|
+
log.err(`Project "${name}" not found in angular.json. Available: ${names.join(', ')}`);
|
|
248
|
+
process.exit(1);
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
kind: 'angular',
|
|
252
|
+
root,
|
|
253
|
+
name,
|
|
254
|
+
configFile: angularJson,
|
|
255
|
+
sourceRoot: cfg.projects[name].sourceRoot || 'src',
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
log.err('Neither angular.json nor nx.json found. Run this from an Angular project root.');
|
|
260
|
+
process.exit(1);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function discoverNxProjects(root) {
|
|
264
|
+
const out = [];
|
|
265
|
+
for (const baseName of ['apps', 'libs']) {
|
|
266
|
+
const base = join(root, baseName);
|
|
267
|
+
if (!existsSync(base)) continue;
|
|
268
|
+
for (const entry of readdirSync(base)) {
|
|
269
|
+
const projDir = join(base, entry);
|
|
270
|
+
if (!statSync(projDir).isDirectory()) continue;
|
|
271
|
+
const projectJson = join(projDir, 'project.json');
|
|
272
|
+
if (!existsSync(projectJson)) continue;
|
|
273
|
+
const cfg = readJson(projectJson);
|
|
274
|
+
const target = findApplicationTarget(cfg);
|
|
275
|
+
if (!target) continue;
|
|
276
|
+
out.push({
|
|
277
|
+
name: cfg.name || entry,
|
|
278
|
+
configFile: projectJson,
|
|
279
|
+
// Relative to workspace root, e.g. "apps/my-app/src".
|
|
280
|
+
sourceRoot: cfg.sourceRoot || relative(root, join(projDir, 'src')),
|
|
281
|
+
buildTargetKey: target,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return out;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/** Return the name of the build target that uses the Angular application builder. */
|
|
289
|
+
function findApplicationTarget(projectCfg) {
|
|
290
|
+
const targets = projectCfg.targets || {};
|
|
291
|
+
for (const [key, t] of Object.entries(targets)) {
|
|
292
|
+
const exec = t.executor || t.builder || '';
|
|
293
|
+
if (exec.includes('@angular/build:application') || exec.includes('@angular-devkit/build-angular')) {
|
|
294
|
+
return key;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return targets.build ? 'build' : null;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// ---------------------------------------------------------------------------
|
|
301
|
+
// Setup steps
|
|
302
|
+
// ---------------------------------------------------------------------------
|
|
303
|
+
|
|
304
|
+
function installDeps(root) {
|
|
305
|
+
const pm = detectPackageManager(root);
|
|
306
|
+
const addCmd = { pnpm: 'pnpm add', npm: 'npm install', yarn: 'yarn add', bun: 'bun add' }[pm];
|
|
307
|
+
const cmd = `${addCmd} ${DEPENDENCIES.join(' ')}`;
|
|
308
|
+
log.step(`Installing dependencies with ${pm}…`);
|
|
309
|
+
log.info(cmd);
|
|
310
|
+
if (DRY_RUN) {
|
|
311
|
+
log.info('[dry-run] skipping install');
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
execSync(cmd, { cwd: root, stdio: 'inherit' });
|
|
315
|
+
log.ok('Dependencies installed.');
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function detectPackageManager(root) {
|
|
319
|
+
if (existsSync(join(root, 'pnpm-lock.yaml'))) return 'pnpm';
|
|
320
|
+
if (existsSync(join(root, 'yarn.lock'))) return 'yarn';
|
|
321
|
+
if (existsSync(join(root, 'bun.lockb'))) return 'bun';
|
|
322
|
+
return 'npm';
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/** Inject the z-ui style entries (tailwind + chosen theme) into the build target. */
|
|
326
|
+
function patchBuildStyles(ws, theme) {
|
|
327
|
+
const tailwindEntry = `node_modules/${Z_UI_PKG}/assets/css/tailwind.css`;
|
|
328
|
+
const themeEntry = `node_modules/${Z_UI_PKG}/assets/css/themes/${theme}.css`;
|
|
329
|
+
const appStyles = `${ws.sourceRoot}/styles.css`.replace(/\\/g, '/');
|
|
330
|
+
|
|
331
|
+
const cfg = readJson(ws.configFile);
|
|
332
|
+
let options;
|
|
333
|
+
if (ws.kind === 'nx') {
|
|
334
|
+
const targetKey = ws.buildTargetKey || 'build';
|
|
335
|
+
cfg.targets ||= {};
|
|
336
|
+
cfg.targets[targetKey] ||= {};
|
|
337
|
+
cfg.targets[targetKey].options ||= {};
|
|
338
|
+
options = cfg.targets[targetKey].options;
|
|
339
|
+
} else {
|
|
340
|
+
const proj = cfg.projects[ws.name];
|
|
341
|
+
proj.architect ||= proj.targets;
|
|
342
|
+
const arch = proj.architect || proj.targets;
|
|
343
|
+
arch.build ||= {};
|
|
344
|
+
arch.build.options ||= {};
|
|
345
|
+
options = arch.build.options;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const styles = Array.isArray(options.styles) ? options.styles : [];
|
|
349
|
+
const desired = [tailwindEntry, themeEntry, appStyles];
|
|
350
|
+
|
|
351
|
+
// Drop any previously-added z-ui tailwind/theme entries so re-runs stay clean.
|
|
352
|
+
const cleaned = styles.filter(s => {
|
|
353
|
+
const str = typeof s === 'string' ? s : s.input;
|
|
354
|
+
if (!str) return true;
|
|
355
|
+
if (str.includes(`${Z_UI_PKG}/assets/css/tailwind.css`)) return false;
|
|
356
|
+
if (str.includes(`${Z_UI_PKG}/assets/css/themes/`)) return false;
|
|
357
|
+
return true;
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// Ensure the app styles entry exists exactly once, after the z-ui entries.
|
|
361
|
+
const withoutApp = cleaned.filter(s => {
|
|
362
|
+
const str = typeof s === 'string' ? s : s.input;
|
|
363
|
+
return str !== appStyles;
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
options.styles = [...desired, ...withoutApp.filter(s => !desired.includes(s))];
|
|
367
|
+
|
|
368
|
+
writeJson(ws.configFile, cfg);
|
|
369
|
+
log.ok(`Build styles set (${relative(process.cwd(), ws.configFile)}):`);
|
|
370
|
+
desired.forEach(s => log.info(` • ${s}`));
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function createPostcssrc(root) {
|
|
374
|
+
const target = join(root, '.postcssrc.json');
|
|
375
|
+
if (existsSync(target)) {
|
|
376
|
+
log.warn('.postcssrc.json already exists — leaving it untouched.');
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
write(target, POSTCSS_CONTENT);
|
|
380
|
+
log.ok('Created .postcssrc.json');
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function patchIndexHtml(ws) {
|
|
384
|
+
const indexPath = firstExisting([
|
|
385
|
+
absSrc(ws, 'index.html'),
|
|
386
|
+
join(ws.root, ws.sourceRoot, '..', 'index.html'),
|
|
387
|
+
join(ws.root, 'src', 'index.html'),
|
|
388
|
+
]);
|
|
389
|
+
if (!indexPath) {
|
|
390
|
+
log.warn('index.html not found — skipping font link injection.');
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
let html = read(indexPath);
|
|
394
|
+
if (html.includes('Be+Vietnam+Pro')) {
|
|
395
|
+
log.warn('Be Vietnam Pro font link already present — skipping.');
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
if (html.includes('</head>')) {
|
|
399
|
+
html = html.replace('</head>', `${FONT_LINK_TAG}\n</head>`);
|
|
400
|
+
} else {
|
|
401
|
+
log.warn('No </head> found in index.html — appending font link at top.');
|
|
402
|
+
html = `${FONT_LINK_TAG}\n${html}`;
|
|
403
|
+
}
|
|
404
|
+
write(indexPath, html);
|
|
405
|
+
log.ok(`Injected font <link> into ${relative(process.cwd(), indexPath)}`);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function createStylesCss(ws) {
|
|
409
|
+
const stylesPath = absSrc(ws, 'styles.css');
|
|
410
|
+
if (existsSync(stylesPath)) {
|
|
411
|
+
const current = read(stylesPath);
|
|
412
|
+
if (current.includes('--font-sans')) {
|
|
413
|
+
log.warn('styles.css already defines --font-sans — leaving it untouched.');
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
write(stylesPath, `${STYLES_CSS_CONTENT}\n${current}`);
|
|
417
|
+
log.ok('Prepended font variables to existing styles.css');
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
write(stylesPath, STYLES_CSS_CONTENT);
|
|
421
|
+
log.ok('Created src/styles.css');
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function patchAppConfig(ws, theme) {
|
|
425
|
+
const configPath = firstExisting([absSrc(ws, 'app', 'app.config.ts'), absSrc(ws, 'app', 'app.config.server.ts')]);
|
|
426
|
+
if (!configPath) {
|
|
427
|
+
log.warn('app.config.ts not found — printing the providers block to add manually.');
|
|
428
|
+
printAppConfigSnippet(theme);
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
let src = read(configPath);
|
|
433
|
+
if (src.includes('provideZTheme')) {
|
|
434
|
+
log.warn('app.config.ts already references provideZTheme — skipping provider patch.');
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// Add imports (skip any whose symbol is already imported anywhere in the file).
|
|
439
|
+
const wantedImports = [
|
|
440
|
+
[`provideHttpClient`, `import { provideHttpClient } from '@angular/common/http';`],
|
|
441
|
+
[`provideZIconLoader`, `import { provideZIconLoader } from '${Z_UI_PKG}/components/z-icon';`],
|
|
442
|
+
[`provideZToast`, `import { provideZToast } from '${Z_UI_PKG}/components/z-toast';`],
|
|
443
|
+
[`provideZTheme`, `import { provideZTheme, provideZTranslate } from '${Z_UI_PKG}/providers';`],
|
|
444
|
+
];
|
|
445
|
+
const importBlock = wantedImports
|
|
446
|
+
.filter(([symbol]) => !src.includes(symbol))
|
|
447
|
+
.map(([, imp]) => imp)
|
|
448
|
+
.join('\n');
|
|
449
|
+
|
|
450
|
+
if (importBlock) {
|
|
451
|
+
const lastImport = src.lastIndexOf('import ');
|
|
452
|
+
const lineEnd = src.indexOf('\n', lastImport);
|
|
453
|
+
src = `${src.slice(0, lineEnd + 1)}${importBlock}\n${src.slice(lineEnd + 1)}`;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Provider lines to add, skipping any already present in the file.
|
|
457
|
+
const wantedProviders = [
|
|
458
|
+
[`provideHttpClient`, `provideHttpClient(),`],
|
|
459
|
+
[`provideZIconLoader`, `provideZIconLoader(),`],
|
|
460
|
+
[`provideZToast`, `provideZToast({ zPosition: 'top-right', zDuration: 3000, zCloseButton: true }),`],
|
|
461
|
+
[`provideZTranslate`, `provideZTranslate({ defaultLang: 'vi' }),`],
|
|
462
|
+
[`provideZTheme`, `provideZTheme({ defaultTheme: '${theme}', defaultDarkMode: false }),`],
|
|
463
|
+
];
|
|
464
|
+
const newProviders = wantedProviders.filter(([symbol]) => !src.includes(`${symbol}(`)).map(([, line]) => line);
|
|
465
|
+
|
|
466
|
+
const providersMatch = src.match(/providers\s*:\s*\[/);
|
|
467
|
+
if (!providersMatch) {
|
|
468
|
+
log.warn('Could not find providers array — printing snippet to add manually.');
|
|
469
|
+
printAppConfigSnippet(theme);
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
const insertAt = providersMatch.index + providersMatch[0].length;
|
|
473
|
+
const indent = '\n ';
|
|
474
|
+
const injection = newProviders.map(l => `${indent}${l}`).join('');
|
|
475
|
+
src = `${src.slice(0, insertAt)}${injection}${src.slice(insertAt)}`;
|
|
476
|
+
|
|
477
|
+
write(configPath, src);
|
|
478
|
+
log.ok(`Patched ${relative(process.cwd(), configPath)} with z-ui providers.`);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function printAppConfigSnippet(theme) {
|
|
482
|
+
console.log(`\n${C.bold}Add these to your app.config.ts providers:${C.reset}`);
|
|
483
|
+
console.log(
|
|
484
|
+
`${C.dim}import { provideHttpClient } from '@angular/common/http';
|
|
485
|
+
import { provideZIconLoader } from '${Z_UI_PKG}/components/z-icon';
|
|
486
|
+
import { provideZToast } from '${Z_UI_PKG}/components/z-toast';
|
|
487
|
+
import { provideZTheme, provideZTranslate } from '${Z_UI_PKG}/providers';
|
|
488
|
+
|
|
489
|
+
providers: [
|
|
490
|
+
provideHttpClient(),
|
|
491
|
+
provideZIconLoader(),
|
|
492
|
+
provideZToast({ zPosition: 'top-right', zDuration: 3000, zCloseButton: true }),
|
|
493
|
+
provideZTranslate({ defaultLang: 'vi' }),
|
|
494
|
+
provideZTheme({ defaultTheme: '${theme}', defaultDarkMode: false }),
|
|
495
|
+
]${C.reset}`
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function patchRootComponent(ws, theme) {
|
|
500
|
+
const candidates = [absSrc(ws, 'app', 'app.ts'), absSrc(ws, 'app', 'app.component.ts')];
|
|
501
|
+
const compPath = firstExisting(candidates);
|
|
502
|
+
if (!compPath) {
|
|
503
|
+
log.warn('Root component (app.ts/app.component.ts) not found — add preloadTheme manually.');
|
|
504
|
+
printPreloadSnippet(theme);
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
let src = read(compPath);
|
|
509
|
+
if (src.includes('preloadTheme')) {
|
|
510
|
+
log.warn('Root component already calls preloadTheme — skipping.');
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Ensure ZThemeService import.
|
|
515
|
+
if (!src.includes('ZThemeService')) {
|
|
516
|
+
const imp = `import { ZThemeService } from '${Z_UI_PKG}/services';`;
|
|
517
|
+
const lastImport = src.lastIndexOf('import ');
|
|
518
|
+
const lineEnd = src.indexOf('\n', lastImport);
|
|
519
|
+
src = `${src.slice(0, lineEnd + 1)}${imp}\n${src.slice(lineEnd + 1)}`;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// Ensure inject + OnInit are imported from @angular/core.
|
|
523
|
+
src = ensureNamedImports(src, '@angular/core', ['inject', 'OnInit']);
|
|
524
|
+
|
|
525
|
+
const classMatch = src.match(/export class (\w+)([^{]*)\{/);
|
|
526
|
+
if (!classMatch) {
|
|
527
|
+
log.warn('Could not locate the root component class — add preloadTheme manually.');
|
|
528
|
+
printPreloadSnippet(theme);
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
const className = classMatch[1];
|
|
532
|
+
const heritage = classMatch[2];
|
|
533
|
+
|
|
534
|
+
// Add `implements OnInit` if not present.
|
|
535
|
+
if (!/implements[^{]*OnInit/.test(heritage)) {
|
|
536
|
+
const newHeritage = /implements/.test(heritage)
|
|
537
|
+
? heritage.replace(/implements\s+([^{]+)/, (m, list) => `implements ${list.trim()}, OnInit `)
|
|
538
|
+
: `${heritage.trimEnd()} implements OnInit `;
|
|
539
|
+
src = src.replace(classMatch[0], `export class ${className}${newHeritage}{`);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// Inject service + ngOnInit body right after the class opening brace.
|
|
543
|
+
const reMatch = src.match(new RegExp(`export class ${className}[^{]*\\{`));
|
|
544
|
+
const braceIdx = reMatch.index + reMatch[0].length;
|
|
545
|
+
const body = `
|
|
546
|
+
private readonly _themeService = inject(ZThemeService);
|
|
547
|
+
|
|
548
|
+
ngOnInit(): void {
|
|
549
|
+
this._themeService.preloadTheme('${theme}');
|
|
550
|
+
}
|
|
551
|
+
`;
|
|
552
|
+
src = `${src.slice(0, braceIdx)}${body}${src.slice(braceIdx)}`;
|
|
553
|
+
|
|
554
|
+
write(compPath, src);
|
|
555
|
+
log.ok(`Patched ${relative(process.cwd(), compPath)} to preloadTheme('${theme}').`);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/** Make sure `names` are present in the named import from `moduleSpec`. */
|
|
559
|
+
function ensureNamedImports(src, moduleSpec, names) {
|
|
560
|
+
const re = new RegExp(`import\\s*\\{([^}]*)\\}\\s*from\\s*['"]${moduleSpec.replace(/[/@]/g, '\\$&')}['"]`);
|
|
561
|
+
const m = src.match(re);
|
|
562
|
+
if (!m) {
|
|
563
|
+
// No existing import from this module — add a fresh one.
|
|
564
|
+
const imp = `import { ${names.join(', ')} } from '${moduleSpec}';`;
|
|
565
|
+
return `${imp}\n${src}`;
|
|
566
|
+
}
|
|
567
|
+
const existing = m[1]
|
|
568
|
+
.split(',')
|
|
569
|
+
.map(s => s.trim())
|
|
570
|
+
.filter(Boolean);
|
|
571
|
+
const merged = Array.from(new Set([...existing, ...names]));
|
|
572
|
+
return src.replace(re, `import { ${merged.join(', ')} } from '${moduleSpec}'`);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
function printPreloadSnippet(theme) {
|
|
576
|
+
console.log(`\n${C.bold}Add this to your root component:${C.reset}`);
|
|
577
|
+
console.log(
|
|
578
|
+
`${C.dim}import { inject, OnInit } from '@angular/core';
|
|
579
|
+
import { ZThemeService } from '${Z_UI_PKG}/services';
|
|
580
|
+
|
|
581
|
+
export class App implements OnInit {
|
|
582
|
+
private readonly _themeService = inject(ZThemeService);
|
|
583
|
+
ngOnInit(): void {
|
|
584
|
+
this._themeService.preloadTheme('${theme}');
|
|
585
|
+
}
|
|
586
|
+
}${C.reset}`
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// ---------------------------------------------------------------------------
|
|
591
|
+
// Main
|
|
592
|
+
// ---------------------------------------------------------------------------
|
|
593
|
+
|
|
594
|
+
async function main() {
|
|
595
|
+
const args = parseArgs(process.argv.slice(2));
|
|
596
|
+
if (args.help) {
|
|
597
|
+
printHelp();
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
DRY_RUN = !!args.dryRun;
|
|
601
|
+
const root = resolve(args.cwd || process.cwd());
|
|
602
|
+
|
|
603
|
+
console.log(`\n${C.bold}z-ui project setup${C.reset}`);
|
|
604
|
+
log.info(`Target: ${root}${DRY_RUN ? ' (dry-run)' : ''}\n`);
|
|
605
|
+
|
|
606
|
+
if (!existsSync(join(root, 'package.json'))) {
|
|
607
|
+
log.err('No package.json in target directory. Run from an Angular project root.');
|
|
608
|
+
process.exit(1);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
const ws = detectWorkspace(root, args.project);
|
|
612
|
+
log.ok(`Configuring project "${ws.name}" (sourceRoot: ${ws.sourceRoot}).`);
|
|
613
|
+
|
|
614
|
+
const theme = await chooseTheme(args.yes, args.theme);
|
|
615
|
+
log.ok(`Theme: ${theme}`);
|
|
616
|
+
|
|
617
|
+
if (!args.yes && !DRY_RUN) {
|
|
618
|
+
const go = await prompt(`\nProceed with setup? [Y/n] `);
|
|
619
|
+
if (go && !/^y(es)?$/i.test(go)) {
|
|
620
|
+
log.warn('Aborted.');
|
|
621
|
+
process.exit(0);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
console.log('');
|
|
626
|
+
if (!args.noInstall) installDeps(root);
|
|
627
|
+
else log.warn('Skipping dependency installation (--no-install).');
|
|
628
|
+
|
|
629
|
+
patchBuildStyles(ws, theme);
|
|
630
|
+
createPostcssrc(root);
|
|
631
|
+
patchIndexHtml(ws);
|
|
632
|
+
createStylesCss(ws);
|
|
633
|
+
patchAppConfig(ws, theme);
|
|
634
|
+
patchRootComponent(ws, theme);
|
|
635
|
+
|
|
636
|
+
console.log('');
|
|
637
|
+
log.ok(`${C.bold}Done.${C.reset} z-ui is wired into "${ws.name}" with the "${theme}" theme.`);
|
|
638
|
+
log.info('Next: start your dev server and verify the theme + fonts load.');
|
|
639
|
+
if (DRY_RUN) log.warn('This was a dry-run — no files were written.');
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
main().catch(e => {
|
|
643
|
+
log.err(e?.stack || String(e));
|
|
644
|
+
process.exit(1);
|
|
645
|
+
});
|
|
@@ -274,7 +274,7 @@ declare class ZAutocompleteComponent<T = unknown> implements OnInit, ControlValu
|
|
|
274
274
|
|
|
275
275
|
declare const zAutocompleteInputVariants: (props?: ({
|
|
276
276
|
zSize?: "sm" | "default" | "lg" | null | undefined;
|
|
277
|
-
zStatus?: "default" | "
|
|
277
|
+
zStatus?: "default" | "open" | "error" | "disabled" | "readonly" | null | undefined;
|
|
278
278
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
279
279
|
type ZAutocompleteInputVariants = VariantProps<typeof zAutocompleteInputVariants>;
|
|
280
280
|
declare const zAutocompleteOptionVariants: (props?: ({
|
|
@@ -328,7 +328,7 @@ declare const Z_EDITOR_DEFAULT_TOOLBAR: readonly ZEditorToolbarItem[];
|
|
|
328
328
|
|
|
329
329
|
declare const zEditorVariants: (props?: ({
|
|
330
330
|
zSize?: "sm" | "default" | "lg" | null | undefined;
|
|
331
|
-
zStatus?: "default" | "
|
|
331
|
+
zStatus?: "default" | "error" | "disabled" | "readonly" | null | undefined;
|
|
332
332
|
zPlaceholderMode?: "firstLine" | "everyLine" | null | undefined;
|
|
333
333
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
334
334
|
type ZEditorVariants = VariantProps<typeof zEditorVariants>;
|
|
@@ -188,7 +188,7 @@ declare class ZGalleryComponent implements AfterViewInit {
|
|
|
188
188
|
protected readonly headerControlHeight: _angular_core.Signal<"1.75rem" | "2rem" | "2.5rem" | "2.25rem">;
|
|
189
189
|
protected readonly skeletonMediaHeight: _angular_core.Signal<"9rem" | "14rem" | "11rem">;
|
|
190
190
|
protected readonly toggleIconSize: _angular_core.Signal<"14" | "16" | "20" | "18">;
|
|
191
|
-
protected readonly searchInputSize: _angular_core.Signal<"
|
|
191
|
+
protected readonly searchInputSize: _angular_core.Signal<"sm" | "default" | "lg">;
|
|
192
192
|
protected readonly filteredFiles: _angular_core.Signal<ZGalleryFile[]>;
|
|
193
193
|
protected readonly selectedIds: _angular_core.Signal<Set<string>>;
|
|
194
194
|
protected readonly isAllSelected: _angular_core.Signal<boolean>;
|
|
@@ -382,16 +382,16 @@ declare const isPreviewable: (file: ZGalleryFile) => boolean;
|
|
|
382
382
|
declare const isImage: (file: ZGalleryFile) => boolean;
|
|
383
383
|
|
|
384
384
|
declare const zGalleryVariants: (props?: ({
|
|
385
|
-
zSize?: "
|
|
385
|
+
zSize?: "sm" | "default" | "lg" | null | undefined;
|
|
386
386
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
387
387
|
type ZGalleryVariants = VariantProps<typeof zGalleryVariants>;
|
|
388
388
|
declare const zGalleryItemVariants: (props?: ({
|
|
389
389
|
zMode?: "grid" | "list" | null | undefined;
|
|
390
|
-
zSize?: "
|
|
390
|
+
zSize?: "sm" | "default" | "lg" | null | undefined;
|
|
391
391
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
392
392
|
type ZGalleryItemVariants = VariantProps<typeof zGalleryItemVariants>;
|
|
393
393
|
declare const zGalleryFileIconVariants: (props?: ({
|
|
394
|
-
zSize?: "
|
|
394
|
+
zSize?: "sm" | "default" | "lg" | null | undefined;
|
|
395
395
|
zMode?: "grid" | "list" | null | undefined;
|
|
396
396
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
397
397
|
type ZGalleryFileIconVariants = VariantProps<typeof zGalleryFileIconVariants>;
|
|
@@ -1,17 +1,33 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
2
|
import { Type, EnvironmentProviders } from '@angular/core';
|
|
3
3
|
import { ClassValue } from 'clsx';
|
|
4
|
+
import * as hugeIcons from '@hugeicons/core-free-icons';
|
|
4
5
|
import * as saxBoldIcons from '@ng-icons/iconsax/bold';
|
|
5
6
|
import * as saxOutlineIcons from '@ng-icons/iconsax/outline';
|
|
6
7
|
import * as lucideIcons from '@ng-icons/lucide';
|
|
8
|
+
import * as phosphorBoldIcons from '@ng-icons/phosphor-icons/bold';
|
|
9
|
+
import * as phosphorDuotoneIcons from '@ng-icons/phosphor-icons/duotone';
|
|
10
|
+
import * as phosphorFillIcons from '@ng-icons/phosphor-icons/fill';
|
|
11
|
+
import * as phosphorLightIcons from '@ng-icons/phosphor-icons/light';
|
|
12
|
+
import * as phosphorRegularIcons from '@ng-icons/phosphor-icons/regular';
|
|
13
|
+
import * as phosphorThinIcons from '@ng-icons/phosphor-icons/thin';
|
|
7
14
|
import * as animatedIcons from 'ng-animated-icons';
|
|
8
15
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
9
16
|
import { VariantProps } from 'class-variance-authority';
|
|
10
17
|
|
|
11
18
|
type ZLucideIcon = Extract<keyof typeof lucideIcons, `lucide${string}`>;
|
|
12
19
|
type ZSaxIcon = Extract<keyof typeof saxBoldIcons | keyof typeof saxOutlineIcons, `sax${string}`>;
|
|
20
|
+
type ZPhosphorIcon = Extract<keyof typeof phosphorRegularIcons | keyof typeof phosphorBoldIcons | keyof typeof phosphorFillIcons | keyof typeof phosphorLightIcons | keyof typeof phosphorThinIcons | keyof typeof phosphorDuotoneIcons, `phosphor${string}`>;
|
|
21
|
+
/**
|
|
22
|
+
* HugeIcons exports are PascalCase with an `Icon` suffix (e.g. `HeartIcon`,
|
|
23
|
+
* `Home01Icon`). We re-expose them with a `huge` prefix to stay consistent
|
|
24
|
+
* with the other families (e.g. `hugeHeart`, `hugeHome01`).
|
|
25
|
+
*/
|
|
26
|
+
type ZHugeIcon = {
|
|
27
|
+
[K in keyof typeof hugeIcons as K extends `${infer Name}Icon` ? `huge${Name}` : never]: true;
|
|
28
|
+
} extends infer M ? Extract<keyof M, `huge${string}`> : never;
|
|
13
29
|
declare const Z_ICONS: {};
|
|
14
|
-
type ZIcon = ZLucideIcon | ZSaxIcon;
|
|
30
|
+
type ZIcon = ZLucideIcon | ZSaxIcon | ZPhosphorIcon | ZHugeIcon;
|
|
15
31
|
|
|
16
32
|
type ZIconAnimationTrigger = 'manual' | 'hover' | 'focus' | 'interaction' | 'always';
|
|
17
33
|
declare class ZIconComponent {
|
|
@@ -251,7 +251,7 @@ declare class ZModalComponent<T, U> extends BasePortalOutlet implements OnDestro
|
|
|
251
251
|
protected readonly effectiveOkText: _angular_core.Signal<string | null | undefined>;
|
|
252
252
|
protected readonly effectiveCancelText: _angular_core.Signal<string | null | undefined>;
|
|
253
253
|
protected readonly effectiveOkDestructive: _angular_core.Signal<boolean | undefined>;
|
|
254
|
-
protected readonly effectiveTypeOk: _angular_core.Signal<"info" | "warning" | "error" | "default" | "primary" | "secondary" | "destructive" | "destructive-heartbeat" | "success" | "outline" | "outline-primary" | "outline-secondary" | "outline-success" | "outline-info" | "outline-warning" | "outline-error" | "outline-destructive" | "outline-shimmer" | "outline-success-secondary" | "outline-info-secondary" | "outline-warning-secondary" | "outline-error-secondary" | "outline-destructive-secondary" | "outline-primary-secondary" | "outline-primary-soft" | "outline-success-soft" | "outline-info-soft" | "outline-warning-soft" | "outline-error-soft" | "outline-destructive-soft" | "outline-primary-soft-border" | "outline-success-soft-border" | "outline-info-soft-border" | "outline-warning-soft-border" | "outline-error-soft-border" | "outline-destructive-soft-border" | "ghost" | "ghost-primary" | "ghost-success" | "ghost-info" | "ghost-warning" | "ghost-error" | "ghost-destructive" | "subtle" | "subtle-primary" | "subtle-success" | "subtle-info" | "subtle-warning" | "subtle-destructive" | "subtle-outline" | "subtle-primary-outline" | "subtle-success-outline" | "subtle-info-outline" | "subtle-warning-outline" | "subtle-destructive-outline" |
|
|
254
|
+
protected readonly effectiveTypeOk: _angular_core.Signal<"info" | "warning" | "error" | "link" | "default" | "primary" | "secondary" | "destructive" | "destructive-heartbeat" | "success" | "outline" | "outline-primary" | "outline-secondary" | "outline-success" | "outline-info" | "outline-warning" | "outline-error" | "outline-destructive" | "outline-shimmer" | "outline-success-secondary" | "outline-info-secondary" | "outline-warning-secondary" | "outline-error-secondary" | "outline-destructive-secondary" | "outline-primary-secondary" | "outline-primary-soft" | "outline-success-soft" | "outline-info-soft" | "outline-warning-soft" | "outline-error-soft" | "outline-destructive-soft" | "outline-primary-soft-border" | "outline-success-soft-border" | "outline-info-soft-border" | "outline-warning-soft-border" | "outline-error-soft-border" | "outline-destructive-soft-border" | "ghost" | "ghost-primary" | "ghost-success" | "ghost-info" | "ghost-warning" | "ghost-error" | "ghost-destructive" | "subtle" | "subtle-primary" | "subtle-success" | "subtle-info" | "subtle-warning" | "subtle-destructive" | "subtle-outline" | "subtle-primary-outline" | "subtle-success-outline" | "subtle-info-outline" | "subtle-warning-outline" | "subtle-destructive-outline" | null | undefined>;
|
|
255
255
|
protected readonly effectiveOkDisabled: _angular_core.Signal<boolean | undefined>;
|
|
256
256
|
protected readonly effectiveLoading: _angular_core.Signal<boolean>;
|
|
257
257
|
protected readonly effectiveContentLoading: _angular_core.Signal<boolean>;
|
|
@@ -116,7 +116,7 @@ declare class ZPopoverDirective implements OnInit, OnDestroy {
|
|
|
116
116
|
readonly zHideDelay: _angular_core.InputSignal<number>;
|
|
117
117
|
readonly zDisabled: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
|
|
118
118
|
readonly zOffset: _angular_core.InputSignal<number>;
|
|
119
|
-
readonly zPopoverWidth: _angular_core.InputSignal<number | "
|
|
119
|
+
readonly zPopoverWidth: _angular_core.InputSignal<number | "trigger" | "auto">;
|
|
120
120
|
readonly zTriggerRef: _angular_core.InputSignal<HTMLElement | ElementRef<HTMLElement> | null>;
|
|
121
121
|
readonly zManualClose: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
|
|
122
122
|
readonly zOutsideClickClose: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
|
|
@@ -323,7 +323,7 @@ declare class ZTagClassesPipe implements PipeTransform {
|
|
|
323
323
|
|
|
324
324
|
declare const zSelectVariants: (props?: ({
|
|
325
325
|
zSize?: "sm" | "default" | "lg" | null | undefined;
|
|
326
|
-
zStatus?: "default" | "
|
|
326
|
+
zStatus?: "default" | "open" | "error" | "disabled" | "readonly" | null | undefined;
|
|
327
327
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
328
328
|
declare const zSelectTagVariants: (props?: ({
|
|
329
329
|
zSize?: "sm" | "default" | "lg" | null | undefined;
|
|
@@ -1720,7 +1720,7 @@ declare class ZTableActionsComponent<T = unknown> {
|
|
|
1720
1720
|
readonly zConfig: _angular_core.InputSignal<ZTableActionColumnConfig<T>>;
|
|
1721
1721
|
readonly zRow: _angular_core.InputSignal<T>;
|
|
1722
1722
|
readonly zRowId: _angular_core.InputSignal<string>;
|
|
1723
|
-
readonly zDropdownButtonSize: _angular_core.InputSignal<"
|
|
1723
|
+
readonly zDropdownButtonSize: _angular_core.InputSignal<"sm" | "default" | "lg" | "xs" | "xl" | null | undefined>;
|
|
1724
1724
|
readonly zActionClick: _angular_core.OutputEmitterRef<ZTableActionClickEvent<T>>;
|
|
1725
1725
|
protected readonly allActions: _angular_core.Signal<ZTableActionItem<T>[]>;
|
|
1726
1726
|
protected readonly shouldShowAsButtons: _angular_core.Signal<boolean>;
|
|
@@ -100,7 +100,7 @@ declare class ZUploadComponent implements OnInit, ControlValueAccessor {
|
|
|
100
100
|
protected readonly hasError: _angular_core.Signal<boolean>;
|
|
101
101
|
protected readonly showError: _angular_core.Signal<boolean>;
|
|
102
102
|
protected readonly errorMessage: _angular_core.Signal<string>;
|
|
103
|
-
protected readonly currentStatus: _angular_core.Signal<"default" | "
|
|
103
|
+
protected readonly currentStatus: _angular_core.Signal<"default" | "error" | "disabled" | "readonly" | "active">;
|
|
104
104
|
protected readonly dropzoneClasses: _angular_core.Signal<string>;
|
|
105
105
|
protected readonly acceptTypes: _angular_core.Signal<string>;
|
|
106
106
|
protected readonly formatFileSize: (bytes: number) => string;
|
|
@@ -141,11 +141,11 @@ declare class ZUploadComponent implements OnInit, ControlValueAccessor {
|
|
|
141
141
|
|
|
142
142
|
declare const zUploadDropzoneVariants: (props?: ({
|
|
143
143
|
zSize?: "sm" | "default" | "lg" | null | undefined;
|
|
144
|
-
zStatus?: "default" | "
|
|
144
|
+
zStatus?: "default" | "error" | "active" | "disabled" | "readonly" | null | undefined;
|
|
145
145
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
146
146
|
type ZUploadDropzoneVariants = VariantProps<typeof zUploadDropzoneVariants>;
|
|
147
147
|
declare const zUploadFileItemVariants: (props?: ({
|
|
148
|
-
zStatus?: "
|
|
148
|
+
zStatus?: "pending" | "uploading" | "success" | "error" | null | undefined;
|
|
149
149
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
150
150
|
type ZUploadFileItemVariants = VariantProps<typeof zUploadFileItemVariants>;
|
|
151
151
|
|