UNPKG

svelte-ux

Version:

A large collection of Svelte components, actions, stores and utils to simplify creating highly interactive and visual applications. Built using Tailwind with extensibility and customization in mind.

105 lines (104 loc) 3.54 kB
import { getContext, setContext } from 'svelte'; import { writable, derived } from 'svelte/store'; import { BROWSER } from 'esm-env'; import { buildFormatters } from '@layerstack/utils/format'; import { getAllKnownLocales, localeStore, } from '@layerstack/utils/locale'; import { breakpoints } from '@layerstack/svelte-stores'; import { createThemeStore } from '@layerstack/svelte-stores'; import { resolveComponentClasses, } from './theme.js'; const settingsKey = Symbol(); function createLocaleStores(settings) { if (settings.locale && settings.localeSettings && settings.format) { return { locale: settings.locale, localeSettings: settings.localeSettings, format: settings.format, }; } let allLocales = getAllKnownLocales(settings.localeFormats); let locale = localeStore(settings.forceLocale, settings.fallbackLocale); let localeSettings = derived(locale, ($locale) => { let settings = allLocales[$locale]; if (settings) { return settings; } return { ...allLocales.en, locale: $locale, }; }); return { locale, localeSettings, format: derived(localeSettings, buildFormatters), }; } function createShowDrawer() { return writable(BROWSER ? window.innerWidth >= breakpoints.md : true); } export function settings(settings = {}) { const lightThemes = settings.themes ? (settings.themes.light ?? []) : ['light']; const darkThemes = settings.themes ? (settings.themes.dark ?? []) : ['dark']; const currentTheme = // In some cases, `settings` is called again from inside a component. Don't create a new theme store in this case. settings.currentTheme ?? createThemeStore({ light: lightThemes, dark: darkThemes, }); const localeStores = createLocaleStores(settings); const showDrawer = createShowDrawer(); return setContext(settingsKey, { ...settings, themes: { light: lightThemes, dark: darkThemes, }, currentTheme, componentSettingsCache: {}, showDrawer, ...localeStores, }); } let FALLBACK_SETTINGS = null; function getFallbackSettings() { FALLBACK_SETTINGS = FALLBACK_SETTINGS ?? { currentTheme: createThemeStore({ light: [], dark: [] }), componentSettingsCache: {}, showDrawer: createShowDrawer(), ...createLocaleStores({}), }; return FALLBACK_SETTINGS; } export function getSettings() { // in a try/catch to be able to test w/o svelte components try { return getContext(settingsKey) ?? getFallbackSettings(); } catch (error) { return getFallbackSettings(); } } export function resolveComponentSettings(settings, name) { const { classes: themeClasses, ...defaultProps } = settings?.components?.[name] ?? {}; const classes = resolveComponentClasses(themeClasses); const output = { defaults: (defaultProps ?? {}), classes, }; return output; } /** * Returns default component props and classes for a given component. * @param name component name */ export function getComponentSettings(name) { const settings = getSettings(); const existing = settings.componentSettingsCache[name]; if (existing) { return existing; } const output = resolveComponentSettings(settings, name); settings.componentSettingsCache[name] = output; return output; }