@leftium/logo 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AppLogo.svelte +16 -7
- package/dist/AppLogo.svelte.d.ts +4 -1
- package/dist/app-logo/color-transform.d.ts +7 -3
- package/dist/app-logo/color-transform.js +14 -8
- package/dist/app-logo/config-serialization.d.ts +80 -0
- package/dist/app-logo/config-serialization.js +489 -0
- package/dist/app-logo/defaults.d.ts +44 -0
- package/dist/app-logo/defaults.js +17 -0
- package/dist/app-logo/generate-svg.js +6 -4
- package/dist/app-logo/iconify.d.ts +16 -2
- package/dist/app-logo/iconify.js +94 -5
- package/dist/app-logo/types.d.ts +2 -0
- package/dist/leftium-logo/generate-svg.d.ts +29 -0
- package/dist/leftium-logo/generate-svg.js +470 -0
- package/dist/tooltip.d.ts +18 -0
- package/dist/tooltip.js +38 -0
- package/package.json +5 -3
package/dist/AppLogo.svelte
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { AppLogoProps, GradientConfig } from './app-logo/types.js';
|
|
3
|
-
import { APP_LOGO_DEFAULTS } from './app-logo/defaults.js';
|
|
3
|
+
import { APP_LOGO_DEFAULTS, DEFAULT_EMOJI_STYLE } from './app-logo/defaults.js';
|
|
4
4
|
import { resolveIcon, type ResolvedIcon } from './app-logo/iconify.js';
|
|
5
5
|
import { applyColorMode } from './app-logo/color-transform.js';
|
|
6
6
|
import { generateCornerPath } from './app-logo/squircle.js';
|
|
@@ -13,11 +13,13 @@
|
|
|
13
13
|
iconOffsetX = APP_LOGO_DEFAULTS.iconOffsetX,
|
|
14
14
|
iconOffsetY = APP_LOGO_DEFAULTS.iconOffsetY,
|
|
15
15
|
iconRotation = APP_LOGO_DEFAULTS.iconRotation,
|
|
16
|
+
grayscaleLightness = 100,
|
|
16
17
|
cornerRadius = APP_LOGO_DEFAULTS.cornerRadius,
|
|
17
18
|
cornerShape = APP_LOGO_DEFAULTS.cornerShape,
|
|
18
19
|
background = APP_LOGO_DEFAULTS.background as AppLogoProps['background'],
|
|
19
|
-
size = APP_LOGO_DEFAULTS.size
|
|
20
|
-
|
|
20
|
+
size = APP_LOGO_DEFAULTS.size,
|
|
21
|
+
emojiStyle = DEFAULT_EMOJI_STYLE
|
|
22
|
+
}: AppLogoProps & { emojiStyle?: string } = $props();
|
|
21
23
|
|
|
22
24
|
// Resolved icon state — use $state.raw since this is replaced, not mutated
|
|
23
25
|
let resolved: ResolvedIcon | null = $state.raw(null);
|
|
@@ -25,11 +27,12 @@
|
|
|
25
27
|
// Fetch icon when the icon prop changes
|
|
26
28
|
$effect(() => {
|
|
27
29
|
const currentIcon = icon;
|
|
30
|
+
const currentEmojiStyle = emojiStyle;
|
|
28
31
|
resolved = null;
|
|
29
32
|
|
|
30
|
-
resolveIcon(currentIcon).then((result) => {
|
|
31
|
-
// Only update if icon hasn't changed while we were fetching
|
|
32
|
-
if (icon === currentIcon) {
|
|
33
|
+
resolveIcon(currentIcon, currentEmojiStyle).then((result) => {
|
|
34
|
+
// Only update if icon/emojiStyle hasn't changed while we were fetching
|
|
35
|
+
if (icon === currentIcon && emojiStyle === currentEmojiStyle) {
|
|
33
36
|
resolved = result;
|
|
34
37
|
}
|
|
35
38
|
});
|
|
@@ -39,7 +42,13 @@
|
|
|
39
42
|
let coloredSvgContent = $derived.by(() => {
|
|
40
43
|
const r = resolved;
|
|
41
44
|
if (!r) return '';
|
|
42
|
-
return applyColorMode(
|
|
45
|
+
return applyColorMode(
|
|
46
|
+
r.svgContent,
|
|
47
|
+
r.isMonochrome,
|
|
48
|
+
iconColorMode,
|
|
49
|
+
iconColor,
|
|
50
|
+
grayscaleLightness
|
|
51
|
+
);
|
|
43
52
|
});
|
|
44
53
|
|
|
45
54
|
// Build the full inline SVG with viewBox and 100% sizing
|
package/dist/AppLogo.svelte.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { AppLogoProps } from './app-logo/types.js';
|
|
2
|
-
|
|
2
|
+
type $$ComponentProps = AppLogoProps & {
|
|
3
|
+
emojiStyle?: string;
|
|
4
|
+
};
|
|
5
|
+
declare const AppLogo: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
3
6
|
type AppLogo = ReturnType<typeof AppLogo>;
|
|
4
7
|
export default AppLogo;
|
|
@@ -8,15 +8,17 @@ import type { IconColorMode } from './types.js';
|
|
|
8
8
|
/**
|
|
9
9
|
* Transform a single CSS color to grayscale using OKLCH.
|
|
10
10
|
* Sets chroma to 0, preserving perceptual lightness.
|
|
11
|
+
* @param lightness Optional lightness multiplier (0-200), default 100 = no change
|
|
11
12
|
*/
|
|
12
|
-
export declare function toGrayscale(color: string): string;
|
|
13
|
+
export declare function toGrayscale(color: string, lightness?: number): string;
|
|
13
14
|
/**
|
|
14
15
|
* Transform a single CSS color to grayscale, then tint toward a target color.
|
|
15
16
|
*
|
|
16
17
|
* The tint color's hue and chroma influence the result, while the original
|
|
17
18
|
* color's lightness is preserved. This unifies a palette while keeping contrast.
|
|
19
|
+
* @param lightness Optional lightness multiplier (0-200), default 100 = no change
|
|
18
20
|
*/
|
|
19
|
-
export declare function toGrayscaleTint(color: string, tintColor: string): string;
|
|
21
|
+
export declare function toGrayscaleTint(color: string, tintColor: string, lightness?: number): string;
|
|
20
22
|
/**
|
|
21
23
|
* Remap a single CSS color to a target hue, optionally overriding saturation.
|
|
22
24
|
*
|
|
@@ -32,5 +34,7 @@ export declare function remapHue(color: string, targetHue: number, targetSaturat
|
|
|
32
34
|
*
|
|
33
35
|
* Color transforms operate on fill/stroke attribute values and style properties,
|
|
34
36
|
* replacing each color with its transformed equivalent.
|
|
37
|
+
*
|
|
38
|
+
* @param grayscaleLightness Lightness multiplier for grayscale modes (0-200), default 100
|
|
35
39
|
*/
|
|
36
|
-
export declare function applyColorMode(svgContent: string, isMonochrome: boolean, colorMode: IconColorMode, iconColor: string): string;
|
|
40
|
+
export declare function applyColorMode(svgContent: string, isMonochrome: boolean, colorMode: IconColorMode, iconColor: string, grayscaleLightness?: number): string;
|
|
@@ -37,30 +37,34 @@ function oklchToHex(l, c, h, alpha) {
|
|
|
37
37
|
/**
|
|
38
38
|
* Transform a single CSS color to grayscale using OKLCH.
|
|
39
39
|
* Sets chroma to 0, preserving perceptual lightness.
|
|
40
|
+
* @param lightness Optional lightness multiplier (0-200), default 100 = no change
|
|
40
41
|
*/
|
|
41
|
-
export function toGrayscale(color) {
|
|
42
|
+
export function toGrayscale(color, lightness = 100) {
|
|
42
43
|
const oklch = parseToOklch(color);
|
|
43
44
|
if (!oklch)
|
|
44
45
|
return color;
|
|
45
|
-
|
|
46
|
+
const l = Math.min(1, Math.max(0, oklch.l * (lightness / 100)));
|
|
47
|
+
return oklchToHex(l, 0, 0, oklch.alpha);
|
|
46
48
|
}
|
|
47
49
|
/**
|
|
48
50
|
* Transform a single CSS color to grayscale, then tint toward a target color.
|
|
49
51
|
*
|
|
50
52
|
* The tint color's hue and chroma influence the result, while the original
|
|
51
53
|
* color's lightness is preserved. This unifies a palette while keeping contrast.
|
|
54
|
+
* @param lightness Optional lightness multiplier (0-200), default 100 = no change
|
|
52
55
|
*/
|
|
53
|
-
export function toGrayscaleTint(color, tintColor) {
|
|
56
|
+
export function toGrayscaleTint(color, tintColor, lightness = 100) {
|
|
54
57
|
const oklch = parseToOklch(color);
|
|
55
58
|
if (!oklch)
|
|
56
59
|
return color;
|
|
57
60
|
const tint = parseToOklch(tintColor);
|
|
58
61
|
if (!tint)
|
|
59
62
|
return color;
|
|
60
|
-
// Use original lightness, tint's hue, and a fraction of tint's chroma
|
|
63
|
+
// Use original lightness (scaled by multiplier), tint's hue, and a fraction of tint's chroma
|
|
61
64
|
// Scale chroma by the ratio of original chroma to max, to preserve some variation
|
|
65
|
+
const l = Math.min(1, Math.max(0, oklch.l * (lightness / 100)));
|
|
62
66
|
const tintChroma = tint.c * 0.7; // 70% of tint chroma for a softer effect
|
|
63
|
-
return oklchToHex(
|
|
67
|
+
return oklchToHex(l, tintChroma, tint.h, oklch.alpha);
|
|
64
68
|
}
|
|
65
69
|
/**
|
|
66
70
|
* Remap a single CSS color to a target hue, optionally overriding saturation.
|
|
@@ -85,8 +89,10 @@ export function remapHue(color, targetHue, targetSaturation) {
|
|
|
85
89
|
*
|
|
86
90
|
* Color transforms operate on fill/stroke attribute values and style properties,
|
|
87
91
|
* replacing each color with its transformed equivalent.
|
|
92
|
+
*
|
|
93
|
+
* @param grayscaleLightness Lightness multiplier for grayscale modes (0-200), default 100
|
|
88
94
|
*/
|
|
89
|
-
export function applyColorMode(svgContent, isMonochrome, colorMode, iconColor) {
|
|
95
|
+
export function applyColorMode(svgContent, isMonochrome, colorMode, iconColor, grayscaleLightness = 100) {
|
|
90
96
|
// Handle simple string modes first
|
|
91
97
|
if (colorMode === 'original') {
|
|
92
98
|
return svgContent;
|
|
@@ -111,10 +117,10 @@ export function applyColorMode(svgContent, isMonochrome, colorMode, iconColor) {
|
|
|
111
117
|
// Replace currentColor with iconColor before transforming
|
|
112
118
|
const resolvedColor = color === 'currentColor' ? iconColor : color;
|
|
113
119
|
if (colorMode === 'grayscale') {
|
|
114
|
-
return toGrayscale(resolvedColor);
|
|
120
|
+
return toGrayscale(resolvedColor, grayscaleLightness);
|
|
115
121
|
}
|
|
116
122
|
if (colorMode === 'grayscale-tint') {
|
|
117
|
-
return toGrayscaleTint(resolvedColor, iconColor);
|
|
123
|
+
return toGrayscaleTint(resolvedColor, iconColor, grayscaleLightness);
|
|
118
124
|
}
|
|
119
125
|
// Object mode: { hue, saturation? }
|
|
120
126
|
if (typeof colorMode === 'object') {
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config serialization: bidirectional conversion between the UI-level ColumnState
|
|
3
|
+
* (flat, slider-friendly) and the export-level AppLogoConfig (structured, spec-compliant).
|
|
4
|
+
*
|
|
5
|
+
* Also handles URL hash encoding/decoding and Svelte snippet generation.
|
|
6
|
+
*/
|
|
7
|
+
import type { AppLogoConfig, CornerShape, GradientConfig, IconColorMode } from './types.js';
|
|
8
|
+
export interface ColumnState {
|
|
9
|
+
icon: string;
|
|
10
|
+
iconColor: string;
|
|
11
|
+
iconColorModeKey: string;
|
|
12
|
+
hueValue: number;
|
|
13
|
+
saturationValue: number;
|
|
14
|
+
iconSize: number;
|
|
15
|
+
iconOffsetX: number;
|
|
16
|
+
iconOffsetY: number;
|
|
17
|
+
iconRotation: number;
|
|
18
|
+
grayscaleLightness: number;
|
|
19
|
+
cornerRadius: number;
|
|
20
|
+
cornerK: number;
|
|
21
|
+
solidColor: string;
|
|
22
|
+
useGradient: boolean;
|
|
23
|
+
gradientAngle: number;
|
|
24
|
+
gradientPosition: number;
|
|
25
|
+
gradientScale: number;
|
|
26
|
+
}
|
|
27
|
+
export declare const DEFAULT_STATE: ColumnState;
|
|
28
|
+
export declare const DEFAULT_LOCKS: Record<keyof ColumnState, boolean>;
|
|
29
|
+
export declare function cornerKToShape(k: number): CornerShape;
|
|
30
|
+
export declare function cornerShapeToK(shape: CornerShape): number;
|
|
31
|
+
export declare function cornerKLabel(k: number): string;
|
|
32
|
+
export declare function iconColorModeFromFlat(key: string, hue: number, saturation: number): IconColorMode;
|
|
33
|
+
export declare function iconColorModeToFlat(mode: IconColorMode): {
|
|
34
|
+
key: string;
|
|
35
|
+
hue: number;
|
|
36
|
+
saturation: number;
|
|
37
|
+
};
|
|
38
|
+
export declare function backgroundFromFlat(col: ColumnState): string | GradientConfig;
|
|
39
|
+
/**
|
|
40
|
+
* Build an AppLogoConfig from the logo and effective favicon ColumnState.
|
|
41
|
+
* Also accepts the lock state to determine which favicon fields are overrides.
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildFullConfig(logoState: ColumnState, effectiveFaviconState: ColumnState, lockState: Record<keyof ColumnState, boolean>, emojiStyle?: string): AppLogoConfig;
|
|
44
|
+
/**
|
|
45
|
+
* Build a single-variant AppLogoConfig for export/rendering.
|
|
46
|
+
*/
|
|
47
|
+
export declare function buildVariantConfig(col: ColumnState, variant: 'logo' | 'favicon', emojiStyle?: string): AppLogoConfig;
|
|
48
|
+
/**
|
|
49
|
+
* Convert an AppLogoConfig back to ColumnState + lock state.
|
|
50
|
+
* Shared fields populate the logo column. Favicon overrides populate
|
|
51
|
+
* the favicon column and unlock the corresponding locks.
|
|
52
|
+
*/
|
|
53
|
+
export declare function configToUIState(config: AppLogoConfig): {
|
|
54
|
+
logo: ColumnState;
|
|
55
|
+
favicon: ColumnState;
|
|
56
|
+
locks: Record<keyof ColumnState, boolean>;
|
|
57
|
+
emojiStyle: string;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Encode a config object to a base64url string for URL hash.
|
|
61
|
+
* Uses TextEncoder for Unicode safety (emoji icon names, non-ASCII app names).
|
|
62
|
+
*/
|
|
63
|
+
export declare function encodeConfigToHash(config: AppLogoConfig): string;
|
|
64
|
+
/**
|
|
65
|
+
* Decode a base64url string from URL hash back to AppLogoConfig.
|
|
66
|
+
* Returns null if decoding fails.
|
|
67
|
+
*/
|
|
68
|
+
export declare function decodeConfigFromHash(hash: string): AppLogoConfig | null;
|
|
69
|
+
/**
|
|
70
|
+
* Generate a minimal <AppLogo> Svelte snippet with only non-default props.
|
|
71
|
+
*/
|
|
72
|
+
export declare function generateSvelteSnippet(config: AppLogoConfig): string;
|
|
73
|
+
/**
|
|
74
|
+
* Generate the HTML favicon snippet for clipboard copy.
|
|
75
|
+
* Re-exports the existing function for convenience.
|
|
76
|
+
*/
|
|
77
|
+
export declare function generateHtmlSnippet(appInfo: {
|
|
78
|
+
name?: string;
|
|
79
|
+
shortName?: string;
|
|
80
|
+
}): string;
|