@sky.ui/core 0.0.38 → 0.0.39
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/custom-elements.json +2283 -2196
- package/dist/helper/index.js +1 -1
- package/dist/helper/utils/color-resolver.d.ts +9 -1
- package/dist/helper/utils/color-resolver.js +1 -1
- package/dist/helper/utils/color-resolver.js.map +1 -1
- package/dist/helper/utils/contrast-color.d.ts +128 -0
- package/dist/helper/utils/contrast-color.js +2 -0
- package/dist/helper/utils/contrast-color.js.map +1 -0
- package/dist/helper/utils/index.d.ts +1 -0
- package/dist/helper/utils/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/sky-alert/sky-alert.js +13 -11
- package/dist/sky-alert/sky-alert.js.map +1 -1
- package/dist/sky-appbar/sky-appbar.js +6 -5
- package/dist/sky-appbar/sky-appbar.js.map +1 -1
- package/dist/sky-badge/sky-badge.js +13 -9
- package/dist/sky-badge/sky-badge.js.map +1 -1
- package/dist/sky-button/sky-button.js +14 -11
- package/dist/sky-button/sky-button.js.map +1 -1
- package/dist/sky-card/sky-card.js.map +1 -1
- package/dist/sky-checkbox/sky-checkbox.js +13 -11
- package/dist/sky-checkbox/sky-checkbox.js.map +1 -1
- package/dist/sky-chip/sky-chip.js +14 -11
- package/dist/sky-chip/sky-chip.js.map +1 -1
- package/dist/sky-combobox/sky-combobox.d.ts +16 -3
- package/dist/sky-combobox/sky-combobox.js +680 -257
- package/dist/sky-combobox/sky-combobox.js.map +1 -1
- package/dist/sky-dialog/sky-dialog.js.map +1 -1
- package/dist/sky-input/sky-input.d.ts +3 -2
- package/dist/sky-input/sky-input.js +452 -180
- package/dist/sky-input/sky-input.js.map +1 -1
- package/dist/sky-radio/sky-radio.d.ts +2 -0
- package/dist/sky-radio/sky-radio.js +28 -13
- package/dist/sky-radio/sky-radio.js.map +1 -1
- package/dist/sky-sheet/sky-sheet.js.map +1 -1
- package/dist/sky-theme-provider/sky-theme-provider.js +1 -1
- package/dist/sky-theme-provider/sky-theme-provider.js.map +1 -1
- package/package.json +1 -1
package/dist/helper/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{extractIconNames,fetchIconsForOffline,registerOfflineIcons}from"./iconify-offline.js";export{AnimationController}from"./controllers/animation-controller.js";export{ColorResolver,DEFAULT_COLOR_TOKENS,colorResolver,createGradient,darkShade,fadeMix,hoverShade,isDefaultColorToken,lightShade,parseGradientSpec,resolveAccentColorForToken,resolveColor,resolveGradientStop,resolveInkColorForToken,resolveSemanticSurfaceKey,resolveTextColorForToken,semanticSoftSurfaceTokens,skyBorderPrimaryShorthand,skyBorderWidthSolid,tuneSurfaceVariantForDefaultColor}from"./utils/color-resolver.js";export{FormControlBase}from"./internals/form-control-base.js";export{PopoverController}from"./controllers/popover-controller.js";export{resolveRadius}from"./utils/size-resolver.js";
|
|
1
|
+
export{extractIconNames,fetchIconsForOffline,registerOfflineIcons}from"./iconify-offline.js";export{AnimationController}from"./controllers/animation-controller.js";export{CONTRAST_COLOR_SUPPORT_QUERY,ON_COLOR_FALLBACK_DARK,ON_COLOR_FALLBACK_LIGHT,contrastOnFill,contrastOverlay,contrastThemeInk,cssContrastColor,cssOnFill,cssOnFillEnhance,isLightFill,parseCssRgb,perceivedLuminance,relativeLuminance}from"./utils/contrast-color.js";export{ColorResolver,DEFAULT_COLOR_TOKENS,colorResolver,createGradient,darkShade,fadeMix,hoverShade,isDefaultColorToken,lightShade,parseGradientSpec,resolveAccentColorForToken,resolveColor,resolveGradientStop,resolveInkColorForToken,resolveSemanticSurfaceKey,resolveTextColorForToken,semanticSoftSurfaceTokens,skyBorderPrimaryShorthand,skyBorderWidthSolid,tuneSurfaceVariantForDefaultColor}from"./utils/color-resolver.js";export{FormControlBase}from"./internals/form-control-base.js";export{PopoverController}from"./controllers/popover-controller.js";export{resolveRadius}from"./utils/size-resolver.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -21,7 +21,15 @@ export declare const DEFAULT_COLOR_TOKENS: Record<string, string>;
|
|
|
21
21
|
*/
|
|
22
22
|
export declare function resolveColor(input: string, customMap?: Record<string, string>): string;
|
|
23
23
|
/**
|
|
24
|
-
* Determines
|
|
24
|
+
* Determines fallback text color for a given background color token.
|
|
25
|
+
*
|
|
26
|
+
* Prefer CSS `contrast-color()` against the **actual fill custom property**
|
|
27
|
+
* for solid surfaces (see `./contrast-color.ts`). Keep using this helper as the
|
|
28
|
+
* pre-`@supports` / inline-var fallback so older browsers stay readable.
|
|
29
|
+
*
|
|
30
|
+
* Soft / tinted surfaces should use ink / soft-semantic tokens instead —
|
|
31
|
+
* do not pair them with `contrast-color()`.
|
|
32
|
+
*
|
|
25
33
|
* @param input - Color token (e.g., 'primary')
|
|
26
34
|
* @returns CSS color value for text
|
|
27
35
|
*/
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const r={primary:"var(--sky-active-primary)",active:"var(--sky-active-primary)",secondary:"var(--sky-info-primary)",success:"var(--sky-success-primary)",danger:"var(--sky-danger-primary)",warning:"var(--sky-warning-primary)",info:"var(--sky-info-primary)",light:"var(--sky-text-light)",dark:"var(--sky-text-dark)",muted:"var(--sky-text-tertiary)","border-light":"var(--sky-border-light)",default:"var(--sky-glass-solid)"};function
|
|
1
|
+
const r={primary:"var(--sky-active-primary)",active:"var(--sky-active-primary)",secondary:"var(--sky-info-primary)",success:"var(--sky-success-primary)",danger:"var(--sky-danger-primary)",warning:"var(--sky-warning-primary)",info:"var(--sky-info-primary)",light:"var(--sky-text-light)",dark:"var(--sky-text-dark)",muted:"var(--sky-text-tertiary)","border-light":"var(--sky-border-light)",default:"var(--sky-glass-solid)"};function a(a,t={}){const o={...r,...t};return o[a]||a||o.primary}function t(r){return{dark:"var(--sky-text-light)",light:"var(--sky-text-dark)",warning:"var(--sky-on-color-fallback-dark, var(--sky-text-black))",success:"var(--sky-on-color-fallback-dark, var(--sky-text-black))",default:"var(--sky-text-primary)"}[r]||"var(--sky-on-color-fallback-light, var(--sky-text-white))"}function o(r){return"default"===r}function e(r){return o(r)?"var(--sky-text-primary)":a(r)}function i(r){return o(r)?"var(--sky-active-primary)":a(r)}const s={primary:"active",active:"active",success:"success",danger:"danger",warning:"warning",info:"info",secondary:"info"};function n(r){return s[r]??null}function y(r,a={}){return{bg:`var(--sky-${r}-quinary)`,color:`var(--sky-${r}-primary-dark)`,border:a.bordered?`1px solid var(--sky-${r}-g1)`:"none"}}function v(){return"var(--sky-border-primary)"}function c(r){return`${r}px solid var(--sky-border-light)`}const l={shadow:{bg:"var(--sky-glass-solid)",hoverBg:"var(--sky-glass-solid)",color:"var(--sky-text-primary)",hoverColor:"var(--sky-active-primary)",shadow:"none",hoverShadow:"var(--sky-box-shadow-hover)",arrow:"var(--sky-glass-solid)"},solid:{hoverShadow:"var(--sky-box-shadow-hover)"},faded:{color:"var(--sky-text-primary)",hoverColor:"var(--sky-text-primary)",arrow:"var(--sky-hover-tertiary)"},bordered:{color:"var(--sky-text-primary)",border:c(2),hoverColor:"var(--sky-text-primary)",hoverBorder:"2px solid var(--sky-text-tertiary)",arrow:"var(--sky-border-light)"},transparent:{color:"var(--sky-text-primary)",hoverBg:"var(--sky-hover-tertiary)",hoverColor:"var(--sky-text-primary)"},flat:{bg:"var(--sky-hover-tertiary)",color:"var(--sky-text-primary)",hoverBg:"var(--sky-hover-secondary)",hoverColor:"var(--sky-active-primary)",arrow:"var(--sky-hover-tertiary)"},ghost:{color:"var(--sky-text-primary)",border:c(2),hoverBg:"var(--sky-hover-secondary)",hoverColor:"var(--sky-text-primary)"},link:{color:"var(--sky-text-primary)",hoverColor:"var(--sky-active-primary)"},light:{color:"var(--sky-text-primary)"}};function k(r,a,t){if(!o(r))return t;const e=l[a];return e?{...t,...e}:t}function d(r,a=20){return`color-mix(in srgb, ${r} ${100-a}%, var(--sky-text-dark))`}function u(r,a=20){return`color-mix(in srgb, ${r} ${100-a}%, var(--sky-text-black))`}function g(r,a=20){return`color-mix(in srgb, ${r} ${100-a}%, var(--sky-text-white))`}function h(r,a=15){return`color-mix(in srgb, ${r} ${a}%, transparent)`}function p(a){const t=a.match(/^([^\s]+)(\s+.+)?$/),o=t?.[1]??a;return`${r[o]||o}${t?.[2]??""}`}function m(r){const a=(r||"").trim(),t=a.indexOf(":");let o="",e=a;-1!==t&&(o=a.slice(0,t).trim(),e=a.slice(t+1).trim());let i="linear",s="90deg";if(o){const[r,t]=o.split("@").map(r=>r.trim()),n=(r||"").toLowerCase();"linear"===n||"radial"===n||"conic"===n?(i=n,s=t||("linear"===i?"90deg":"radial"===i?"circle":"from 0deg at 50% 50%")):e=a}return{kind:i,args:s,stops:e.split(",").map(r=>r.trim()).filter(Boolean)}}function f(r,a="var(--sky-active-primary)"){const t=m(r),o=(t.stops.length?t.stops:[a,a]).map(r=>p(r)),{kind:e,args:i}=t;switch(e){case"linear":return`linear-gradient(${i}, ${o.join(", ")})`;case"radial":return`radial-gradient(${i}, ${o.join(", ")})`;case"conic":return`conic-gradient(${i}, ${o.join(", ")})`;default:return`linear-gradient(90deg, ${o.join(", ")})`}}class x{constructor(r={}){this.config={prefix:r.prefix||"sky",useColorMix:r.useColorMix??!0}}resolve(a){if(a.startsWith("#"))return a;if(a.startsWith("rgb")||a.startsWith("hsl"))return a;if(a.startsWith("var("))return a;const t=`var(--${this.config.prefix}-${a})`;return r[a]||t||r.primary}getTextColor(a){return a in r?t(a):"var(--sky-text-white)"}getHoverColor(r,a=20){return this.config.useColorMix?d(r,a):r}}const b=new x;export{x as ColorResolver,r as DEFAULT_COLOR_TOKENS,b as colorResolver,f as createGradient,u as darkShade,h as fadeMix,d as hoverShade,o as isDefaultColorToken,g as lightShade,m as parseGradientSpec,i as resolveAccentColorForToken,a as resolveColor,p as resolveGradientStop,e as resolveInkColorForToken,n as resolveSemanticSurfaceKey,t as resolveTextColorForToken,y as semanticSoftSurfaceTokens,v as skyBorderPrimaryShorthand,c as skyBorderWidthSolid,k as tuneSurfaceVariantForDefaultColor};
|
|
2
2
|
//# sourceMappingURL=color-resolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"color-resolver.js","sources":["../../../src/helper/utils/color-resolver.ts"],"sourcesContent":["/**\r\n * Color resolution utilities for Sky Design System\r\n * Provides consistent color token mapping across components\r\n */\r\n\r\nexport type ColorToken =\r\n | 'primary'\r\n | 'secondary'\r\n | 'success'\r\n | 'danger'\r\n | 'warning'\r\n | 'light'\r\n | 'dark'\r\n | 'default'\r\n | string; // Custom CSS color\r\n\r\nexport interface ColorResolverConfig {\r\n /** CSS variable prefix (default: 'sky') */\r\n prefix?: string;\r\n /** Whether to use color-mix for hover states */\r\n useColorMix?: boolean;\r\n}\r\n\r\n/**\r\n * Default color token mapping to CSS variables\r\n */\r\nexport const DEFAULT_COLOR_TOKENS: Record<string, string> = {\r\n primary: 'var(--sky-active-primary)',\r\n active: 'var(--sky-active-primary)',\r\n secondary: 'var(--sky-info-primary)',\r\n success: 'var(--sky-success-primary)',\r\n danger: 'var(--sky-danger-primary)',\r\n warning: 'var(--sky-warning-primary)',\r\n info: 'var(--sky-info-primary)',\r\n light: 'var(--sky-text-light)',\r\n dark: 'var(--sky-text-dark)',\r\n /** Muted line/text (e.g. dividers); maps to `--sky-text-tertiary`. */\r\n muted: 'var(--sky-text-tertiary)',\r\n /** Light border tone; maps to `--sky-border-light`. */\r\n 'border-light': 'var(--sky-border-light)',\r\n default: 'var(--sky-glass-solid)',\r\n} as const;\r\n\r\n/**\r\n * Resolves a color token to its CSS value\r\n * @param input - Color token (e.g., 'primary') or custom CSS color\r\n * @param customMap - Optional custom token mapping (overrides defaults)\r\n * @returns CSS color value\r\n */\r\nexport function resolveColor(\r\n input: string,\r\n customMap: Record<string, string> = {}\r\n): string {\r\n const map = { ...DEFAULT_COLOR_TOKENS, ...customMap };\r\n return map[input] || input || map.primary;\r\n}\r\n\r\n/**\r\n * Determines appropriate text color for a given background color token\r\n * @param input - Color token (e.g., 'primary')\r\n * @returns CSS color value for text\r\n */\r\nexport function resolveTextColorForToken(input: string): string {\r\n const tokenMap: Record<string, string> = {\r\n dark: 'var(--sky-text-light)',\r\n light: 'var(--sky-text-dark)',\r\n warning: 'var(--sky-text-black)',\r\n success: 'var(--sky-text-black)',\r\n default: 'var(--sky-text-primary)',\r\n };\r\n\r\n return tokenMap[input] || 'var(--sky-text-white)';\r\n}\r\n\r\n/** True when the token is the neutral glass surface (`default`), not a brand accent. */\r\nexport function isDefaultColorToken(input: string): boolean {\r\n return input === 'default';\r\n}\r\n\r\n/** Foreground ink (labels, borders) — never use glass-solid as text. */\r\nexport function resolveInkColorForToken(input: string): string {\r\n return isDefaultColorToken(input)\r\n ? 'var(--sky-text-primary)'\r\n : resolveColor(input);\r\n}\r\n\r\n/** Accent for hover/focus on neutral surfaces. */\r\nexport function resolveAccentColorForToken(input: string): string {\r\n return isDefaultColorToken(input)\r\n ? 'var(--sky-active-primary)'\r\n : resolveColor(input);\r\n}\r\n\r\n/** Maps component color tokens to theme semantic keys (`active`, `success`, …). */\r\nconst SEMANTIC_SURFACE_KEYS: Record<string, string> = {\r\n primary: \"active\",\r\n active: \"active\",\r\n success: \"success\",\r\n danger: \"danger\",\r\n warning: \"warning\",\r\n info: \"info\",\r\n secondary: \"info\",\r\n};\r\n\r\n/**\r\n * Resolves a color token to a theme semantic surface key, if one exists.\r\n */\r\nexport function resolveSemanticSurfaceKey(colorToken: string): string | null {\r\n return SEMANTIC_SURFACE_KEYS[colorToken] ?? null;\r\n}\r\n\r\n/** Soft semantic surface tokens for alerts, badges, and subtle status blocks. */\r\nexport function semanticSoftSurfaceTokens(\r\n semanticKey: string,\r\n options: { bordered?: boolean } = {},\r\n): { bg: string; color: string; border: string } {\r\n return {\r\n bg: `var(--sky-${semanticKey}-quinary)`,\r\n color: `var(--sky-${semanticKey}-primary-dark)`,\r\n border: options.bordered\r\n ? `1px solid var(--sky-${semanticKey}-g1)`\r\n : \"none\",\r\n };\r\n}\r\n\r\n/**\r\n * Theme glass border shorthand (`1px solid …` from `--sky-border-primary`).\r\n * Use as a full `border` value — do not wrap in `Npx solid var(--sky-border-primary)`.\r\n */\r\nexport function skyBorderPrimaryShorthand(): string {\r\n return 'var(--sky-border-primary)';\r\n}\r\n\r\n/**\r\n * Separator stroke for custom widths (`--sky-border-light` is a color, not shorthand).\r\n */\r\nexport function skyBorderWidthSolid(widthPx: number): string {\r\n return `${widthPx}px solid var(--sky-border-light)`;\r\n}\r\n\r\n/** Partial variant overrides when `color=\"default\"` (surface token, not ink). */\r\nexport type DefaultColorVariantPatch = Partial<{\r\n bg: string;\r\n color: string;\r\n border: string;\r\n shadow: string;\r\n hoverBg: string;\r\n hoverColor: string;\r\n hoverShadow: string;\r\n hoverBorder: string;\r\n arrow: string;\r\n}>;\r\n\r\nconst DEFAULT_COLOR_VARIANT_PATCHES: Record<string, DefaultColorVariantPatch> = {\r\n shadow: {\r\n bg: 'var(--sky-glass-solid)',\r\n hoverBg: 'var(--sky-glass-solid)',\r\n color: 'var(--sky-text-primary)',\r\n hoverColor: 'var(--sky-active-primary)',\r\n shadow: 'none',\r\n hoverShadow: 'var(--sky-box-shadow-hover)',\r\n arrow: 'var(--sky-glass-solid)',\r\n },\r\n solid: {\r\n hoverShadow: 'var(--sky-box-shadow-hover)',\r\n },\r\n faded: {\r\n color: 'var(--sky-text-primary)',\r\n hoverColor: 'var(--sky-text-primary)',\r\n arrow: 'var(--sky-hover-tertiary)',\r\n },\r\n bordered: {\r\n color: 'var(--sky-text-primary)',\r\n border: skyBorderWidthSolid(2),\r\n hoverColor: 'var(--sky-text-primary)',\r\n hoverBorder: '2px solid var(--sky-text-tertiary)',\r\n arrow: 'var(--sky-border-light)',\r\n },\r\n transparent: {\r\n color: 'var(--sky-text-primary)',\r\n hoverBg: 'var(--sky-hover-tertiary)',\r\n hoverColor: 'var(--sky-text-primary)',\r\n },\r\n flat: {\r\n bg: 'var(--sky-hover-tertiary)',\r\n color: 'var(--sky-text-primary)',\r\n hoverBg: 'var(--sky-hover-secondary)',\r\n hoverColor: 'var(--sky-active-primary)',\r\n arrow: 'var(--sky-hover-tertiary)',\r\n },\r\n ghost: {\r\n color: 'var(--sky-text-primary)',\r\n border: skyBorderWidthSolid(2),\r\n hoverBg: 'var(--sky-hover-secondary)',\r\n hoverColor: 'var(--sky-text-primary)',\r\n },\r\n link: {\r\n color: 'var(--sky-text-primary)',\r\n hoverColor: 'var(--sky-active-primary)',\r\n },\r\n light: {\r\n color: 'var(--sky-text-primary)',\r\n },\r\n};\r\n\r\n/**\r\n * Applies variant style overrides for `color=\"default\"` so glass tokens are not\r\n * used as text/border/hover ink on translucent surfaces.\r\n */\r\nexport function tuneSurfaceVariantForDefaultColor<T extends DefaultColorVariantPatch>(\r\n colorToken: string,\r\n variant: string,\r\n styles: T,\r\n): T {\r\n if (!isDefaultColorToken(colorToken)) return styles;\r\n const patch = DEFAULT_COLOR_VARIANT_PATCHES[variant];\r\n if (!patch) return styles;\r\n return { ...styles, ...patch };\r\n}\r\n\r\n/**\r\n * Creates a hover shade using color-mix\r\n * @param color - Base CSS color\r\n * @param amount - Percentage of black to mix (0-100)\r\n * @returns CSS color-mix() value\r\n */\r\nexport function hoverShade(color: string, amount: number = 20): string {\r\n return `color-mix(in srgb, ${color} ${100 - amount}%, var(--sky-text-dark))`;\r\n}\r\n/**\r\n * Creates a hover shade using color-mix\r\n * @param color - Base CSS color\r\n * @param amount - Percentage of black to mix (0-100)\r\n * @returns CSS color-mix() value\r\n */\r\nexport function darkShade(color: string, amount: number = 20): string {\r\n return `color-mix(in srgb, ${color} ${100 - amount}%, var(--sky-text-black))`;\r\n}\r\n/**\r\n * Creates a hover shade using color-mix\r\n * @param color - Base CSS color\r\n * @param amount - Percentage of black to mix (0-100)\r\n * @returns CSS color-mix() value\r\n */\r\nexport function lightShade(color: string, amount: number = 20): string {\r\n return `color-mix(in srgb, ${color} ${100 - amount}%, var(--sky-text-white))`;\r\n}\r\n\r\n\r\n/**\r\n * Creates a faded/transparent version of a color\r\n * @param color - Base CSS color\r\n * @param amount - Percentage of transparency (0-100)\r\n * @returns CSS color-mix() value with transparency\r\n */\r\nexport function fadeMix(color: string, amount: number = 15): string {\r\n return `color-mix(in srgb, ${color} ${amount}%, transparent)`;\r\n}\r\n\r\n/**\r\n * Resolves gradient stop tokens to CSS colors\r\n * @param stop - Gradient stop token (e.g., 'primary 30%')\r\n * @returns CSS gradient stop value\r\n */\r\nexport function resolveGradientStop(stop: string): string {\r\n const match = stop.match(/^([^\\s]+)(\\s+.+)?$/);\r\n const head = match?.[1] ?? stop;\r\n const tail = match?.[2] ?? '';\r\n\r\n const resolved = DEFAULT_COLOR_TOKENS[head] || head;\r\n return `${resolved}${tail}`;\r\n}\r\n\r\n/**\r\n * Parses a gradient specification string\r\n */\r\nexport interface GradientSpec {\r\n kind: 'linear' | 'radial' | 'conic';\r\n args: string;\r\n stops: string[];\r\n}\r\n\r\n/**\r\n * Parses gradient specification string\r\n * Format: \"kind@args: stop1, stop2, stop3\"\r\n * Example: \"linear@90deg: primary, secondary 50%, danger\"\r\n * Example: \"radial@circle: primary, transparent\"\r\n */\r\nexport function parseGradientSpec(input: string): GradientSpec {\r\n const raw = (input || '').trim();\r\n const idx = raw.indexOf(':');\r\n let prefix = '';\r\n let stopsStr = raw;\r\n\r\n if (idx !== -1) {\r\n prefix = raw.slice(0, idx).trim();\r\n stopsStr = raw.slice(idx + 1).trim();\r\n }\r\n\r\n let kind: 'linear' | 'radial' | 'conic' = 'linear';\r\n let args = '90deg';\r\n\r\n if (prefix) {\r\n const [k, a] = prefix.split('@').map(s => s.trim());\r\n const kLower = (k || '').toLowerCase();\r\n if (kLower === 'linear' || kLower === 'radial' || kLower === 'conic') {\r\n kind = kLower;\r\n args = a || (kind === 'linear'\r\n ? '90deg'\r\n : kind === 'radial'\r\n ? 'circle'\r\n : 'from 0deg at 50% 50%');\r\n } else {\r\n stopsStr = raw;\r\n }\r\n }\r\n\r\n const stops = stopsStr\r\n .split(',')\r\n .map(s => s.trim())\r\n .filter(Boolean);\r\n\r\n return { kind, args, stops };\r\n}\r\n\r\n/**\r\n * Creates a CSS gradient from a specification string\r\n * @param specStr - Gradient specification string\r\n * @param fallbackColor - Fallback color if no stops provided\r\n * @returns CSS gradient value\r\n */\r\nexport function createGradient(\r\n specStr: string,\r\n fallbackColor: string = 'var(--sky-active-primary)'\r\n): string {\r\n const spec = parseGradientSpec(specStr);\r\n const stops = (\r\n spec.stops.length\r\n ? spec.stops\r\n : [fallbackColor, fallbackColor]\r\n ).map(st => resolveGradientStop(st));\r\n\r\n const { kind, args } = spec;\r\n\r\n switch (kind) {\r\n case 'linear':\r\n return `linear-gradient(${args}, ${stops.join(', ')})`;\r\n case 'radial':\r\n return `radial-gradient(${args}, ${stops.join(', ')})`;\r\n case 'conic':\r\n return `conic-gradient(${args}, ${stops.join(', ')})`;\r\n default:\r\n return `linear-gradient(90deg, ${stops.join(', ')})`;\r\n }\r\n}\r\n\r\n/**\r\n * Color resolver with configuration support\r\n */\r\nexport class ColorResolver {\r\n private config: Required<ColorResolverConfig>;\r\n\r\n constructor(config: ColorResolverConfig = {}) {\r\n this.config = {\r\n prefix: config.prefix || 'sky',\r\n useColorMix: config.useColorMix ?? true,\r\n };\r\n }\r\n\r\n /**\r\n * Resolves a color with prefix-aware variable names\r\n */\r\n resolve(input: string): string {\r\n if (input.startsWith('#')) return input;\r\n if (input.startsWith('rgb') || input.startsWith('hsl')) return input;\r\n if (input.startsWith('var(')) return input;\r\n\r\n const customVar = `var(--${this.config.prefix}-${input})`;\r\n const defaultResolved = DEFAULT_COLOR_TOKENS[input];\r\n\r\n return defaultResolved || customVar || DEFAULT_COLOR_TOKENS.primary;\r\n }\r\n\r\n /**\r\n * Gets text color for a background color\r\n */\r\n getTextColor(backgroundColor: string): string {\r\n // If it's a token, use the token-based logic\r\n if (backgroundColor in DEFAULT_COLOR_TOKENS) {\r\n return resolveTextColorForToken(backgroundColor);\r\n }\r\n\r\n // For custom colors, return a sensible default\r\n return 'var(--sky-text-white)';\r\n }\r\n\r\n /**\r\n * Creates a hover state color\r\n */\r\n getHoverColor(baseColor: string, darkenAmount: number = 20): string {\r\n if (!this.config.useColorMix) {\r\n // Fallback for browsers without color-mix support\r\n return baseColor;\r\n }\r\n\r\n return hoverShade(baseColor, darkenAmount);\r\n }\r\n}\r\n\r\n/**\r\n * Singleton instance for convenience\r\n */\r\nexport const colorResolver = new ColorResolver();\r\n\r\n"],"names":["DEFAULT_COLOR_TOKENS","primary","active","secondary","success","danger","warning","info","light","dark","muted","default","resolveColor","input","customMap","map","resolveTextColorForToken","isDefaultColorToken","resolveInkColorForToken","resolveAccentColorForToken","SEMANTIC_SURFACE_KEYS","resolveSemanticSurfaceKey","colorToken","semanticSoftSurfaceTokens","semanticKey","options","bg","color","border","bordered","skyBorderPrimaryShorthand","skyBorderWidthSolid","widthPx","DEFAULT_COLOR_VARIANT_PATCHES","shadow","hoverBg","hoverColor","hoverShadow","arrow","solid","faded","hoverBorder","transparent","flat","ghost","link","tuneSurfaceVariantForDefaultColor","variant","styles","patch","hoverShade","amount","darkShade","lightShade","fadeMix","resolveGradientStop","stop","match","head","parseGradientSpec","raw","trim","idx","indexOf","prefix","stopsStr","slice","kind","args","k","a","split","s","kLower","toLowerCase","stops","filter","Boolean","createGradient","specStr","fallbackColor","spec","length","st","join","ColorResolver","constructor","config","this","useColorMix","resolve","startsWith","customVar","getTextColor","backgroundColor","getHoverColor","baseColor","darkenAmount","colorResolver"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"color-resolver.js","sources":["../../../src/helper/utils/color-resolver.ts"],"sourcesContent":["/**\r\n * Color resolution utilities for Sky Design System\r\n * Provides consistent color token mapping across components\r\n */\r\n\r\nexport type ColorToken =\r\n | 'primary'\r\n | 'secondary'\r\n | 'success'\r\n | 'danger'\r\n | 'warning'\r\n | 'light'\r\n | 'dark'\r\n | 'default'\r\n | string; // Custom CSS color\r\n\r\nexport interface ColorResolverConfig {\r\n /** CSS variable prefix (default: 'sky') */\r\n prefix?: string;\r\n /** Whether to use color-mix for hover states */\r\n useColorMix?: boolean;\r\n}\r\n\r\n/**\r\n * Default color token mapping to CSS variables\r\n */\r\nexport const DEFAULT_COLOR_TOKENS: Record<string, string> = {\r\n primary: 'var(--sky-active-primary)',\r\n active: 'var(--sky-active-primary)',\r\n secondary: 'var(--sky-info-primary)',\r\n success: 'var(--sky-success-primary)',\r\n danger: 'var(--sky-danger-primary)',\r\n warning: 'var(--sky-warning-primary)',\r\n info: 'var(--sky-info-primary)',\r\n light: 'var(--sky-text-light)',\r\n dark: 'var(--sky-text-dark)',\r\n /** Muted line/text (e.g. dividers); maps to `--sky-text-tertiary`. */\r\n muted: 'var(--sky-text-tertiary)',\r\n /** Light border tone; maps to `--sky-border-light`. */\r\n 'border-light': 'var(--sky-border-light)',\r\n default: 'var(--sky-glass-solid)',\r\n} as const;\r\n\r\n/**\r\n * Resolves a color token to its CSS value\r\n * @param input - Color token (e.g., 'primary') or custom CSS color\r\n * @param customMap - Optional custom token mapping (overrides defaults)\r\n * @returns CSS color value\r\n */\r\nexport function resolveColor(\r\n input: string,\r\n customMap: Record<string, string> = {}\r\n): string {\r\n const map = { ...DEFAULT_COLOR_TOKENS, ...customMap };\r\n return map[input] || input || map.primary;\r\n}\r\n\r\n/**\r\n * Determines fallback text color for a given background color token.\r\n *\r\n * Prefer CSS `contrast-color()` against the **actual fill custom property**\r\n * for solid surfaces (see `./contrast-color.ts`). Keep using this helper as the\r\n * pre-`@supports` / inline-var fallback so older browsers stay readable.\r\n *\r\n * Soft / tinted surfaces should use ink / soft-semantic tokens instead —\r\n * do not pair them with `contrast-color()`.\r\n *\r\n * @param input - Color token (e.g., 'primary')\r\n * @returns CSS color value for text\r\n */\r\nexport function resolveTextColorForToken(input: string): string {\r\n const tokenMap: Record<string, string> = {\r\n dark: 'var(--sky-text-light)',\r\n light: 'var(--sky-text-dark)',\r\n warning: 'var(--sky-on-color-fallback-dark, var(--sky-text-black))',\r\n success: 'var(--sky-on-color-fallback-dark, var(--sky-text-black))',\r\n default: 'var(--sky-text-primary)',\r\n };\r\n\r\n return tokenMap[input] || 'var(--sky-on-color-fallback-light, var(--sky-text-white))';\r\n}\r\n\r\n/** True when the token is the neutral glass surface (`default`), not a brand accent. */\r\nexport function isDefaultColorToken(input: string): boolean {\r\n return input === 'default';\r\n}\r\n\r\n/** Foreground ink (labels, borders) — never use glass-solid as text. */\r\nexport function resolveInkColorForToken(input: string): string {\r\n return isDefaultColorToken(input)\r\n ? 'var(--sky-text-primary)'\r\n : resolveColor(input);\r\n}\r\n\r\n/** Accent for hover/focus on neutral surfaces. */\r\nexport function resolveAccentColorForToken(input: string): string {\r\n return isDefaultColorToken(input)\r\n ? 'var(--sky-active-primary)'\r\n : resolveColor(input);\r\n}\r\n\r\n/** Maps component color tokens to theme semantic keys (`active`, `success`, …). */\r\nconst SEMANTIC_SURFACE_KEYS: Record<string, string> = {\r\n primary: \"active\",\r\n active: \"active\",\r\n success: \"success\",\r\n danger: \"danger\",\r\n warning: \"warning\",\r\n info: \"info\",\r\n secondary: \"info\",\r\n};\r\n\r\n/**\r\n * Resolves a color token to a theme semantic surface key, if one exists.\r\n */\r\nexport function resolveSemanticSurfaceKey(colorToken: string): string | null {\r\n return SEMANTIC_SURFACE_KEYS[colorToken] ?? null;\r\n}\r\n\r\n/** Soft semantic surface tokens for alerts, badges, and subtle status blocks. */\r\nexport function semanticSoftSurfaceTokens(\r\n semanticKey: string,\r\n options: { bordered?: boolean } = {},\r\n): { bg: string; color: string; border: string } {\r\n return {\r\n bg: `var(--sky-${semanticKey}-quinary)`,\r\n color: `var(--sky-${semanticKey}-primary-dark)`,\r\n border: options.bordered\r\n ? `1px solid var(--sky-${semanticKey}-g1)`\r\n : \"none\",\r\n };\r\n}\r\n\r\n/**\r\n * Theme glass border shorthand (`1px solid …` from `--sky-border-primary`).\r\n * Use as a full `border` value — do not wrap in `Npx solid var(--sky-border-primary)`.\r\n */\r\nexport function skyBorderPrimaryShorthand(): string {\r\n return 'var(--sky-border-primary)';\r\n}\r\n\r\n/**\r\n * Separator stroke for custom widths (`--sky-border-light` is a color, not shorthand).\r\n */\r\nexport function skyBorderWidthSolid(widthPx: number): string {\r\n return `${widthPx}px solid var(--sky-border-light)`;\r\n}\r\n\r\n/** Partial variant overrides when `color=\"default\"` (surface token, not ink). */\r\nexport type DefaultColorVariantPatch = Partial<{\r\n bg: string;\r\n color: string;\r\n border: string;\r\n shadow: string;\r\n hoverBg: string;\r\n hoverColor: string;\r\n hoverShadow: string;\r\n hoverBorder: string;\r\n arrow: string;\r\n}>;\r\n\r\nconst DEFAULT_COLOR_VARIANT_PATCHES: Record<string, DefaultColorVariantPatch> = {\r\n shadow: {\r\n bg: 'var(--sky-glass-solid)',\r\n hoverBg: 'var(--sky-glass-solid)',\r\n color: 'var(--sky-text-primary)',\r\n hoverColor: 'var(--sky-active-primary)',\r\n shadow: 'none',\r\n hoverShadow: 'var(--sky-box-shadow-hover)',\r\n arrow: 'var(--sky-glass-solid)',\r\n },\r\n solid: {\r\n hoverShadow: 'var(--sky-box-shadow-hover)',\r\n },\r\n faded: {\r\n color: 'var(--sky-text-primary)',\r\n hoverColor: 'var(--sky-text-primary)',\r\n arrow: 'var(--sky-hover-tertiary)',\r\n },\r\n bordered: {\r\n color: 'var(--sky-text-primary)',\r\n border: skyBorderWidthSolid(2),\r\n hoverColor: 'var(--sky-text-primary)',\r\n hoverBorder: '2px solid var(--sky-text-tertiary)',\r\n arrow: 'var(--sky-border-light)',\r\n },\r\n transparent: {\r\n color: 'var(--sky-text-primary)',\r\n hoverBg: 'var(--sky-hover-tertiary)',\r\n hoverColor: 'var(--sky-text-primary)',\r\n },\r\n flat: {\r\n bg: 'var(--sky-hover-tertiary)',\r\n color: 'var(--sky-text-primary)',\r\n hoverBg: 'var(--sky-hover-secondary)',\r\n hoverColor: 'var(--sky-active-primary)',\r\n arrow: 'var(--sky-hover-tertiary)',\r\n },\r\n ghost: {\r\n color: 'var(--sky-text-primary)',\r\n border: skyBorderWidthSolid(2),\r\n hoverBg: 'var(--sky-hover-secondary)',\r\n hoverColor: 'var(--sky-text-primary)',\r\n },\r\n link: {\r\n color: 'var(--sky-text-primary)',\r\n hoverColor: 'var(--sky-active-primary)',\r\n },\r\n light: {\r\n color: 'var(--sky-text-primary)',\r\n },\r\n};\r\n\r\n/**\r\n * Applies variant style overrides for `color=\"default\"` so glass tokens are not\r\n * used as text/border/hover ink on translucent surfaces.\r\n */\r\nexport function tuneSurfaceVariantForDefaultColor<T extends DefaultColorVariantPatch>(\r\n colorToken: string,\r\n variant: string,\r\n styles: T,\r\n): T {\r\n if (!isDefaultColorToken(colorToken)) return styles;\r\n const patch = DEFAULT_COLOR_VARIANT_PATCHES[variant];\r\n if (!patch) return styles;\r\n return { ...styles, ...patch };\r\n}\r\n\r\n/**\r\n * Creates a hover shade using color-mix\r\n * @param color - Base CSS color\r\n * @param amount - Percentage of black to mix (0-100)\r\n * @returns CSS color-mix() value\r\n */\r\nexport function hoverShade(color: string, amount: number = 20): string {\r\n return `color-mix(in srgb, ${color} ${100 - amount}%, var(--sky-text-dark))`;\r\n}\r\n/**\r\n * Creates a hover shade using color-mix\r\n * @param color - Base CSS color\r\n * @param amount - Percentage of black to mix (0-100)\r\n * @returns CSS color-mix() value\r\n */\r\nexport function darkShade(color: string, amount: number = 20): string {\r\n return `color-mix(in srgb, ${color} ${100 - amount}%, var(--sky-text-black))`;\r\n}\r\n/**\r\n * Creates a hover shade using color-mix\r\n * @param color - Base CSS color\r\n * @param amount - Percentage of black to mix (0-100)\r\n * @returns CSS color-mix() value\r\n */\r\nexport function lightShade(color: string, amount: number = 20): string {\r\n return `color-mix(in srgb, ${color} ${100 - amount}%, var(--sky-text-white))`;\r\n}\r\n\r\n\r\n/**\r\n * Creates a faded/transparent version of a color\r\n * @param color - Base CSS color\r\n * @param amount - Percentage of transparency (0-100)\r\n * @returns CSS color-mix() value with transparency\r\n */\r\nexport function fadeMix(color: string, amount: number = 15): string {\r\n return `color-mix(in srgb, ${color} ${amount}%, transparent)`;\r\n}\r\n\r\n/**\r\n * Resolves gradient stop tokens to CSS colors\r\n * @param stop - Gradient stop token (e.g., 'primary 30%')\r\n * @returns CSS gradient stop value\r\n */\r\nexport function resolveGradientStop(stop: string): string {\r\n const match = stop.match(/^([^\\s]+)(\\s+.+)?$/);\r\n const head = match?.[1] ?? stop;\r\n const tail = match?.[2] ?? '';\r\n\r\n const resolved = DEFAULT_COLOR_TOKENS[head] || head;\r\n return `${resolved}${tail}`;\r\n}\r\n\r\n/**\r\n * Parses a gradient specification string\r\n */\r\nexport interface GradientSpec {\r\n kind: 'linear' | 'radial' | 'conic';\r\n args: string;\r\n stops: string[];\r\n}\r\n\r\n/**\r\n * Parses gradient specification string\r\n * Format: \"kind@args: stop1, stop2, stop3\"\r\n * Example: \"linear@90deg: primary, secondary 50%, danger\"\r\n * Example: \"radial@circle: primary, transparent\"\r\n */\r\nexport function parseGradientSpec(input: string): GradientSpec {\r\n const raw = (input || '').trim();\r\n const idx = raw.indexOf(':');\r\n let prefix = '';\r\n let stopsStr = raw;\r\n\r\n if (idx !== -1) {\r\n prefix = raw.slice(0, idx).trim();\r\n stopsStr = raw.slice(idx + 1).trim();\r\n }\r\n\r\n let kind: 'linear' | 'radial' | 'conic' = 'linear';\r\n let args = '90deg';\r\n\r\n if (prefix) {\r\n const [k, a] = prefix.split('@').map(s => s.trim());\r\n const kLower = (k || '').toLowerCase();\r\n if (kLower === 'linear' || kLower === 'radial' || kLower === 'conic') {\r\n kind = kLower;\r\n args = a || (kind === 'linear'\r\n ? '90deg'\r\n : kind === 'radial'\r\n ? 'circle'\r\n : 'from 0deg at 50% 50%');\r\n } else {\r\n stopsStr = raw;\r\n }\r\n }\r\n\r\n const stops = stopsStr\r\n .split(',')\r\n .map(s => s.trim())\r\n .filter(Boolean);\r\n\r\n return { kind, args, stops };\r\n}\r\n\r\n/**\r\n * Creates a CSS gradient from a specification string\r\n * @param specStr - Gradient specification string\r\n * @param fallbackColor - Fallback color if no stops provided\r\n * @returns CSS gradient value\r\n */\r\nexport function createGradient(\r\n specStr: string,\r\n fallbackColor: string = 'var(--sky-active-primary)'\r\n): string {\r\n const spec = parseGradientSpec(specStr);\r\n const stops = (\r\n spec.stops.length\r\n ? spec.stops\r\n : [fallbackColor, fallbackColor]\r\n ).map(st => resolveGradientStop(st));\r\n\r\n const { kind, args } = spec;\r\n\r\n switch (kind) {\r\n case 'linear':\r\n return `linear-gradient(${args}, ${stops.join(', ')})`;\r\n case 'radial':\r\n return `radial-gradient(${args}, ${stops.join(', ')})`;\r\n case 'conic':\r\n return `conic-gradient(${args}, ${stops.join(', ')})`;\r\n default:\r\n return `linear-gradient(90deg, ${stops.join(', ')})`;\r\n }\r\n}\r\n\r\n/**\r\n * Color resolver with configuration support\r\n */\r\nexport class ColorResolver {\r\n private config: Required<ColorResolverConfig>;\r\n\r\n constructor(config: ColorResolverConfig = {}) {\r\n this.config = {\r\n prefix: config.prefix || 'sky',\r\n useColorMix: config.useColorMix ?? true,\r\n };\r\n }\r\n\r\n /**\r\n * Resolves a color with prefix-aware variable names\r\n */\r\n resolve(input: string): string {\r\n if (input.startsWith('#')) return input;\r\n if (input.startsWith('rgb') || input.startsWith('hsl')) return input;\r\n if (input.startsWith('var(')) return input;\r\n\r\n const customVar = `var(--${this.config.prefix}-${input})`;\r\n const defaultResolved = DEFAULT_COLOR_TOKENS[input];\r\n\r\n return defaultResolved || customVar || DEFAULT_COLOR_TOKENS.primary;\r\n }\r\n\r\n /**\r\n * Gets text color for a background color\r\n */\r\n getTextColor(backgroundColor: string): string {\r\n // If it's a token, use the token-based logic\r\n if (backgroundColor in DEFAULT_COLOR_TOKENS) {\r\n return resolveTextColorForToken(backgroundColor);\r\n }\r\n\r\n // For custom colors, return a sensible default\r\n return 'var(--sky-text-white)';\r\n }\r\n\r\n /**\r\n * Creates a hover state color\r\n */\r\n getHoverColor(baseColor: string, darkenAmount: number = 20): string {\r\n if (!this.config.useColorMix) {\r\n // Fallback for browsers without color-mix support\r\n return baseColor;\r\n }\r\n\r\n return hoverShade(baseColor, darkenAmount);\r\n }\r\n}\r\n\r\n/**\r\n * Singleton instance for convenience\r\n */\r\nexport const colorResolver = new ColorResolver();\r\n\r\n"],"names":["DEFAULT_COLOR_TOKENS","primary","active","secondary","success","danger","warning","info","light","dark","muted","default","resolveColor","input","customMap","map","resolveTextColorForToken","isDefaultColorToken","resolveInkColorForToken","resolveAccentColorForToken","SEMANTIC_SURFACE_KEYS","resolveSemanticSurfaceKey","colorToken","semanticSoftSurfaceTokens","semanticKey","options","bg","color","border","bordered","skyBorderPrimaryShorthand","skyBorderWidthSolid","widthPx","DEFAULT_COLOR_VARIANT_PATCHES","shadow","hoverBg","hoverColor","hoverShadow","arrow","solid","faded","hoverBorder","transparent","flat","ghost","link","tuneSurfaceVariantForDefaultColor","variant","styles","patch","hoverShade","amount","darkShade","lightShade","fadeMix","resolveGradientStop","stop","match","head","parseGradientSpec","raw","trim","idx","indexOf","prefix","stopsStr","slice","kind","args","k","a","split","s","kLower","toLowerCase","stops","filter","Boolean","createGradient","specStr","fallbackColor","spec","length","st","join","ColorResolver","constructor","config","this","useColorMix","resolve","startsWith","customVar","getTextColor","backgroundColor","getHoverColor","baseColor","darkenAmount","colorResolver"],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS `contrast-color()` helpers for solid fills, plus JS luminance helpers
|
|
3
|
+
* for canvas / SVG / preview surfaces where native CSS contrast cannot apply.
|
|
4
|
+
*
|
|
5
|
+
* Use only on opaque / solid surfaces. Soft tints, glass, and hover washes
|
|
6
|
+
* should keep theme ink tokens (`--sky-text-primary`, soft semantic darks).
|
|
7
|
+
*
|
|
8
|
+
* Always declare a CSS fallback first; wrap the enhance rule in `@supports`.
|
|
9
|
+
*
|
|
10
|
+
* @see components-raw/CONTRAST_COLOR_AUDIT_PLAN.md
|
|
11
|
+
*/
|
|
12
|
+
export type RgbChannels = {
|
|
13
|
+
r: number;
|
|
14
|
+
g: number;
|
|
15
|
+
b: number;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Parse `#rgb` / `#rrggbb` / `rgb()` / `rgba()` into 0–255 channels.
|
|
19
|
+
* Returns `null` for CSS vars, named colors, oklch, etc.
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseCssRgb(color: string): RgbChannels | null;
|
|
22
|
+
/**
|
|
23
|
+
* Rec.601 perceived luminance in 0–1 (matches historical chart/theme-gen usage).
|
|
24
|
+
*/
|
|
25
|
+
export declare function perceivedLuminance(rgb: RgbChannels): number;
|
|
26
|
+
/** WCAG 2.1 relative luminance in 0–1. */
|
|
27
|
+
export declare function relativeLuminance(rgb: RgbChannels): number;
|
|
28
|
+
export type LuminanceMode = "perceived" | "wcag";
|
|
29
|
+
/**
|
|
30
|
+
* True when the fill is “light” enough that dark FG/overlays read better.
|
|
31
|
+
* Unparseable colors return `false` (assume dark fill / light FG).
|
|
32
|
+
*/
|
|
33
|
+
export declare function isLightFill(color: string, threshold?: number, mode?: LuminanceMode): boolean;
|
|
34
|
+
export type ContrastOnFillOptions = {
|
|
35
|
+
/** Returned / used when the fill is light. */
|
|
36
|
+
onLight?: string;
|
|
37
|
+
/** Returned / used when the fill is dark. */
|
|
38
|
+
onDark?: string;
|
|
39
|
+
/** Luminance cutover. Default `0.5`. */
|
|
40
|
+
threshold?: number;
|
|
41
|
+
/** Default `perceived` (Rec.601). Use `wcag` for AA-aligned picks. */
|
|
42
|
+
mode?: LuminanceMode;
|
|
43
|
+
/** When parse fails. Defaults to `onDark`. */
|
|
44
|
+
fallback?: string;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Pick an opaque FG string for canvas / SVG paints against a solid fill.
|
|
48
|
+
* Defaults: black on light fills, white on dark fills.
|
|
49
|
+
*/
|
|
50
|
+
export declare function contrastOnFill(color: string, options?: ContrastOnFillOptions): string;
|
|
51
|
+
/**
|
|
52
|
+
* Semi-transparent overlay for patterns / ripples on a solid fill.
|
|
53
|
+
*/
|
|
54
|
+
export declare function contrastOverlay(color: string, options?: ContrastOnFillOptions): string;
|
|
55
|
+
/**
|
|
56
|
+
* Theme preview ink: primary on light swatches, inverse on dark.
|
|
57
|
+
* Unparseable / non-hex CSS values fall back to `onLight` (theme text).
|
|
58
|
+
*/
|
|
59
|
+
export declare function contrastThemeInk(color: string, options?: ContrastOnFillOptions): string;
|
|
60
|
+
/** Feature query used by every `@supports` enhance block. */
|
|
61
|
+
export declare const CONTRAST_COLOR_SUPPORT_QUERY: "(color: contrast-color(red))";
|
|
62
|
+
/** Fallback FG when the fill is assumed dark (most brand solids). */
|
|
63
|
+
export declare const ON_COLOR_FALLBACK_LIGHT: "var(--sky-on-color-fallback-light, var(--sky-text-white))";
|
|
64
|
+
/** Fallback FG when the fill is assumed light (e.g. warning / success). */
|
|
65
|
+
export declare const ON_COLOR_FALLBACK_DARK: "var(--sky-on-color-fallback-dark, var(--sky-text-black))";
|
|
66
|
+
/**
|
|
67
|
+
* Returns `contrast-color(var(--fill))` (or `contrast-color(<color>)`).
|
|
68
|
+
*/
|
|
69
|
+
export declare function cssContrastColor(fillVar: string): string;
|
|
70
|
+
export type CssOnFillOptions = {
|
|
71
|
+
/**
|
|
72
|
+
* Selector whose `color` should follow the fill
|
|
73
|
+
* (e.g. `.chip`, `button`, `:host([variant="solid"]) button`).
|
|
74
|
+
*/
|
|
75
|
+
selector: string;
|
|
76
|
+
/**
|
|
77
|
+
* Fill custom property or `var()` expression to contrast against
|
|
78
|
+
* (e.g. `--chip-bg-color`, `var(--btn-bg-color)`).
|
|
79
|
+
*/
|
|
80
|
+
fillVar: string;
|
|
81
|
+
/**
|
|
82
|
+
* Pre-`@supports` fallback. Defaults to on-color light (white) token.
|
|
83
|
+
* Pass `false` to omit the fallback declaration (when the selector already sets `color`).
|
|
84
|
+
*/
|
|
85
|
+
fallback?: string | false;
|
|
86
|
+
/**
|
|
87
|
+
* Appended to `selector` inside `@supports` only
|
|
88
|
+
* (e.g. `:not([data-text-explicit])`).
|
|
89
|
+
*/
|
|
90
|
+
enhanceSuffix?: string;
|
|
91
|
+
/** CSS property to set. Default `color`. */
|
|
92
|
+
property?: string;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Fallback-first + `@supports` enhance block for a solid fill foreground.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```ts
|
|
99
|
+
* css`
|
|
100
|
+
* ${unsafeCSS(cssOnFill({
|
|
101
|
+
* selector: ".chip",
|
|
102
|
+
* fillVar: "--chip-bg-color",
|
|
103
|
+
* fallback: "var(--chip-text-color)",
|
|
104
|
+
* enhanceSuffix: ":not([data-text-explicit])",
|
|
105
|
+
* }))}
|
|
106
|
+
* `
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
export declare function cssOnFill(options: CssOnFillOptions): string;
|
|
110
|
+
/**
|
|
111
|
+
* Multi-rule `@supports` enhance only (no fallback declarations).
|
|
112
|
+
* Use when selectors already set fallback `color` via other rules / inline vars.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* css`
|
|
117
|
+
* button { color: var(--btn-color); }
|
|
118
|
+
* ${unsafeCSS(cssOnFillEnhance([
|
|
119
|
+
* { selector: ':host([variant="solid"]:not([data-text-explicit])) button', fillVar: '--btn-bg-color' },
|
|
120
|
+
* ]))}
|
|
121
|
+
* `
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export declare function cssOnFillEnhance(rules: Array<{
|
|
125
|
+
selector: string;
|
|
126
|
+
fillVar: string;
|
|
127
|
+
property?: string;
|
|
128
|
+
}>): string;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function r(r){const t=r.trim();if(!t)return null;if(t.startsWith("#")){const r=t.slice(1);if(3===r.length||4===r.length){const t=parseInt(r[0]+r[0],16),n=parseInt(r[1]+r[1],16),e=parseInt(r[2]+r[2],16);return[t,n,e].some(r=>Number.isNaN(r))?null:{r:t,g:n,b:e}}if(6===r.length||8===r.length){const t=parseInt(r.slice(0,2),16),n=parseInt(r.slice(2,4),16),e=parseInt(r.slice(4,6),16);return[t,n,e].some(r=>Number.isNaN(r))?null:{r:t,g:n,b:e}}return null}const n=t.match(/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i);return n?{r:Math.min(255,Math.max(0,Number(n[1]))),g:Math.min(255,Math.max(0,Number(n[2]))),b:Math.min(255,Math.max(0,Number(n[3])))}:null}function t(r){return(.299*r.r+.587*r.g+.114*r.b)/255}function n(r){const t=r/255;return t<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4)}function e(r){return.2126*n(r.r)+.7152*n(r.g)+.0722*n(r.b)}function o(r,n="perceived"){return"wcag"===n?e(r):t(r)}function a(t,n=.5,e="perceived"){const a=r(t);return!!a&&o(a,e)>n}function s(t,n={}){const{onLight:e="#000000",onDark:a="#ffffff",threshold:s=.5,mode:c="perceived",fallback:i=a}=n,l=r(t);return l?o(l,c)>s?e:a:i}function c(r,t={}){return s(r,{onLight:"rgba(0,0,0,0.55)",onDark:"rgba(255,255,255,0.6)",threshold:.5,mode:"perceived",...t})}function i(r,t={}){return s(r,{onLight:"var(--sky-text-primary)",onDark:"var(--sky-text-inverse)",threshold:.6,mode:"perceived",fallback:"var(--sky-text-primary)",...t})}const l="(color: contrast-color(red))",u="var(--sky-on-color-fallback-light, var(--sky-text-white))",f="var(--sky-on-color-fallback-dark, var(--sky-text-black))";function h(r){const t=r.trim();return t.startsWith("var(")?t:t.startsWith("--")?`var(${t})`:t}function p(r){return`contrast-color(${h(r)})`}function m(r){const{selector:t,fillVar:n,fallback:e=u,enhanceSuffix:o="",property:a="color"}=r,s=h(n);return`${!1===e?"":`${t} {\n ${a}: ${e};\n}\n`}@supports ${l} {\n ${`${t}${o}`} {\n ${a}: ${p(s)};\n }\n}`}function b(r){if(!r.length)return"";const t=r.map(({selector:r,fillVar:t,property:n="color"})=>` ${r} {\n ${n}: ${p(t)};\n }`).join("\n");return`@supports ${l} {\n${t}\n}`}export{l as CONTRAST_COLOR_SUPPORT_QUERY,f as ON_COLOR_FALLBACK_DARK,u as ON_COLOR_FALLBACK_LIGHT,s as contrastOnFill,c as contrastOverlay,i as contrastThemeInk,p as cssContrastColor,m as cssOnFill,b as cssOnFillEnhance,a as isLightFill,r as parseCssRgb,t as perceivedLuminance,e as relativeLuminance};
|
|
2
|
+
//# sourceMappingURL=contrast-color.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contrast-color.js","sources":["../../../src/helper/utils/contrast-color.ts"],"sourcesContent":["/**\n * CSS `contrast-color()` helpers for solid fills, plus JS luminance helpers\n * for canvas / SVG / preview surfaces where native CSS contrast cannot apply.\n *\n * Use only on opaque / solid surfaces. Soft tints, glass, and hover washes\n * should keep theme ink tokens (`--sky-text-primary`, soft semantic darks).\n *\n * Always declare a CSS fallback first; wrap the enhance rule in `@supports`.\n *\n * @see components-raw/CONTRAST_COLOR_AUDIT_PLAN.md\n */\n\nexport type RgbChannels = { r: number; g: number; b: number };\n\n/**\n * Parse `#rgb` / `#rrggbb` / `rgb()` / `rgba()` into 0–255 channels.\n * Returns `null` for CSS vars, named colors, oklch, etc.\n */\nexport function parseCssRgb(color: string): RgbChannels | null {\n const trimmed = color.trim();\n if (!trimmed) return null;\n\n if (trimmed.startsWith(\"#\")) {\n const hex = trimmed.slice(1);\n if (hex.length === 3 || hex.length === 4) {\n const r = parseInt(hex[0] + hex[0], 16);\n const g = parseInt(hex[1] + hex[1], 16);\n const b = parseInt(hex[2] + hex[2], 16);\n if ([r, g, b].some((n) => Number.isNaN(n))) return null;\n return { r, g, b };\n }\n if (hex.length === 6 || hex.length === 8) {\n const r = parseInt(hex.slice(0, 2), 16);\n const g = parseInt(hex.slice(2, 4), 16);\n const b = parseInt(hex.slice(4, 6), 16);\n if ([r, g, b].some((n) => Number.isNaN(n))) return null;\n return { r, g, b };\n }\n return null;\n }\n\n const m = trimmed.match(\n /^rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)/i,\n );\n if (!m) return null;\n return {\n r: Math.min(255, Math.max(0, Number(m[1]))),\n g: Math.min(255, Math.max(0, Number(m[2]))),\n b: Math.min(255, Math.max(0, Number(m[3]))),\n };\n}\n\n/**\n * Rec.601 perceived luminance in 0–1 (matches historical chart/theme-gen usage).\n */\nexport function perceivedLuminance(rgb: RgbChannels): number {\n return (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;\n}\n\nfunction srgbChannelToLinear(v: number): number {\n const c = v / 255;\n return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n}\n\n/** WCAG 2.1 relative luminance in 0–1. */\nexport function relativeLuminance(rgb: RgbChannels): number {\n return (\n 0.2126 * srgbChannelToLinear(rgb.r) +\n 0.7152 * srgbChannelToLinear(rgb.g) +\n 0.0722 * srgbChannelToLinear(rgb.b)\n );\n}\n\nexport type LuminanceMode = \"perceived\" | \"wcag\";\n\nfunction luminanceOf(\n rgb: RgbChannels,\n mode: LuminanceMode = \"perceived\",\n): number {\n return mode === \"wcag\" ? relativeLuminance(rgb) : perceivedLuminance(rgb);\n}\n\n/**\n * True when the fill is “light” enough that dark FG/overlays read better.\n * Unparseable colors return `false` (assume dark fill / light FG).\n */\nexport function isLightFill(\n color: string,\n threshold = 0.5,\n mode: LuminanceMode = \"perceived\",\n): boolean {\n const rgb = parseCssRgb(color);\n if (!rgb) return false;\n return luminanceOf(rgb, mode) > threshold;\n}\n\nexport type ContrastOnFillOptions = {\n /** Returned / used when the fill is light. */\n onLight?: string;\n /** Returned / used when the fill is dark. */\n onDark?: string;\n /** Luminance cutover. Default `0.5`. */\n threshold?: number;\n /** Default `perceived` (Rec.601). Use `wcag` for AA-aligned picks. */\n mode?: LuminanceMode;\n /** When parse fails. Defaults to `onDark`. */\n fallback?: string;\n};\n\n/**\n * Pick an opaque FG string for canvas / SVG paints against a solid fill.\n * Defaults: black on light fills, white on dark fills.\n */\nexport function contrastOnFill(\n color: string,\n options: ContrastOnFillOptions = {},\n): string {\n const {\n onLight = \"#000000\",\n onDark = \"#ffffff\",\n threshold = 0.5,\n mode = \"perceived\",\n fallback = onDark,\n } = options;\n const rgb = parseCssRgb(color);\n if (!rgb) return fallback;\n return luminanceOf(rgb, mode) > threshold ? onLight : onDark;\n}\n\n/**\n * Semi-transparent overlay for patterns / ripples on a solid fill.\n */\nexport function contrastOverlay(\n color: string,\n options: ContrastOnFillOptions = {},\n): string {\n return contrastOnFill(color, {\n onLight: \"rgba(0,0,0,0.55)\",\n onDark: \"rgba(255,255,255,0.6)\",\n threshold: 0.5,\n mode: \"perceived\",\n ...options,\n });\n}\n\n/**\n * Theme preview ink: primary on light swatches, inverse on dark.\n * Unparseable / non-hex CSS values fall back to `onLight` (theme text).\n */\nexport function contrastThemeInk(\n color: string,\n options: ContrastOnFillOptions = {},\n): string {\n return contrastOnFill(color, {\n onLight: \"var(--sky-text-primary)\",\n onDark: \"var(--sky-text-inverse)\",\n threshold: 0.6,\n mode: \"perceived\",\n fallback: \"var(--sky-text-primary)\",\n ...options,\n });\n}\n\n/** Feature query used by every `@supports` enhance block. */\nexport const CONTRAST_COLOR_SUPPORT_QUERY = \"(color: contrast-color(red))\" as const;\n\n/** Fallback FG when the fill is assumed dark (most brand solids). */\nexport const ON_COLOR_FALLBACK_LIGHT = \"var(--sky-on-color-fallback-light, var(--sky-text-white))\" as const;\n\n/** Fallback FG when the fill is assumed light (e.g. warning / success). */\nexport const ON_COLOR_FALLBACK_DARK = \"var(--sky-on-color-fallback-dark, var(--sky-text-black))\" as const;\n\nfunction asCssVarRef(fillVar: string): string {\n const trimmed = fillVar.trim();\n if (trimmed.startsWith(\"var(\")) return trimmed;\n if (trimmed.startsWith(\"--\")) return `var(${trimmed})`;\n return trimmed;\n}\n\n/**\n * Returns `contrast-color(var(--fill))` (or `contrast-color(<color>)`).\n */\nexport function cssContrastColor(fillVar: string): string {\n return `contrast-color(${asCssVarRef(fillVar)})`;\n}\n\nexport type CssOnFillOptions = {\n /**\n * Selector whose `color` should follow the fill\n * (e.g. `.chip`, `button`, `:host([variant=\"solid\"]) button`).\n */\n selector: string;\n /**\n * Fill custom property or `var()` expression to contrast against\n * (e.g. `--chip-bg-color`, `var(--btn-bg-color)`).\n */\n fillVar: string;\n /**\n * Pre-`@supports` fallback. Defaults to on-color light (white) token.\n * Pass `false` to omit the fallback declaration (when the selector already sets `color`).\n */\n fallback?: string | false;\n /**\n * Appended to `selector` inside `@supports` only\n * (e.g. `:not([data-text-explicit])`).\n */\n enhanceSuffix?: string;\n /** CSS property to set. Default `color`. */\n property?: string;\n};\n\n/**\n * Fallback-first + `@supports` enhance block for a solid fill foreground.\n *\n * @example\n * ```ts\n * css`\n * ${unsafeCSS(cssOnFill({\n * selector: \".chip\",\n * fillVar: \"--chip-bg-color\",\n * fallback: \"var(--chip-text-color)\",\n * enhanceSuffix: \":not([data-text-explicit])\",\n * }))}\n * `\n * ```\n */\nexport function cssOnFill(options: CssOnFillOptions): string {\n const {\n selector,\n fillVar,\n fallback = ON_COLOR_FALLBACK_LIGHT,\n enhanceSuffix = \"\",\n property = \"color\",\n } = options;\n\n const fill = asCssVarRef(fillVar);\n const enhanceSelector = `${selector}${enhanceSuffix}`;\n const fallbackRule =\n fallback === false\n ? \"\"\n : `${selector} {\\n ${property}: ${fallback};\\n}\\n`;\n\n return `${fallbackRule}@supports ${CONTRAST_COLOR_SUPPORT_QUERY} {\n ${enhanceSelector} {\n ${property}: ${cssContrastColor(fill)};\n }\n}`;\n}\n\n/**\n * Multi-rule `@supports` enhance only (no fallback declarations).\n * Use when selectors already set fallback `color` via other rules / inline vars.\n *\n * @example\n * ```ts\n * css`\n * button { color: var(--btn-color); }\n * ${unsafeCSS(cssOnFillEnhance([\n * { selector: ':host([variant=\"solid\"]:not([data-text-explicit])) button', fillVar: '--btn-bg-color' },\n * ]))}\n * `\n * ```\n */\nexport function cssOnFillEnhance(\n rules: Array<{\n selector: string;\n fillVar: string;\n property?: string;\n }>,\n): string {\n if (!rules.length) return \"\";\n\n const body = rules\n .map(({ selector, fillVar, property = \"color\" }) => {\n return ` ${selector} {\\n ${property}: ${cssContrastColor(fillVar)};\\n }`;\n })\n .join(\"\\n\");\n\n return `@supports ${CONTRAST_COLOR_SUPPORT_QUERY} {\\n${body}\\n}`;\n}\n"],"names":["parseCssRgb","color","trimmed","trim","startsWith","hex","slice","length","r","parseInt","g","b","some","n","Number","isNaN","m","match","Math","min","max","perceivedLuminance","rgb","srgbChannelToLinear","v","c","pow","relativeLuminance","luminanceOf","mode","isLightFill","threshold","contrastOnFill","options","onLight","onDark","fallback","contrastOverlay","contrastThemeInk","CONTRAST_COLOR_SUPPORT_QUERY","ON_COLOR_FALLBACK_LIGHT","ON_COLOR_FALLBACK_DARK","asCssVarRef","fillVar","cssContrastColor","cssOnFill","selector","enhanceSuffix","property","fill","cssOnFillEnhance","rules","body","map","join"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{ColorResolver,DEFAULT_COLOR_TOKENS,colorResolver,createGradient,darkShade,fadeMix,hoverShade,isDefaultColorToken,lightShade,parseGradientSpec,resolveAccentColorForToken,resolveColor,resolveGradientStop,resolveInkColorForToken,resolveSemanticSurfaceKey,resolveTextColorForToken,semanticSoftSurfaceTokens,skyBorderPrimaryShorthand,skyBorderWidthSolid,tuneSurfaceVariantForDefaultColor}from"./color-resolver.js";export{resolveRadius}from"./size-resolver.js";
|
|
1
|
+
export{ColorResolver,DEFAULT_COLOR_TOKENS,colorResolver,createGradient,darkShade,fadeMix,hoverShade,isDefaultColorToken,lightShade,parseGradientSpec,resolveAccentColorForToken,resolveColor,resolveGradientStop,resolveInkColorForToken,resolveSemanticSurfaceKey,resolveTextColorForToken,semanticSoftSurfaceTokens,skyBorderPrimaryShorthand,skyBorderWidthSolid,tuneSurfaceVariantForDefaultColor}from"./color-resolver.js";export{CONTRAST_COLOR_SUPPORT_QUERY,ON_COLOR_FALLBACK_DARK,ON_COLOR_FALLBACK_LIGHT,contrastOnFill,contrastOverlay,contrastThemeInk,cssContrastColor,cssOnFill,cssOnFillEnhance,isLightFill,parseCssRgb,perceivedLuminance,relativeLuminance}from"./contrast-color.js";export{resolveRadius}from"./size-resolver.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{html}from"lit";export{AnimationController}from"./helper/controllers/animation-controller.js";export{ColorResolver,DEFAULT_COLOR_TOKENS,colorResolver,createGradient,darkShade,fadeMix,hoverShade,isDefaultColorToken,lightShade,parseGradientSpec,resolveAccentColorForToken,resolveColor,resolveGradientStop,resolveInkColorForToken,resolveSemanticSurfaceKey,resolveTextColorForToken,semanticSoftSurfaceTokens,skyBorderPrimaryShorthand,skyBorderWidthSolid,tuneSurfaceVariantForDefaultColor}from"./helper/utils/color-resolver.js";export{FormControlBase}from"./helper/internals/form-control-base.js";export{PopoverController}from"./helper/controllers/popover-controller.js";export{SkyAlert}from"./sky-alert/sky-alert.js";export{SkyAppbar}from"./sky-appbar/sky-appbar.js";export{SkyAvatar}from"./sky-avatar/sky-avatar.js";export{SkyBadge}from"./sky-badge/sky-badge.js";export{SkyButton}from"./sky-button/sky-button.js";export{SkyCard}from"./sky-card/sky-card.js";export{SkyCheckbox}from"./sky-checkbox/sky-checkbox.js";export{SkyChip}from"./sky-chip/sky-chip.js";export{SkyCol}from"./sky-col/sky-col.js";export{SkyCombobox}from"./sky-combobox/sky-combobox.js";export{SkyDialog}from"./sky-dialog/sky-dialog.js";export{SkyDivider}from"./sky-divider/sky-divider.js";export{SkyFlexbox}from"./sky-flexbox/sky-flexbox.js";export{SkyFlexcol}from"./sky-flexcol/sky-flexcol.js";export{SkyForm}from"./sky-form/sky-form.js";export{SkyGrid}from"./sky-grid/sky-grid.js";export{SkyIcon}from"./sky-icon/sky-icon.js";export{SkyImage}from"./sky-image/sky-image.js";export{SkyInput}from"./sky-input/sky-input.js";export{SkyList}from"./sky-list/sky-list.js";export{SkyListitem}from"./sky-listitem/sky-listitem.js";export{SkyRadio}from"./sky-radio/sky-radio.js";export{SkyRow}from"./sky-row/sky-row.js";export{SkySheet,resolveSheetRadius}from"./sky-sheet/sky-sheet.js";export{SkySimpleTable}from"./sky-simple-table/sky-simple-table.js";export{SkyThemeProvider,defaultTheme,getCurrentTheme,getThemePreference,mergeTheme,onThemeChange,resolveActualTheme,themeContext}from"./sky-theme-provider/sky-theme-provider.js";export{extractIconNames,fetchIconsForOffline,registerOfflineIcons}from"./helper/iconify-offline.js";export{resolveRadius}from"./helper/utils/size-resolver.js";
|
|
1
|
+
export{html}from"lit";export{AnimationController}from"./helper/controllers/animation-controller.js";export{CONTRAST_COLOR_SUPPORT_QUERY,ON_COLOR_FALLBACK_DARK,ON_COLOR_FALLBACK_LIGHT,contrastOnFill,contrastOverlay,contrastThemeInk,cssContrastColor,cssOnFill,cssOnFillEnhance,isLightFill,parseCssRgb,perceivedLuminance,relativeLuminance}from"./helper/utils/contrast-color.js";export{ColorResolver,DEFAULT_COLOR_TOKENS,colorResolver,createGradient,darkShade,fadeMix,hoverShade,isDefaultColorToken,lightShade,parseGradientSpec,resolveAccentColorForToken,resolveColor,resolveGradientStop,resolveInkColorForToken,resolveSemanticSurfaceKey,resolveTextColorForToken,semanticSoftSurfaceTokens,skyBorderPrimaryShorthand,skyBorderWidthSolid,tuneSurfaceVariantForDefaultColor}from"./helper/utils/color-resolver.js";export{FormControlBase}from"./helper/internals/form-control-base.js";export{PopoverController}from"./helper/controllers/popover-controller.js";export{SkyAlert}from"./sky-alert/sky-alert.js";export{SkyAppbar}from"./sky-appbar/sky-appbar.js";export{SkyAvatar}from"./sky-avatar/sky-avatar.js";export{SkyBadge}from"./sky-badge/sky-badge.js";export{SkyButton}from"./sky-button/sky-button.js";export{SkyCard}from"./sky-card/sky-card.js";export{SkyCheckbox}from"./sky-checkbox/sky-checkbox.js";export{SkyChip}from"./sky-chip/sky-chip.js";export{SkyCol}from"./sky-col/sky-col.js";export{SkyCombobox}from"./sky-combobox/sky-combobox.js";export{SkyDialog}from"./sky-dialog/sky-dialog.js";export{SkyDivider}from"./sky-divider/sky-divider.js";export{SkyFlexbox}from"./sky-flexbox/sky-flexbox.js";export{SkyFlexcol}from"./sky-flexcol/sky-flexcol.js";export{SkyForm}from"./sky-form/sky-form.js";export{SkyGrid}from"./sky-grid/sky-grid.js";export{SkyIcon}from"./sky-icon/sky-icon.js";export{SkyImage}from"./sky-image/sky-image.js";export{SkyInput}from"./sky-input/sky-input.js";export{SkyList}from"./sky-list/sky-list.js";export{SkyListitem}from"./sky-listitem/sky-listitem.js";export{SkyRadio}from"./sky-radio/sky-radio.js";export{SkyRow}from"./sky-row/sky-row.js";export{SkySheet,resolveSheetRadius}from"./sky-sheet/sky-sheet.js";export{SkySimpleTable}from"./sky-simple-table/sky-simple-table.js";export{SkyThemeProvider,defaultTheme,getCurrentTheme,getThemePreference,mergeTheme,onThemeChange,resolveActualTheme,themeContext}from"./sky-theme-provider/sky-theme-provider.js";export{extractIconNames,fetchIconsForOffline,registerOfflineIcons}from"./helper/iconify-offline.js";export{resolveRadius}from"./helper/utils/size-resolver.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{unsafeCSS as t,css as e,LitElement as r,html as i}from"lit";import{property as o,state as s,customElement as n}from"lit/decorators.js";import{styleMap as a}from"lit/directives/style-map.js";import{classMap as l}from"lit/directives/class-map.js";import{when as p}from"lit/directives/when.js";import{resolveRadius as d}from"../helper/utils/size-resolver.js";import{resolveColor as c,resolveTextColorForToken as h,resolveSemanticSurfaceKey as g,semanticSoftSurfaceTokens as y,tuneSurfaceVariantForDefaultColor as m,isDefaultColorToken as v,skyBorderPrimaryShorthand as b,hoverShade as x,fadeMix as f}from"../helper/utils/color-resolver.js";import{cssOnFillEnhance as u}from"../helper/utils/contrast-color.js";import{SkyIcon as k}from"../sky-icon/sky-icon.js";var z=Object.defineProperty,S=Object.getOwnPropertyDescriptor,C=(t,e,r,i)=>{for(var o,s=i>1?void 0:i?S(e,r):e,n=t.length-1;n>=0;n--)(o=t[n])&&(s=(i?o(e,r,s):o(s))||s);return i&&s&&z(e,r,s),s};let $=class extends r{constructor(){super(...arguments),this.title="",this.message="",this.removable=!1,this.color="primary",this.size="md",this.radius="md",this.icon=null,this.strip="none",this.stripColor="currentColor",this.variant="solid",this.loading=!1,this.roleType="alert",this._styleVars={},this._sizeCache=null,this._hasActionsSlotContent=!1}_resolveSize(t){const e=String(t).trim();if(this._sizeCache&&this._sizeCache.size===e)return this._sizeCache.result;const r={xs:{padding:"3px 7px",titleFontSize:"12px",messageFontSize:"11px",gap:"4px",icon:"14px",closeSize:"18px",closeFontSize:"12px",spinner:"12px",stripWidth:"2px",minHeight:"28px"},sm:{padding:"5px 9px",titleFontSize:"14px",messageFontSize:"13px",gap:"6px",icon:"16px",closeSize:"20px",closeFontSize:"14px",spinner:"14px",stripWidth:"3px",minHeight:"32px"},md:{padding:"8px 12px",titleFontSize:"16px",messageFontSize:"14px",gap:"8px",icon:"20px",closeSize:"24px",closeFontSize:"16px",spinner:"16px",stripWidth:"4px",minHeight:"36px"},lg:{padding:"10px 14px",titleFontSize:"18px",messageFontSize:"15px",gap:"10px",icon:"22px",closeSize:"28px",closeFontSize:"18px",spinner:"18px",stripWidth:"5px",minHeight:"40px"},xl:{padding:"12px 16px",titleFontSize:"20px",messageFontSize:"16px",gap:"12px",icon:"24px",closeSize:"32px",closeFontSize:"20px",spinner:"20px",stripWidth:"6px",minHeight:"44px"}};if(r[t])return this._sizeCache={size:e,result:r[t]},r[t];const i=String(t).trim().match(/^([\d.]+)(px|rem|em)?$/i),o=i?.[2]||"px",s=i?parseFloat(i[1]):16,n=t=>`${Math.round(100*t)/100}${o}`,a=(t,e,r)=>Math.max(e,Math.min(r,t)),l=`${s}${o}`,p=a(.875*s,11,16),d=a(.5*s,3,12),c=a(.75*s,7,16),h=a(.5*s,4,12),g=a(1.25*s,14,24),y=a(1.5*s,18,32),m=a(1*s,12,20),v=a(1*s,12,20),b=a(.25*s,2,6),x=a(2.25*s,28,44);return{padding:`${n(d)} ${n(c)}`,titleFontSize:l,messageFontSize:n(p),gap:n(h),icon:n(g),closeSize:n(y),closeFontSize:n(m),spinner:n(v),stripWidth:n(b),minHeight:n(x)}}willUpdate(t){super.willUpdate(t),(t.has("color")||t.has("variant")||t.has("stripColor")||t.has("radius")||t.has("size"))&&this._updateStyleVars()}firstUpdated(){queueMicrotask(()=>this._checkActionsSlot())}_updateStyleVars(){const t=c(this.color),e=h(this.color),r="currentColor"===this.stripColor?t:c(this.stripColor),i=this._resolveSize(this.size),o=g(this.color),s={solid:{bg:t,color:e,border:"none"},flat:o?y(o):{bg:f(t,20),color:x(t,30),border:"none"},faded:o?y(o,{bordered:!0}):{bg:"var(--sky-hover-tertiary)",color:t,border:"1px solid var(--sky-text-tertiary)"},bordered:{bg:"transparent",color:o?`var(--sky-${o}-primary-dark)`:t,border:`2px solid ${t}`},light:{bg:"transparent",color:o?`var(--sky-${o}-primary-dark)`:t,border:"none"}},n=this.variant in s?this.variant:"flat";let a=m(this.color,n,s[n]);!v(this.color)||"flat"!==n&&"faded"!==n||(a={...a,bg:"var(--sky-glass-solid)",color:"var(--sky-text-primary)",border:"faded"===n?b():"none"});let l="var(--sky-hover-primary)",p="currentColor",u="var(--sky-hover-secondary)",k="currentColor";"solid"===n?(l=f(e,20),p=e,u=f(e,30),k=e):"flat"!==n&&"faded"!==n||(o?(l=`var(--sky-${o}-g0)`,p=a.color,u=`var(--sky-${o}-g1)`,k=a.color):v(this.color)?(l="var(--sky-hover-primary)",p=a.color,u="var(--sky-hover-secondary)",k=a.color):(l=f(t,15),p=a.color,u=f(t,25),k=a.color)),this._styleVars={"--alert-bg":a.bg,"--alert-color":a.color,"--alert-border":a.border,"--alert-radius":d(this.radius),"--alert-padding":i.padding,"--alert-gap":i.gap,"--alert-min-height":i.minHeight,"--title-font-size":i.titleFontSize,"--message-font-size":i.messageFontSize,"--icon-size":i.icon,"--close-size":i.closeSize,"--close-font-size":i.closeFontSize,"--spinner-size":i.spinner,"--strip-color":r,"--strip-width":i.stripWidth,"--close-bg":l,"--close-color":p,"--close-hover-bg":u,"--close-hover-color":k}}close(){const t=new CustomEvent("alert-closed",{detail:{title:this.title,message:this.message},bubbles:!0,composed:!0});this.dispatchEvent(t),this.remove()}getAriaRole(){return this.roleType}_checkActionsSlot(){const t=this.renderRoot?.querySelector('slot[name="actions"]');if(!t)return;const e=t.assignedNodes({flatten:!0}).some(t=>t.nodeType!==Node.TEXT_NODE||(t.textContent?.trim().length??0)>0);e!==this._hasActionsSlotContent&&(this._hasActionsSlotContent=e)}_onActionsSlotChange(t){const e=t.target.assignedNodes({flatten:!0}).some(t=>t.nodeType!==Node.TEXT_NODE||(t.textContent?.trim().length??0)>0);this._hasActionsSlotContent=e}render(){const t=this.getAriaRole(),e=l({alert:!0,[this.variant]:!0,"strip-start":"start"===this.strip||"both"===this.strip,"strip-end":"end"===this.strip||"both"===this.strip});return i`
|
|
2
2
|
<div
|
|
3
3
|
part="alert"
|
|
4
4
|
class=${e}
|
|
5
5
|
role="${t}"
|
|
6
6
|
aria-live="${"alert"===this.roleType?"assertive":"polite"}"
|
|
7
|
-
style=${
|
|
7
|
+
style=${a(this._styleVars)}
|
|
8
8
|
>
|
|
9
|
-
${
|
|
9
|
+
${p(this.icon,()=>i`<sky-icon part="icon" class="icon" icon="${this.icon}"></sky-icon>`)}
|
|
10
10
|
|
|
11
11
|
<div part="content" class="content">
|
|
12
|
-
${
|
|
13
|
-
${
|
|
12
|
+
${p(this.title,()=>i`<div part="title" class="title">${this.title}</div>`)}
|
|
13
|
+
${p(this.message,()=>i`<p part="message" class="message">${this.message}</p>`,()=>i`<slot></slot>`)}
|
|
14
14
|
</div>
|
|
15
15
|
|
|
16
|
-
${
|
|
16
|
+
${p(this._hasActionsSlotContent||this.removable,()=>i`
|
|
17
17
|
<div part="actions" class="actions">
|
|
18
18
|
<slot name="actions" @slotchange=${this._onActionsSlotChange}></slot>
|
|
19
|
-
${
|
|
19
|
+
${p(this.removable,()=>i`
|
|
20
20
|
<button
|
|
21
21
|
part="close-button"
|
|
22
22
|
class="close-button"
|
|
@@ -29,19 +29,19 @@ import{css as t,LitElement as e,html as r}from"lit";import{property as i,state a
|
|
|
29
29
|
</button>
|
|
30
30
|
`)}
|
|
31
31
|
</div>
|
|
32
|
-
`,()=>
|
|
32
|
+
`,()=>i`
|
|
33
33
|
<div class="actions-slot-placeholder" aria-hidden="true">
|
|
34
34
|
<slot name="actions" @slotchange=${this._onActionsSlotChange}></slot>
|
|
35
35
|
</div>
|
|
36
36
|
`)}
|
|
37
37
|
|
|
38
|
-
${
|
|
38
|
+
${p(this.loading,()=>i`
|
|
39
39
|
<div part="loading-overlay" class="loading-overlay">
|
|
40
40
|
<div part="loading-spinner" class="loading-spinner"></div>
|
|
41
41
|
</div>
|
|
42
42
|
`)}
|
|
43
43
|
</div>
|
|
44
|
-
`}}
|
|
44
|
+
`}};$.dependencies={"sky-icon":k},$.styles=e`
|
|
45
45
|
:host {
|
|
46
46
|
display: block;
|
|
47
47
|
font-family: var(--sky-font);
|
|
@@ -278,5 +278,7 @@ import{css as t,LitElement as e,html as r}from"lit";import{property as i,state a
|
|
|
278
278
|
transform: translateY(0);
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
|
-
|
|
281
|
+
|
|
282
|
+
${t(u([{selector:".alert.solid",fillVar:"--alert-bg"}]))}
|
|
283
|
+
`,C([o({type:String})],$.prototype,"title",2),C([o({type:String})],$.prototype,"message",2),C([o({type:Boolean})],$.prototype,"removable",2),C([o({type:String})],$.prototype,"color",2),C([o({type:String})],$.prototype,"size",2),C([o({type:String})],$.prototype,"radius",2),C([o({type:String})],$.prototype,"icon",2),C([o({type:String,reflect:!0})],$.prototype,"strip",2),C([o({type:String})],$.prototype,"stripColor",2),C([o({type:String,reflect:!0})],$.prototype,"variant",2),C([o({type:Boolean})],$.prototype,"loading",2),C([o({type:String,reflect:!0})],$.prototype,"roleType",2),C([s()],$.prototype,"_hasActionsSlotContent",2),$=C([n("sky-alert")],$);export{$ as SkyAlert};
|
|
282
284
|
//# sourceMappingURL=sky-alert.js.map
|