UNPKG

@helpwave/hightide

Version:

helpwave's component and theming library

1 lines 6.12 kB
{"version":3,"sources":["../../src/util/news.ts","../../src/hooks/useLanguage.tsx","../../src/hooks/useLocalStorage.tsx"],"sourcesContent":["import { z } from 'zod'\nimport type { Languages } from '../hooks/useLanguage'\nimport { languages } from '../hooks/useLanguage'\n\nexport type News = {\n title: string,\n date: Date,\n description: (string | URL)[],\n externalResource?: URL,\n keys: string[],\n}\n\nexport type LocalizedNews = Record<Languages, News[]>\n\nexport const newsSchema = z.object({\n title: z.string(),\n description: z.string(),\n date: z.string(),\n image: z.string().url().optional(),\n externalResource: z.string().url().optional(),\n keys: z.array(z.string())\n}).transform<News>((obj) => {\n let description: (string | URL)[] = [obj.description]\n if (obj.image) {\n description = [new URL(obj.image), ...description]\n }\n\n return {\n title: obj.title,\n date: new Date(obj.date),\n description,\n externalResource: obj.externalResource ? new URL(obj.externalResource) : undefined,\n keys: obj.keys\n }\n})\n\nexport const newsListSchema = z.array(newsSchema)\n\nexport const localizedNewsSchema = z.record(z.enum(languages), newsListSchema)\n\nexport const filterNews = (localizedNews: News[], requiredKeys: string[]) => {\n return localizedNews.filter(news => requiredKeys.every(value => news.keys.includes(value)))\n}\n","import type { Dispatch, PropsWithChildren, SetStateAction } from 'react'\nimport { createContext, useContext, useEffect, useState } from 'react'\nimport { useLocalStorage } from './useLocalStorage'\n\nexport const languages = ['en', 'de'] as const\nexport type Languages = typeof languages[number]\nexport const languagesLocalNames: Record<Languages, string> = {\n en: 'English',\n de: 'Deutsch',\n}\n\nexport const DEFAULT_LANGUAGE = 'en'\n\nexport type LanguageContextValue = {\n language: Languages,\n setLanguage: Dispatch<SetStateAction<Languages>>,\n}\n\nexport const LanguageContext = createContext<LanguageContextValue>({ language: DEFAULT_LANGUAGE, setLanguage: (v) => v })\n\nexport const useLanguage = () => useContext(LanguageContext)\n\nexport const useLocale = (overWriteLanguage?: Languages) => {\n const { language } = useLanguage()\n const mapping: Record<Languages, string> = {\n en: 'en-US',\n de: 'de-DE'\n }\n return mapping[overWriteLanguage ?? language]\n}\n\ntype ProvideLanguageProps = {\n initialLanguage?: Languages,\n}\n\nexport const ProvideLanguage = ({ initialLanguage, children }: PropsWithChildren<ProvideLanguageProps>) => {\n const [language, setLanguage] = useState<Languages>(initialLanguage ?? DEFAULT_LANGUAGE)\n const [storedLanguage, setStoredLanguage] = useLocalStorage<Languages>('language', initialLanguage ?? DEFAULT_LANGUAGE)\n\n useEffect(() => {\n if(language !== initialLanguage && initialLanguage){\n console.warn('LanguageProvider initial state changed: Prefer using useLanguages\\'s setLanguage instead')\n setLanguage(initialLanguage)\n }\n }, [initialLanguage]) // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n // TODO set locale of html tag here as well\n setStoredLanguage(language)\n }, [language, setStoredLanguage])\n\n useEffect(() => {\n if (storedLanguage !== null) {\n setLanguage(storedLanguage)\n return\n }\n\n const languagesToTestAgainst = Object.values(languages)\n\n const matchingBrowserLanguages = window.navigator.languages\n .map(language => languagesToTestAgainst.find((test) => language === test || language.split('-')[0] === test))\n .filter(entry => entry !== undefined)\n\n if (matchingBrowserLanguages.length === 0) return\n\n const firstMatch = matchingBrowserLanguages[0] as Languages\n setLanguage(firstMatch)\n }, []) // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <LanguageContext.Provider value={{\n language,\n setLanguage\n }}>\n {children}\n </LanguageContext.Provider>\n )\n}\n","import type { Dispatch, SetStateAction } from 'react'\nimport { useCallback, useEffect, useState } from 'react'\nimport { LocalStorageService } from '../util/storage'\n\ntype SetValue<T> = Dispatch<SetStateAction<T>>\nexport const useLocalStorage = <T, >(key: string, initValue: T): [T, SetValue<T>] => {\n const get = useCallback((): T => {\n if (typeof window === 'undefined') {\n return initValue\n }\n const storageService = new LocalStorageService()\n const value = storageService.get<T>(key)\n return value || initValue\n }, [initValue, key])\n\n const [storedValue, setStoredValue] = useState<T>(get)\n\n const setValue: SetValue<T> = useCallback(value => {\n const newValue = value instanceof Function ? value(storedValue) : value\n const storageService = new LocalStorageService()\n storageService.set(key, value)\n\n setStoredValue(newValue)\n }, [storedValue, setStoredValue, key])\n\n useEffect(() => {\n setStoredValue(get())\n }, []) // eslint-disable-line react-hooks/exhaustive-deps\n\n return [storedValue, setValue]\n}"],"mappings":";AAAA,SAAS,SAAS;;;ACClB,SAAS,eAAe,YAAY,aAAAA,YAAW,YAAAC,iBAAgB;;;ACA/D,SAAS,aAAa,WAAW,gBAAgB;;;ADqE7C;AAlEG,IAAM,YAAY,CAAC,MAAM,IAAI;AAO7B,IAAM,mBAAmB;AAOzB,IAAM,kBAAkB,cAAoC,EAAE,UAAU,kBAAkB,aAAa,CAAC,MAAM,EAAE,CAAC;;;ADJjH,IAAM,aAAa,EAAE,OAAO;AAAA,EACjC,OAAO,EAAE,OAAO;AAAA,EAChB,aAAa,EAAE,OAAO;AAAA,EACtB,MAAM,EAAE,OAAO;AAAA,EACf,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACjC,kBAAkB,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EAC5C,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC;AAC1B,CAAC,EAAE,UAAgB,CAAC,QAAQ;AAC1B,MAAI,cAAgC,CAAC,IAAI,WAAW;AACpD,MAAI,IAAI,OAAO;AACb,kBAAc,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG,GAAG,WAAW;AAAA,EACnD;AAEA,SAAO;AAAA,IACL,OAAO,IAAI;AAAA,IACX,MAAM,IAAI,KAAK,IAAI,IAAI;AAAA,IACvB;AAAA,IACA,kBAAkB,IAAI,mBAAmB,IAAI,IAAI,IAAI,gBAAgB,IAAI;AAAA,IACzE,MAAM,IAAI;AAAA,EACZ;AACF,CAAC;AAEM,IAAM,iBAAiB,EAAE,MAAM,UAAU;AAEzC,IAAM,sBAAsB,EAAE,OAAO,EAAE,KAAK,SAAS,GAAG,cAAc;AAEtE,IAAM,aAAa,CAAC,eAAuB,iBAA2B;AAC3E,SAAO,cAAc,OAAO,UAAQ,aAAa,MAAM,WAAS,KAAK,KAAK,SAAS,KAAK,CAAC,CAAC;AAC5F;","names":["useEffect","useState"]}