UNPKG

@dvcol/neo-svelte

Version:

Neomorphic ui library for svelte 5

88 lines (87 loc) 3.77 kB
import { clamp } from '@dvcol/common-utils/common/math'; import { NeoTextButton } from '../buttons/neo-button.model.js'; export const MaxShadowElevation = 5; export const MinShadowElevation = -5; export const MaxShallowShadowElevation = 3; export const MinShallowShadowElevation = -3; export const DefaultShallowMinMaxElevation = { max: MaxShallowShadowElevation, min: MinShallowShadowElevation, }; export const DefaultShadowElevation = 3; export const DefaultShadowActiveElevation = -2; export const DefaultShadowPressedElevation = -2; export const ShadowElevations = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]; export const DefaultShadowHoverElevation = -1; export const DefaultShadowHoverPressedElevation = 0; export const ShadowHoverElevations = [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; export const DefaultShadowShallowElevation = 2; export const ShadowShallowElevations = [-3, -2, -1, 0, 1, 2, 3]; export const PositiveShadowElevations = [0, 1, 2, 3, 4, 5]; export const PositiveMinMaxElevation = { min: 0, max: MaxShadowElevation }; export const BlurElevations = [0, 1, 2, 3, 4, 5]; export const ShadowFlatRegex = /^.*flat\)?;?$/; export const DefaultSaturation = 3; export function getDefaultElevation(pressed, fallback = DefaultShadowElevation) { return pressed ? DefaultShadowPressedElevation : fallback; } export function getDefaultHoverElevation(pressed, fallback = DefaultShadowHoverElevation) { return pressed ? DefaultShadowHoverPressedElevation : fallback; } export function getDefaultSlideElevation(elevation, fallback = DefaultShadowPressedElevation) { if (elevation < 0) return Math.abs(elevation); return fallback; } export function coerce(elevation, { min, max } = {}) { if (elevation === undefined || elevation === null) return elevation; const _elevation = Number(elevation); if (min !== undefined && _elevation < min) return min; if (max !== undefined && _elevation > max) return max; return _elevation; } export function parseBlur(blur, elevation, minMax = { min: 1, max: 5 }) { if (!blur || elevation === undefined) return minMax.min ?? 1; return coerce(blur ?? elevation, minMax); } export const isShadowFlat = (shadow) => ShadowFlatRegex.test(shadow); export function computeElevation(elevation, { min = MinShadowElevation, max = MaxShadowElevation } = {}) { if (elevation < min) return min; if (elevation > max) return max; return elevation; } export function computeShadowElevation(elevation, { glass, convex, pressed, active } = {}, minMax = {}) { const raided = convex ? 'convex' : 'raised'; let inset = 'inset'; if (pressed) inset = 'pressed'; if (active) inset = 'active'; let shadow = `var(--neo-${glass ? 'glass-' : ''}box-shadow-`; const level = computeElevation(elevation, minMax); if (!level) return `${shadow}flat)`; shadow += level < 0 ? inset : raided; return `${shadow}-${Math.trunc(Math.abs(level))})`; } export function computeHoverShadowElevation(elevation, hover, options, minMax = {}) { if (!hover) return; return computeShadowElevation(elevation + hover, options, minMax); } export function computeGlassFilter(elevation, glass, { min = 1, max = MaxShadowElevation, saturation = DefaultSaturation } = {}) { if (!glass) return; return `var(--neo-blur-${clamp(Math.abs(elevation), min, max)}) var(--neo-saturate-${saturation})`; } export function computeButtonTemplate(elevation, pressed, text) { if (text || elevation >= 0) return NeoTextButton; return { elevation: Math.min(Math.abs(elevation), 3), hover: 0, active: -2, pressed: true, borderless: true }; }