react-os-shell 4.41.0 → 4.54.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/{Browser-TKBH4DZ3.js → Browser-5NHZNED2.js} +6 -6
- package/dist/{Browser-TKBH4DZ3.js.map → Browser-5NHZNED2.js.map} +1 -1
- package/dist/{Calculator-XERXEV35.js → Calculator-PHKNMRLX.js} +5 -5
- package/dist/{Calculator-XERXEV35.js.map → Calculator-PHKNMRLX.js.map} +1 -1
- package/dist/{CurrencyConverter-OSZISLHT.js → CurrencyConverter-MEG7RHEK.js} +5 -5
- package/dist/{CurrencyConverter-OSZISLHT.js.map → CurrencyConverter-MEG7RHEK.js.map} +1 -1
- package/dist/{Documents-YRTLDTLX.js → Documents-YOUMLERR.js} +7 -7
- package/dist/{Documents-YRTLDTLX.js.map → Documents-YOUMLERR.js.map} +1 -1
- package/dist/{Files-WHYCDRYU.js → Files-4NQ5IFUE.js} +8 -8
- package/dist/{Files-WHYCDRYU.js.map → Files-4NQ5IFUE.js.map} +1 -1
- package/dist/{Notepad-6UAWRNZH.js → Notepad-UHTEKEEM.js} +7 -7
- package/dist/{Notepad-6UAWRNZH.js.map → Notepad-UHTEKEEM.js.map} +1 -1
- package/dist/{PomodoroTimer-5ZSIG7SQ.js → PomodoroTimer-5B5AFXQH.js} +7 -7
- package/dist/{PomodoroTimer-5ZSIG7SQ.js.map → PomodoroTimer-5B5AFXQH.js.map} +1 -1
- package/dist/{Preview-VBIWWJLK.js → Preview-2CCBN25S.js} +8 -8
- package/dist/{Preview-VBIWWJLK.js.map → Preview-2CCBN25S.js.map} +1 -1
- package/dist/{Spreadsheet-GRD4P3OI.js → Spreadsheet-2N6TMVQU.js} +6 -6
- package/dist/{Spreadsheet-GRD4P3OI.js.map → Spreadsheet-2N6TMVQU.js.map} +1 -1
- package/dist/{Stock-4BORXILI.js → Stock-KTWRNBI6.js} +5 -5
- package/dist/{Stock-4BORXILI.js.map → Stock-KTWRNBI6.js.map} +1 -1
- package/dist/{Weather-ZPPSEUIY.js → Weather-B7MO7N4N.js} +5 -5
- package/dist/{Weather-ZPPSEUIY.js.map → Weather-B7MO7N4N.js.map} +1 -1
- package/dist/{WorldClock-LBKYWDWE.js → WorldClock-M5MEV74F.js} +5 -5
- package/dist/{WorldClock-LBKYWDWE.js.map → WorldClock-M5MEV74F.js.map} +1 -1
- package/dist/apps/index.js +16 -16
- package/dist/{chunk-22BNPLM4.js → chunk-3OCL3DB4.js} +3 -3
- package/dist/{chunk-22BNPLM4.js.map → chunk-3OCL3DB4.js.map} +1 -1
- package/dist/{chunk-D4WFGAUW.js → chunk-3SUSQHOW.js} +278 -60
- package/dist/chunk-3SUSQHOW.js.map +1 -0
- package/dist/{chunk-GUWAKATU.js → chunk-5S65ZC5W.js} +3 -3
- package/dist/{chunk-GUWAKATU.js.map → chunk-5S65ZC5W.js.map} +1 -1
- package/dist/{chunk-COTCIYLS.js → chunk-BIZJ7RLC.js} +4 -4
- package/dist/{chunk-COTCIYLS.js.map → chunk-BIZJ7RLC.js.map} +1 -1
- package/dist/{chunk-X5PZYTAK.js → chunk-ECE3B3FZ.js} +3 -3
- package/dist/{chunk-X5PZYTAK.js.map → chunk-ECE3B3FZ.js.map} +1 -1
- package/dist/{chunk-X6DOWIY2.js → chunk-FHPPPDHL.js} +3 -3
- package/dist/{chunk-X6DOWIY2.js.map → chunk-FHPPPDHL.js.map} +1 -1
- package/dist/{chunk-OI253GOA.js → chunk-IOCOH2QQ.js} +4 -4
- package/dist/{chunk-OI253GOA.js.map → chunk-IOCOH2QQ.js.map} +1 -1
- package/dist/{chunk-4AKVHY4B.js → chunk-TK6HI2U4.js} +23 -3
- package/dist/chunk-TK6HI2U4.js.map +1 -0
- package/dist/chunk-XVXEYKMT.js +7 -0
- package/dist/{chunk-TQFUNASX.js.map → chunk-XVXEYKMT.js.map} +1 -1
- package/dist/{chunk-C22EFSND.js → chunk-ZCDFNZQS.js} +21 -6
- package/dist/chunk-ZCDFNZQS.js.map +1 -0
- package/dist/{index-B4RRJ5bp.d.ts → index-B6QGa8SJ.d.ts} +167 -8
- package/dist/index.d.ts +2 -2
- package/dist/index.js +14 -14
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +4 -4
- package/dist/ui.css +117 -43
- package/package.json +1 -1
- package/dist/chunk-4AKVHY4B.js.map +0 -1
- package/dist/chunk-C22EFSND.js.map +0 -1
- package/dist/chunk-D4WFGAUW.js.map +0 -1
- package/dist/chunk-TQFUNASX.js +0 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/apps/WorldClock.tsx"],"names":[],"mappings":"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","file":"WorldClock-LBKYWDWE.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit, type CityWeather } from './_weatherData';\n\nconst SETTINGS_KEY = 'world_clock_appearance';\nconst DEFAULT_CITIES = ['London', 'Shanghai', 'New York'];\n\ninterface WeatherPrefs { useFahrenheit: boolean }\n\n/**\n * Resolve the local time for the supplied IANA timezone into a digital\n * `12:34` + `AM` / `PM` pair. Used by the World Clock rows.\n */\nfunction digitalTime(tz: string, now: Date): { time: string; ampm: string } {\n try {\n const parts = new Intl.DateTimeFormat('en-US', {\n timeZone: tz, hour: 'numeric', minute: '2-digit', hour12: true,\n }).formatToParts(now);\n const h = parts.find(p => p.type === 'hour')?.value || '12';\n const m = parts.find(p => p.type === 'minute')?.value || '00';\n const ampm = (parts.find(p => p.type === 'dayPeriod')?.value || '').toUpperCase();\n return { time: `${h}:${m}`, ampm };\n } catch { return { time: '', ampm: '' }; }\n}\n\n/**\n * World Clock widget — multi-city list. Each row pairs a tiny analogue\n * clock (minimal-style: ring, four cardinal dots, two hands) with the\n * city's current weather. The weather emoji doubles as a day/night cue\n * (☀ vs 🌙 for clear, the same icons for everything else). Reads the\n * shared Open-Meteo cache so it doesn't re-hit the API when the Weather\n * widget already has the data.\n */\nexport default function WorldClock() {\n const { prefs, save } = useShellPrefs();\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configCities, setConfigCities] = useState<string[]>([]);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n const wxPrefs: WeatherPrefs = {\n useFahrenheit: !!(prefs.weather_prefs as WeatherPrefs | undefined)?.useFahrenheit,\n };\n const [configWxPrefs, setConfigWxPrefs] = useState(wxPrefs);\n\n // Tick once every 30 s so the analogue minute-hands drift smoothly. We\n // don't show seconds so faster polling is wasted re-renders.\n const [now, setNow] = useState(() => new Date());\n useEffect(() => {\n const t = setInterval(() => setNow(new Date()), 30 * 1000);\n return () => clearInterval(t);\n }, []);\n\n // Resolve the saved city list and migrate the legacy IANA-timezone\n // format (`Europe/London`) over to the new city-name format\n // (`London`).\n const tzToCity: Record<string, string> = Object.fromEntries(\n Object.entries(AVAILABLE_CITIES).map(([city, info]) => [info.tz, city])\n );\n const rawClocks = prefs.world_clocks as string[] | undefined;\n const cities: string[] = (() => {\n if (!Array.isArray(rawClocks) || rawClocks.length === 0) return DEFAULT_CITIES;\n const out: string[] = [];\n for (const v of rawClocks) {\n const asCity = AVAILABLE_CITIES[v] ? v : tzToCity[v];\n if (asCity && !out.includes(asCity)) out.push(asCity);\n }\n return out.length ? out : DEFAULT_CITIES;\n })();\n\n const [data, setData] = useState<Record<string, CityWeather>>({});\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n (async () => {\n const next: Record<string, CityWeather> = {};\n await Promise.all(cities.map(async c => {\n const w = await fetchCityWeather(c);\n if (w) next[c] = w;\n }));\n if (!cancelled) { setData(next); setLoading(false); }\n })();\n return () => { cancelled = true; };\n }, [cities.join(',')]);\n\n useWidgetSettings(useCallback(() => {\n setConfigCities([...cities]);\n setConfigAppearance({ ...appearance });\n setConfigWxPrefs({ ...wxPrefs });\n setSettingsOpen(true);\n }, [cities.join(','), appearance, wxPrefs.useFahrenheit]));\n\n const saveSettings = () => {\n if (configCities.length === 0) return;\n save({\n world_clocks: configCities,\n weather_prefs: { ...(prefs.weather_prefs as object | undefined ?? {}), useFahrenheit: configWxPrefs.useFahrenheit },\n });\n setAppearance(configAppearance);\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n const formatTemp = (c: number) => wxPrefs.useFahrenheit ? `${toFahrenheit(c)}°` : `${c}°`;\n\n return (\n <>\n {/* Theme-aware panel — same colour as the taskbar so all dashboard\n * widgets read as a coordinated set across light and dark themes.\n * Rows use `divide-y` rather than per-row border classes so the\n * last row never paints a stray separator line at the panel's\n * bottom edge. */}\n <div\n style={{\n backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n <div className=\"divide-y divide-gray-200\">\n {loading && cities.every(c => !data[c]) && (\n <div className=\"px-3 py-6 text-center text-xs text-gray-500\">Loading…</div>\n )}\n {cities.map((cityName) => {\n const w = data[cityName];\n const tz = AVAILABLE_CITIES[cityName]?.tz ?? 'UTC';\n const { time, ampm } = digitalTime(tz, now);\n if (!w) {\n return (\n <div key={cityName} className=\"px-4 py-3\">\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"tabular-nums text-[13px] font-medium text-gray-500\">{time}<span className=\"text-[9px] ml-0.5 opacity-70\">{ampm}</span></span>\n </div>\n <div className=\"text-[11px] text-gray-400 mt-1\">Loading weather…</div>\n </div>\n );\n }\n const [condition, emoji] = getCondition(w.code, w.isDay);\n return (\n <div key={cityName} className=\"px-4 py-3\">\n {/* Top — city name on the left, big temperature on the right. */}\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"text-[26px] font-extralight leading-none tabular-nums tracking-tight text-gray-900 shrink-0\">{formatTemp(w.temp)}</span>\n </div>\n\n {/* Bottom — emoji · digital time · condition on the left;\n H/L on the right. */}\n <div className=\"flex items-center justify-between gap-2 mt-1.5 text-[11px]\">\n <div className=\"flex items-center gap-1.5 min-w-0 text-gray-500\">\n <span className=\"text-base leading-none shrink-0\">{emoji}</span>\n <span className=\"tabular-nums font-semibold text-gray-700 shrink-0\">\n {time}<span className=\"text-[9px] font-medium ml-0.5 opacity-70\">{ampm}</span>\n </span>\n <span className=\"text-gray-300 shrink-0\">·</span>\n <span className=\"truncate\">{condition}</span>\n </div>\n <span className=\"tabular-nums text-gray-500 shrink-0\">H:{formatTemp(w.high)} L:{formatTemp(w.low)}</span>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"World Clock Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Display</h3>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Temperature</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: '°C' }, { key: true, label: '°F' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigWxPrefs(p => ({ ...p, useFahrenheit: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configWxPrefs.useFahrenheit === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <p className=\"text-[10px] text-gray-400 mt-1\">Shared with the Weather widget.</p>\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Cities</h3>\n <div className=\"grid grid-cols-2 gap-1 max-h-56 overflow-y-auto\">\n {Object.keys(AVAILABLE_CITIES).map(name => (\n <label key={name} className=\"flex items-center gap-2 text-sm py-1 cursor-pointer hover:bg-gray-50 rounded px-2\">\n <input type=\"checkbox\" checked={configCities.includes(name)}\n onChange={() => setConfigCities(prev => prev.includes(name) ? prev.filter(c => c !== name) : [...prev, name])}\n className=\"rounded border-gray-300 text-blue-600 focus:ring-blue-500 h-3.5 w-3.5\" />\n {name}\n </label>\n ))}\n </div>\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/apps/WorldClock.tsx"],"names":[],"mappings":"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","file":"WorldClock-M5MEV74F.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit, type CityWeather } from './_weatherData';\n\nconst SETTINGS_KEY = 'world_clock_appearance';\nconst DEFAULT_CITIES = ['London', 'Shanghai', 'New York'];\n\ninterface WeatherPrefs { useFahrenheit: boolean }\n\n/**\n * Resolve the local time for the supplied IANA timezone into a digital\n * `12:34` + `AM` / `PM` pair. Used by the World Clock rows.\n */\nfunction digitalTime(tz: string, now: Date): { time: string; ampm: string } {\n try {\n const parts = new Intl.DateTimeFormat('en-US', {\n timeZone: tz, hour: 'numeric', minute: '2-digit', hour12: true,\n }).formatToParts(now);\n const h = parts.find(p => p.type === 'hour')?.value || '12';\n const m = parts.find(p => p.type === 'minute')?.value || '00';\n const ampm = (parts.find(p => p.type === 'dayPeriod')?.value || '').toUpperCase();\n return { time: `${h}:${m}`, ampm };\n } catch { return { time: '', ampm: '' }; }\n}\n\n/**\n * World Clock widget — multi-city list. Each row pairs a tiny analogue\n * clock (minimal-style: ring, four cardinal dots, two hands) with the\n * city's current weather. The weather emoji doubles as a day/night cue\n * (☀ vs 🌙 for clear, the same icons for everything else). Reads the\n * shared Open-Meteo cache so it doesn't re-hit the API when the Weather\n * widget already has the data.\n */\nexport default function WorldClock() {\n const { prefs, save } = useShellPrefs();\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configCities, setConfigCities] = useState<string[]>([]);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n const wxPrefs: WeatherPrefs = {\n useFahrenheit: !!(prefs.weather_prefs as WeatherPrefs | undefined)?.useFahrenheit,\n };\n const [configWxPrefs, setConfigWxPrefs] = useState(wxPrefs);\n\n // Tick once every 30 s so the analogue minute-hands drift smoothly. We\n // don't show seconds so faster polling is wasted re-renders.\n const [now, setNow] = useState(() => new Date());\n useEffect(() => {\n const t = setInterval(() => setNow(new Date()), 30 * 1000);\n return () => clearInterval(t);\n }, []);\n\n // Resolve the saved city list and migrate the legacy IANA-timezone\n // format (`Europe/London`) over to the new city-name format\n // (`London`).\n const tzToCity: Record<string, string> = Object.fromEntries(\n Object.entries(AVAILABLE_CITIES).map(([city, info]) => [info.tz, city])\n );\n const rawClocks = prefs.world_clocks as string[] | undefined;\n const cities: string[] = (() => {\n if (!Array.isArray(rawClocks) || rawClocks.length === 0) return DEFAULT_CITIES;\n const out: string[] = [];\n for (const v of rawClocks) {\n const asCity = AVAILABLE_CITIES[v] ? v : tzToCity[v];\n if (asCity && !out.includes(asCity)) out.push(asCity);\n }\n return out.length ? out : DEFAULT_CITIES;\n })();\n\n const [data, setData] = useState<Record<string, CityWeather>>({});\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n (async () => {\n const next: Record<string, CityWeather> = {};\n await Promise.all(cities.map(async c => {\n const w = await fetchCityWeather(c);\n if (w) next[c] = w;\n }));\n if (!cancelled) { setData(next); setLoading(false); }\n })();\n return () => { cancelled = true; };\n }, [cities.join(',')]);\n\n useWidgetSettings(useCallback(() => {\n setConfigCities([...cities]);\n setConfigAppearance({ ...appearance });\n setConfigWxPrefs({ ...wxPrefs });\n setSettingsOpen(true);\n }, [cities.join(','), appearance, wxPrefs.useFahrenheit]));\n\n const saveSettings = () => {\n if (configCities.length === 0) return;\n save({\n world_clocks: configCities,\n weather_prefs: { ...(prefs.weather_prefs as object | undefined ?? {}), useFahrenheit: configWxPrefs.useFahrenheit },\n });\n setAppearance(configAppearance);\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n const formatTemp = (c: number) => wxPrefs.useFahrenheit ? `${toFahrenheit(c)}°` : `${c}°`;\n\n return (\n <>\n {/* Theme-aware panel — same colour as the taskbar so all dashboard\n * widgets read as a coordinated set across light and dark themes.\n * Rows use `divide-y` rather than per-row border classes so the\n * last row never paints a stray separator line at the panel's\n * bottom edge. */}\n <div\n style={{\n backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n <div className=\"divide-y divide-gray-200\">\n {loading && cities.every(c => !data[c]) && (\n <div className=\"px-3 py-6 text-center text-xs text-gray-500\">Loading…</div>\n )}\n {cities.map((cityName) => {\n const w = data[cityName];\n const tz = AVAILABLE_CITIES[cityName]?.tz ?? 'UTC';\n const { time, ampm } = digitalTime(tz, now);\n if (!w) {\n return (\n <div key={cityName} className=\"px-4 py-3\">\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"tabular-nums text-[13px] font-medium text-gray-500\">{time}<span className=\"text-[9px] ml-0.5 opacity-70\">{ampm}</span></span>\n </div>\n <div className=\"text-[11px] text-gray-400 mt-1\">Loading weather…</div>\n </div>\n );\n }\n const [condition, emoji] = getCondition(w.code, w.isDay);\n return (\n <div key={cityName} className=\"px-4 py-3\">\n {/* Top — city name on the left, big temperature on the right. */}\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"text-[26px] font-extralight leading-none tabular-nums tracking-tight text-gray-900 shrink-0\">{formatTemp(w.temp)}</span>\n </div>\n\n {/* Bottom — emoji · digital time · condition on the left;\n H/L on the right. */}\n <div className=\"flex items-center justify-between gap-2 mt-1.5 text-[11px]\">\n <div className=\"flex items-center gap-1.5 min-w-0 text-gray-500\">\n <span className=\"text-base leading-none shrink-0\">{emoji}</span>\n <span className=\"tabular-nums font-semibold text-gray-700 shrink-0\">\n {time}<span className=\"text-[9px] font-medium ml-0.5 opacity-70\">{ampm}</span>\n </span>\n <span className=\"text-gray-300 shrink-0\">·</span>\n <span className=\"truncate\">{condition}</span>\n </div>\n <span className=\"tabular-nums text-gray-500 shrink-0\">H:{formatTemp(w.high)} L:{formatTemp(w.low)}</span>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"World Clock Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Display</h3>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Temperature</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: '°C' }, { key: true, label: '°F' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigWxPrefs(p => ({ ...p, useFahrenheit: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configWxPrefs.useFahrenheit === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <p className=\"text-[10px] text-gray-400 mt-1\">Shared with the Weather widget.</p>\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Cities</h3>\n <div className=\"grid grid-cols-2 gap-1 max-h-56 overflow-y-auto\">\n {Object.keys(AVAILABLE_CITIES).map(name => (\n <label key={name} className=\"flex items-center gap-2 text-sm py-1 cursor-pointer hover:bg-gray-50 rounded px-2\">\n <input type=\"checkbox\" checked={configCities.includes(name)}\n onChange={() => setConfigCities(prev => prev.includes(name) ? prev.filter(c => c !== name) : [...prev, name])}\n className=\"rounded border-gray-300 text-blue-600 focus:ring-blue-500 h-3.5 w-3.5\" />\n {name}\n </label>\n ))}\n </div>\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
|
package/dist/apps/index.js
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
export { openFilesInTrashMode, setFilesDemoTree } from '../chunk-QJS6RBH4.js';
|
|
2
2
|
export { setBrowserStartUrl } from '../chunk-BFBWLCO6.js';
|
|
3
|
-
export { BUILTIN_APP_INFO } from '../chunk-
|
|
3
|
+
export { BUILTIN_APP_INFO } from '../chunk-BIZJ7RLC.js';
|
|
4
4
|
import '../chunk-OQ7GRU7G.js';
|
|
5
5
|
export { setSpreadsheetPreview } from '../chunk-4SQU5YV6.js';
|
|
6
6
|
export { setPdfPreview } from '../chunk-BV6SQ46N.js';
|
|
7
|
-
import '../chunk-
|
|
8
|
-
import '../chunk-
|
|
9
|
-
import '../chunk-
|
|
7
|
+
import '../chunk-XVXEYKMT.js';
|
|
8
|
+
import '../chunk-5S65ZC5W.js';
|
|
9
|
+
import '../chunk-ZCDFNZQS.js';
|
|
10
10
|
import '../chunk-OXLLRKBC.js';
|
|
11
11
|
import '../chunk-WNLPTLT6.js';
|
|
12
12
|
import '../chunk-3CUSBZWG.js';
|
|
13
13
|
import { lazy } from 'react';
|
|
14
14
|
|
|
15
|
-
var Calculator = lazy(() => import('../Calculator-
|
|
16
|
-
var Spreadsheet = lazy(() => import('../Spreadsheet-
|
|
17
|
-
var Weather = lazy(() => import('../Weather-
|
|
18
|
-
var CurrencyConverter = lazy(() => import('../CurrencyConverter-
|
|
19
|
-
var PomodoroTimer = lazy(() => import('../PomodoroTimer-
|
|
20
|
-
var Notepad = lazy(() => import('../Notepad-
|
|
21
|
-
var WorldClock = lazy(() => import('../WorldClock-
|
|
22
|
-
var Stock = lazy(() => import('../Stock-
|
|
23
|
-
var Preview = lazy(() => import('../Preview-
|
|
24
|
-
var Documents = lazy(() => import('../Documents-
|
|
25
|
-
var Files = lazy(() => import('../Files-
|
|
26
|
-
var Browser = lazy(() => import('../Browser-
|
|
15
|
+
var Calculator = lazy(() => import('../Calculator-PHKNMRLX.js'));
|
|
16
|
+
var Spreadsheet = lazy(() => import('../Spreadsheet-2N6TMVQU.js'));
|
|
17
|
+
var Weather = lazy(() => import('../Weather-B7MO7N4N.js'));
|
|
18
|
+
var CurrencyConverter = lazy(() => import('../CurrencyConverter-MEG7RHEK.js'));
|
|
19
|
+
var PomodoroTimer = lazy(() => import('../PomodoroTimer-5B5AFXQH.js'));
|
|
20
|
+
var Notepad = lazy(() => import('../Notepad-UHTEKEEM.js'));
|
|
21
|
+
var WorldClock = lazy(() => import('../WorldClock-M5MEV74F.js'));
|
|
22
|
+
var Stock = lazy(() => import('../Stock-KTWRNBI6.js'));
|
|
23
|
+
var Preview = lazy(() => import('../Preview-2CCBN25S.js'));
|
|
24
|
+
var Documents = lazy(() => import('../Documents-YOUMLERR.js'));
|
|
25
|
+
var Files = lazy(() => import('../Files-4NQ5IFUE.js'));
|
|
26
|
+
var Browser = lazy(() => import('../Browser-5NHZNED2.js'));
|
|
27
27
|
var utilityApps = {
|
|
28
28
|
"/calculator": { component: Calculator, label: "Calculator", size: "sm", allowPinOnTop: true, utility: true, widget: true, dimensions: [280, 420] },
|
|
29
29
|
"/spreadsheet": { component: Spreadsheet, label: "Spreadsheets", size: "2xl", appStyle: true, multiInstance: true },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { setSpreadsheetPreview } from './chunk-4SQU5YV6.js';
|
|
2
2
|
import { setPdfPreview } from './chunk-BV6SQ46N.js';
|
|
3
|
-
import { toast_default } from './chunk-
|
|
3
|
+
import { toast_default } from './chunk-TK6HI2U4.js';
|
|
4
4
|
|
|
5
5
|
// src/utils/openPreviewFile.ts
|
|
6
6
|
var PREVIEW_OPENED_EVENT = "react-os-shell:preview-opened";
|
|
@@ -42,5 +42,5 @@ async function openPreviewFile(opts) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
export { PREVIEW_OPENED_EVENT, openPreviewFile };
|
|
45
|
-
//# sourceMappingURL=chunk-
|
|
46
|
-
//# sourceMappingURL=chunk-
|
|
45
|
+
//# sourceMappingURL=chunk-3OCL3DB4.js.map
|
|
46
|
+
//# sourceMappingURL=chunk-3OCL3DB4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/openPreviewFile.ts"],"names":[],"mappings":";;;;;AA6BO,IAAM,oBAAA,GAAuB;AAQpC,SAAS,SAAA,GAAY;AACnB,EAAA,MAAM,QAAA,GAAY,OAAO,MAAA,KAAW,WAAA,IAAgB,MAAA,CAAe,8BAAA;AACnE,EAAA,OAAA,CAAQ,QAAA,IAAY,uBAAA,EAAyB,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAChE;AAEA,eAAsB,gBAAgB,IAAA,EAA6C;AACjF,EAAA,MAAM,EAAE,QAAA,EAAU,QAAA,EAAU,IAAA,EAAM,UAAS,GAAI,IAAA;AAC/C,EAAA,IAAI;AACF,IAAA,MAAM,MAAM,MAAM,KAAA;AAAA,MAChB,GAAG,SAAA,EAAW,CAAA,eAAA,EAAkB,kBAAA,CAAmB,QAAQ,CAAC,CAAA,CAAA;AAAA,MAC5D,EAAE,aAAa,SAAA;AAAU,KAC3B;AACA,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,aAAA,CAAM,KAAA,CAAM,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,CAAA,CAAG,CAAA;AAC7C,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,SAAS,KAAA,EAAO;AAClB,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,IAAA,EAAK;AAC7B,MAAA,qBAAA,CAAsB,EAAE,GAAA,EAAK,IAAA,EAAM,QAAA,EAAU,CAAA;AAC7C,MAAA,QAAA,GAAW,cAAc,CAAA;AAAA,IAC3B,CAAA,MAAO;AACL,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,MAAA,aAAA,CAAc,EAAE,GAAA,EAAK,QAAA,EAAU,IAAA,EAAM,CAAA;AACrC,MAAA,QAAA,GAAW,UAAU,CAAA;AAAA,IACvB;AACA,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,MAAA,MAAA,CAAO,aAAA,CAAc,IAAI,WAAA,CAAiC,oBAAA,EAAsB;AAAA,QAC9E,MAAA,EAAQ,EAAE,QAAA,EAAU,QAAA,EAAU,IAAA;AAAK,OACpC,CAAC,CAAA;AAAA,IACJ;AACA,IAAA,OAAO,IAAA;AAAA,EACT,SAAS,CAAA,EAAQ;AACf,IAAA,aAAA,CAAM,KAAA,CAAM,CAAA,EAAG,OAAA,IAAW,aAAa,CAAA;AACvC,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/utils/openPreviewFile.ts"],"names":[],"mappings":";;;;;AA6BO,IAAM,oBAAA,GAAuB;AAQpC,SAAS,SAAA,GAAY;AACnB,EAAA,MAAM,QAAA,GAAY,OAAO,MAAA,KAAW,WAAA,IAAgB,MAAA,CAAe,8BAAA;AACnE,EAAA,OAAA,CAAQ,QAAA,IAAY,uBAAA,EAAyB,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAChE;AAEA,eAAsB,gBAAgB,IAAA,EAA6C;AACjF,EAAA,MAAM,EAAE,QAAA,EAAU,QAAA,EAAU,IAAA,EAAM,UAAS,GAAI,IAAA;AAC/C,EAAA,IAAI;AACF,IAAA,MAAM,MAAM,MAAM,KAAA;AAAA,MAChB,GAAG,SAAA,EAAW,CAAA,eAAA,EAAkB,kBAAA,CAAmB,QAAQ,CAAC,CAAA,CAAA;AAAA,MAC5D,EAAE,aAAa,SAAA;AAAU,KAC3B;AACA,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,aAAA,CAAM,KAAA,CAAM,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,CAAA,CAAG,CAAA;AAC7C,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,SAAS,KAAA,EAAO;AAClB,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,IAAA,EAAK;AAC7B,MAAA,qBAAA,CAAsB,EAAE,GAAA,EAAK,IAAA,EAAM,QAAA,EAAU,CAAA;AAC7C,MAAA,QAAA,GAAW,cAAc,CAAA;AAAA,IAC3B,CAAA,MAAO;AACL,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,MAAA,aAAA,CAAc,EAAE,GAAA,EAAK,QAAA,EAAU,IAAA,EAAM,CAAA;AACrC,MAAA,QAAA,GAAW,UAAU,CAAA;AAAA,IACvB;AACA,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,MAAA,MAAA,CAAO,aAAA,CAAc,IAAI,WAAA,CAAiC,oBAAA,EAAsB;AAAA,QAC9E,MAAA,EAAQ,EAAE,QAAA,EAAU,QAAA,EAAU,IAAA;AAAK,OACpC,CAAC,CAAA;AAAA,IACJ;AACA,IAAA,OAAO,IAAA;AAAA,EACT,SAAS,CAAA,EAAQ;AACf,IAAA,aAAA,CAAM,KAAA,CAAM,CAAA,EAAG,OAAA,IAAW,aAAa,CAAA;AACvC,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"chunk-3OCL3DB4.js","sourcesContent":["/**\n * Fetch a file from the user's file-server and route it into the right\n * preview window. Shared by the Files app and the desktop Documents\n * folder's shortcut click-through.\n *\n * On success, dispatches `react-os-shell:preview-opened` so Desktop can\n * record the file as a shortcut without this util needing access to the\n * prefs adapter.\n */\nimport toast from '../shell/toast';\nimport { setPdfPreview } from '../apps/_previewStage';\nimport { setSpreadsheetPreview } from '../apps/_spreadsheetStage';\n\nexport type PreviewFileKind = 'pdf' | 'dxf' | '3d' | 'image' | 'csv';\n\nexport interface OpenPreviewFileOpts {\n /** Server-relative path, e.g. \"/reports/Q1.pdf\". */\n filePath: string;\n /** Display name (also used as the download filename). */\n filename: string;\n /** Which viewer to route into. CSV opens in Spreadsheet; the rest open in Preview. */\n kind: PreviewFileKind;\n /** Optional callback invoked after staging the preview, with the route to\n * open (e.g. '/preview' or '/spreadsheet'). The caller is responsible\n * for actually opening the page since the window manager hook is\n * React-scoped. */\n onStaged?: (route: '/preview' | '/spreadsheet') => void;\n}\n\nexport const PREVIEW_OPENED_EVENT = 'react-os-shell:preview-opened';\n\nexport interface PreviewOpenedDetail {\n filePath: string;\n filename: string;\n kind: PreviewFileKind;\n}\n\nfunction getServer() {\n const override = (typeof window !== 'undefined' && (window as any).__REACT_OS_SHELL_FILE_SERVER__) as string | undefined;\n return (override || 'http://localhost:4000').replace(/\\/$/, '');\n}\n\nexport async function openPreviewFile(opts: OpenPreviewFileOpts): Promise<boolean> {\n const { filePath, filename, kind, onStaged } = opts;\n try {\n const res = await fetch(\n `${getServer()}/api/file?path=${encodeURIComponent(filePath)}`,\n { credentials: 'include' },\n );\n if (!res.ok) {\n toast.error(`Download failed (${res.status})`);\n return false;\n }\n const blob = await res.blob();\n if (kind === 'csv') {\n const text = await blob.text();\n setSpreadsheetPreview({ csv: text, filename });\n onStaged?.('/spreadsheet');\n } else {\n const url = URL.createObjectURL(blob);\n setPdfPreview({ url, filename, kind });\n onStaged?.('/preview');\n }\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent<PreviewOpenedDetail>(PREVIEW_OPENED_EVENT, {\n detail: { filePath, filename, kind },\n }));\n }\n return true;\n } catch (e: any) {\n toast.error(e?.message || 'Open failed');\n return false;\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Breadcrumbs } from './chunk-HNH7FOYB.js';
|
|
2
2
|
import { SidebarLayout } from './chunk-YG45DAUT.js';
|
|
3
|
-
import { useIsMobile, useShellPrefs } from './chunk-
|
|
3
|
+
import { useIsMobile, PopupMenu, PopupMenuItem, useShellPrefs } from './chunk-ZCDFNZQS.js';
|
|
4
4
|
import { registerModalEscapeInterceptor, useFocusTrap, useScrollLock } from './chunk-OXLLRKBC.js';
|
|
5
5
|
import { glassStyle } from './chunk-3CUSBZWG.js';
|
|
6
6
|
import { forwardRef, useId, useCallback, useState, useRef, useEffect, createContext, useLayoutEffect, useMemo, Children, isValidElement, cloneElement, useContext, Fragment as Fragment$1, useSyncExternalStore } from 'react';
|
|
@@ -619,10 +619,23 @@ function FormField({
|
|
|
619
619
|
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
620
620
|
label && /* @__PURE__ */ jsxs("label", { id: labelId, htmlFor, className: "mb-1 block text-xs font-medium text-gray-600", children: [
|
|
621
621
|
label,
|
|
622
|
-
required && /* @__PURE__ */ jsx("span", { className: "ml-0.5 text-red-500", children: "*" })
|
|
622
|
+
required && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ml-0.5 text-red-500", children: "*" })
|
|
623
623
|
] }),
|
|
624
624
|
children,
|
|
625
|
-
error ?
|
|
625
|
+
error ? (
|
|
626
|
+
// A validation message appears after the user submits, without focus
|
|
627
|
+
// moving to it. Without a live region it reaches nobody — and this is
|
|
628
|
+
// the one status message a form cannot afford to lose.
|
|
629
|
+
/* @__PURE__ */ jsx(
|
|
630
|
+
"p",
|
|
631
|
+
{
|
|
632
|
+
id: htmlFor ? `${htmlFor}-error` : void 0,
|
|
633
|
+
role: "alert",
|
|
634
|
+
className: "mt-1 text-[11px] text-red-600",
|
|
635
|
+
children: error
|
|
636
|
+
}
|
|
637
|
+
)
|
|
638
|
+
) : hint ? /* @__PURE__ */ jsx("p", { id: htmlFor ? `${htmlFor}-hint` : void 0, className: "mt-1 text-[11px] text-gray-400", children: hint }) : null
|
|
626
639
|
] });
|
|
627
640
|
}
|
|
628
641
|
function Label({ required, children, className = "", ...rest }) {
|
|
@@ -2192,13 +2205,52 @@ var PADDING = {
|
|
|
2192
2205
|
md: { body: "p-4", edge: "px-4 py-3" },
|
|
2193
2206
|
lg: { body: "p-6", edge: "px-6 py-4" }
|
|
2194
2207
|
};
|
|
2195
|
-
function Card({
|
|
2208
|
+
function Card({
|
|
2209
|
+
children,
|
|
2210
|
+
header,
|
|
2211
|
+
footer,
|
|
2212
|
+
padded = true,
|
|
2213
|
+
padding,
|
|
2214
|
+
headingLevel,
|
|
2215
|
+
headerActions,
|
|
2216
|
+
"aria-label": ariaLabel,
|
|
2217
|
+
className = "",
|
|
2218
|
+
bodyClassName = "",
|
|
2219
|
+
style
|
|
2220
|
+
}) {
|
|
2196
2221
|
const p = PADDING[padding ?? (padded ? "md" : "none")];
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2222
|
+
const headingId = useId();
|
|
2223
|
+
const titled = headingLevel != null && header != null;
|
|
2224
|
+
const Heading = `h${headingLevel}`;
|
|
2225
|
+
const named = titled || ariaLabel != null && ariaLabel !== "";
|
|
2226
|
+
const Root = named ? "section" : "div";
|
|
2227
|
+
const surface = `rounded-lg border border-gray-200 bg-white shadow-sm ${className}`.trim();
|
|
2228
|
+
const headerCls = `border-b border-gray-100 ${p.edge} text-sm font-semibold text-gray-900`;
|
|
2229
|
+
return /* @__PURE__ */ jsxs(
|
|
2230
|
+
Root,
|
|
2231
|
+
{
|
|
2232
|
+
className: surface,
|
|
2233
|
+
style,
|
|
2234
|
+
...titled ? { "aria-labelledby": headingId } : named ? { "aria-label": ariaLabel } : {},
|
|
2235
|
+
children: [
|
|
2236
|
+
header != null && (headerActions != null ? (
|
|
2237
|
+
// With actions the row has to be a flex container, so the heading is
|
|
2238
|
+
// nested rather than being the row itself — and only the title is
|
|
2239
|
+
// inside it.
|
|
2240
|
+
/* @__PURE__ */ jsxs("div", { className: `${headerCls} flex items-center justify-between gap-3`, children: [
|
|
2241
|
+
titled ? /* @__PURE__ */ jsx(Heading, { id: headingId, children: header }) : /* @__PURE__ */ jsx("span", { children: header }),
|
|
2242
|
+
headerActions
|
|
2243
|
+
] })
|
|
2244
|
+
) : titled ? (
|
|
2245
|
+
// Without them the heading carries the row's own styling rather than
|
|
2246
|
+
// nesting a second element, so the title is not two boxes deep.
|
|
2247
|
+
/* @__PURE__ */ jsx(Heading, { id: headingId, className: headerCls, children: header })
|
|
2248
|
+
) : /* @__PURE__ */ jsx("div", { className: headerCls, children: header })),
|
|
2249
|
+
/* @__PURE__ */ jsx("div", { className: [p.body, bodyClassName].filter(Boolean).join(" "), children }),
|
|
2250
|
+
footer && /* @__PURE__ */ jsx("div", { className: `border-t border-gray-100 ${p.edge}`, children: footer })
|
|
2251
|
+
]
|
|
2252
|
+
}
|
|
2253
|
+
);
|
|
2202
2254
|
}
|
|
2203
2255
|
function StatCard({ label, value, icon, delta, className = "" }) {
|
|
2204
2256
|
const deltaColor = delta?.direction === "up" ? "text-green-600" : delta?.direction === "down" ? "text-red-600" : "text-gray-500";
|
|
@@ -4010,6 +4062,133 @@ function TopNav({ items, activeKey, onSelect, brand, actions, className }) {
|
|
|
4010
4062
|
}
|
|
4011
4063
|
);
|
|
4012
4064
|
}
|
|
4065
|
+
function DropdownMenu({
|
|
4066
|
+
trigger,
|
|
4067
|
+
items,
|
|
4068
|
+
align = "end",
|
|
4069
|
+
"aria-label": ariaLabel,
|
|
4070
|
+
className = "",
|
|
4071
|
+
disabled
|
|
4072
|
+
}) {
|
|
4073
|
+
const [open, setOpen] = useState(false);
|
|
4074
|
+
const [active, setActive] = useState(0);
|
|
4075
|
+
const wrapRef = useRef(null);
|
|
4076
|
+
const triggerRef = useRef(null);
|
|
4077
|
+
const itemRefs = useRef([]);
|
|
4078
|
+
const menuId = useId();
|
|
4079
|
+
const close = useCallback((restoreFocus) => {
|
|
4080
|
+
setOpen(false);
|
|
4081
|
+
if (restoreFocus) triggerRef.current?.focus();
|
|
4082
|
+
}, []);
|
|
4083
|
+
const enabledFrom = (from, step) => {
|
|
4084
|
+
for (let i = 0; i < items.length; i += 1) {
|
|
4085
|
+
const at = ((from + step * i) % items.length + items.length) % items.length;
|
|
4086
|
+
if (!items[at]?.disabled) return at;
|
|
4087
|
+
}
|
|
4088
|
+
return from;
|
|
4089
|
+
};
|
|
4090
|
+
useEffect(() => {
|
|
4091
|
+
if (!open) return;
|
|
4092
|
+
const onPointerDown = (e) => {
|
|
4093
|
+
if (!wrapRef.current?.contains(e.target)) close(false);
|
|
4094
|
+
};
|
|
4095
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
4096
|
+
return () => document.removeEventListener("pointerdown", onPointerDown, true);
|
|
4097
|
+
}, [open, close]);
|
|
4098
|
+
useEffect(() => {
|
|
4099
|
+
if (open) itemRefs.current[active]?.focus();
|
|
4100
|
+
}, [open, active]);
|
|
4101
|
+
useEffect(() => {
|
|
4102
|
+
if (!open) return;
|
|
4103
|
+
return registerModalEscapeInterceptor((event) => {
|
|
4104
|
+
if (event.key !== "Escape") return false;
|
|
4105
|
+
close(true);
|
|
4106
|
+
return true;
|
|
4107
|
+
});
|
|
4108
|
+
}, [open, close]);
|
|
4109
|
+
const openAt = (index) => {
|
|
4110
|
+
setActive(index);
|
|
4111
|
+
setOpen(true);
|
|
4112
|
+
};
|
|
4113
|
+
const onTriggerKeyDown = (e) => {
|
|
4114
|
+
if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
|
|
4115
|
+
e.preventDefault();
|
|
4116
|
+
openAt(enabledFrom(0, 1));
|
|
4117
|
+
} else if (e.key === "ArrowUp") {
|
|
4118
|
+
e.preventDefault();
|
|
4119
|
+
openAt(enabledFrom(items.length - 1, -1));
|
|
4120
|
+
}
|
|
4121
|
+
};
|
|
4122
|
+
const onMenuKeyDown = (e) => {
|
|
4123
|
+
if (e.key === "ArrowDown") {
|
|
4124
|
+
e.preventDefault();
|
|
4125
|
+
setActive(enabledFrom(active + 1, 1));
|
|
4126
|
+
} else if (e.key === "ArrowUp") {
|
|
4127
|
+
e.preventDefault();
|
|
4128
|
+
setActive(enabledFrom(active - 1, -1));
|
|
4129
|
+
} else if (e.key === "Home") {
|
|
4130
|
+
e.preventDefault();
|
|
4131
|
+
setActive(enabledFrom(0, 1));
|
|
4132
|
+
} else if (e.key === "End") {
|
|
4133
|
+
e.preventDefault();
|
|
4134
|
+
setActive(enabledFrom(items.length - 1, -1));
|
|
4135
|
+
} else if (e.key === "Tab") {
|
|
4136
|
+
e.preventDefault();
|
|
4137
|
+
close(true);
|
|
4138
|
+
}
|
|
4139
|
+
};
|
|
4140
|
+
const select = (item) => {
|
|
4141
|
+
if (item.disabled) return;
|
|
4142
|
+
close(true);
|
|
4143
|
+
item.onSelect();
|
|
4144
|
+
};
|
|
4145
|
+
return /* @__PURE__ */ jsxs("div", { ref: wrapRef, className: `relative inline-flex ${className}`.trim(), children: [
|
|
4146
|
+
/* @__PURE__ */ jsx(
|
|
4147
|
+
"button",
|
|
4148
|
+
{
|
|
4149
|
+
ref: triggerRef,
|
|
4150
|
+
type: "button",
|
|
4151
|
+
"aria-haspopup": "menu",
|
|
4152
|
+
"aria-expanded": open,
|
|
4153
|
+
"aria-controls": open ? menuId : void 0,
|
|
4154
|
+
"aria-label": ariaLabel,
|
|
4155
|
+
disabled,
|
|
4156
|
+
onClick: () => open ? close(false) : openAt(enabledFrom(0, 1)),
|
|
4157
|
+
onKeyDown: onTriggerKeyDown,
|
|
4158
|
+
className: "inline-flex items-center justify-center rounded-md text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-400 disabled:cursor-not-allowed disabled:opacity-60",
|
|
4159
|
+
children: trigger
|
|
4160
|
+
}
|
|
4161
|
+
),
|
|
4162
|
+
open && /* @__PURE__ */ jsx(
|
|
4163
|
+
"div",
|
|
4164
|
+
{
|
|
4165
|
+
className: `absolute top-full z-50 mt-1 ${align === "end" ? "right-0" : "left-0"}`,
|
|
4166
|
+
onKeyDown: onMenuKeyDown,
|
|
4167
|
+
children: /* @__PURE__ */ jsx(PopupMenu, { portal: false, minWidth: 180, children: /* @__PURE__ */ jsx("div", { id: menuId, role: "menu", "aria-orientation": "vertical", "aria-label": ariaLabel, children: items.map((item, i) => /* @__PURE__ */ jsxs(
|
|
4168
|
+
PopupMenuItem,
|
|
4169
|
+
{
|
|
4170
|
+
ref: (el) => {
|
|
4171
|
+
itemRefs.current[i] = el;
|
|
4172
|
+
},
|
|
4173
|
+
role: "menuitem",
|
|
4174
|
+
tabIndex: i === active ? 0 : -1,
|
|
4175
|
+
danger: item.danger,
|
|
4176
|
+
disabled: item.disabled,
|
|
4177
|
+
onMouseEnter: () => {
|
|
4178
|
+
if (!item.disabled) setActive(i);
|
|
4179
|
+
},
|
|
4180
|
+
onClick: () => select(item),
|
|
4181
|
+
children: [
|
|
4182
|
+
item.icon,
|
|
4183
|
+
item.label
|
|
4184
|
+
]
|
|
4185
|
+
},
|
|
4186
|
+
item.key
|
|
4187
|
+
)) }) })
|
|
4188
|
+
}
|
|
4189
|
+
)
|
|
4190
|
+
] });
|
|
4191
|
+
}
|
|
4013
4192
|
var SIZE_PX2 = { sm: 320, md: 448, lg: 640 };
|
|
4014
4193
|
var SIDE_POSITION = {
|
|
4015
4194
|
right: "inset-y-0 right-0",
|
|
@@ -4453,6 +4632,7 @@ function Pagination({
|
|
|
4453
4632
|
showEdges && /* @__PURE__ */ jsx("button", { type: "button", "aria-label": "Last page", disabled: page === pageCount, onClick: () => go(pageCount), className: `${BTN} text-gray-600 hover:bg-gray-100`, children: "\xBB" })
|
|
4454
4633
|
] });
|
|
4455
4634
|
}
|
|
4635
|
+
var isGroup = (h) => Array.isArray(h.columns);
|
|
4456
4636
|
var PAD = {
|
|
4457
4637
|
sm: "px-2 py-1.5",
|
|
4458
4638
|
md: "px-3 py-2"
|
|
@@ -4475,6 +4655,7 @@ function DataTable({
|
|
|
4475
4655
|
sort = null,
|
|
4476
4656
|
onSortChange,
|
|
4477
4657
|
pagination,
|
|
4658
|
+
caption,
|
|
4478
4659
|
loading = false,
|
|
4479
4660
|
bordered = false,
|
|
4480
4661
|
size = "md",
|
|
@@ -4492,13 +4673,52 @@ function DataTable({
|
|
|
4492
4673
|
if (!onSortChange) return;
|
|
4493
4674
|
const field = fieldOf(col);
|
|
4494
4675
|
const current = directionFor(col);
|
|
4495
|
-
|
|
4496
|
-
|
|
4676
|
+
const first = col.sortFirst ?? "asc";
|
|
4677
|
+
const second = first === "asc" ? "desc" : "asc";
|
|
4678
|
+
if (current === null) onSortChange({ field, direction: first });
|
|
4679
|
+
else if (current === first) onSortChange({ field, direction: second });
|
|
4497
4680
|
else onSortChange(null);
|
|
4498
4681
|
};
|
|
4682
|
+
const leaves = columns.flatMap((h) => isGroup(h) ? h.columns : [h]);
|
|
4683
|
+
const grouped = columns.some(isGroup);
|
|
4499
4684
|
const cellBase = `${PAD[size]} ${size === "sm" ? "text-xs" : "text-sm"}`;
|
|
4685
|
+
const headerCell = (col, ci, rowSpan) => {
|
|
4686
|
+
const dir = directionFor(col);
|
|
4687
|
+
const align = ALIGN2[col.align ?? (col.numeric ? "right" : "left")];
|
|
4688
|
+
const pinned = col.fixed === "left";
|
|
4689
|
+
return /* @__PURE__ */ jsx(
|
|
4690
|
+
"th",
|
|
4691
|
+
{
|
|
4692
|
+
scope: "col",
|
|
4693
|
+
rowSpan: rowSpan > 1 ? rowSpan : void 0,
|
|
4694
|
+
"aria-sort": dir === "asc" ? "ascending" : dir === "desc" ? "descending" : col.sortable && onSortChange ? "none" : void 0,
|
|
4695
|
+
style: { width: col.width, ...pinned ? { left: offsets[ci] ?? 0 } : {} },
|
|
4696
|
+
className: [
|
|
4697
|
+
cellBase,
|
|
4698
|
+
align,
|
|
4699
|
+
"font-semibold uppercase tracking-wide text-gray-500",
|
|
4700
|
+
size === "sm" ? "text-[10px]" : "text-xs",
|
|
4701
|
+
pinned ? "sticky z-10 bg-gray-50" : "",
|
|
4702
|
+
col.headerClassName ?? ""
|
|
4703
|
+
].filter(Boolean).join(" "),
|
|
4704
|
+
children: col.sortable && onSortChange ? /* @__PURE__ */ jsxs(
|
|
4705
|
+
"button",
|
|
4706
|
+
{
|
|
4707
|
+
type: "button",
|
|
4708
|
+
onClick: () => toggleSort(col),
|
|
4709
|
+
className: `inline-flex items-center font-semibold uppercase tracking-wide hover:text-gray-700 ${align}`,
|
|
4710
|
+
children: [
|
|
4711
|
+
col.title,
|
|
4712
|
+
/* @__PURE__ */ jsx(SortIcon, { direction: dir })
|
|
4713
|
+
]
|
|
4714
|
+
}
|
|
4715
|
+
) : col.title
|
|
4716
|
+
},
|
|
4717
|
+
col.key
|
|
4718
|
+
);
|
|
4719
|
+
};
|
|
4500
4720
|
let fixedOffset = 0;
|
|
4501
|
-
const offsets =
|
|
4721
|
+
const offsets = leaves.map((col) => {
|
|
4502
4722
|
if (col.fixed !== "left") return null;
|
|
4503
4723
|
const at = fixedOffset;
|
|
4504
4724
|
fixedOffset += col.width ?? 0;
|
|
@@ -4514,56 +4734,56 @@ function DataTable({
|
|
|
4514
4734
|
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading" })
|
|
4515
4735
|
] }),
|
|
4516
4736
|
/* @__PURE__ */ jsxs("table", { className: "w-full border-collapse tabular-nums", style: minWidth ? { minWidth } : void 0, children: [
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
{
|
|
4524
|
-
scope: "col",
|
|
4525
|
-
"aria-sort": dir === "asc" ? "ascending" : dir === "desc" ? "descending" : void 0,
|
|
4526
|
-
style: {
|
|
4527
|
-
width: col.width,
|
|
4528
|
-
...pinned ? { left: offsets[ci] ?? 0 } : {}
|
|
4529
|
-
},
|
|
4530
|
-
className: [
|
|
4531
|
-
cellBase,
|
|
4532
|
-
align,
|
|
4533
|
-
"font-semibold uppercase tracking-wide text-gray-500",
|
|
4534
|
-
size === "sm" ? "text-[10px]" : "text-xs",
|
|
4535
|
-
pinned ? "sticky z-10 bg-gray-50" : "",
|
|
4536
|
-
col.headerClassName ?? ""
|
|
4537
|
-
].filter(Boolean).join(" "),
|
|
4538
|
-
children: col.sortable && onSortChange ? /* @__PURE__ */ jsxs(
|
|
4539
|
-
"button",
|
|
4737
|
+
caption && /* @__PURE__ */ jsx("caption", { className: "sr-only", children: caption }),
|
|
4738
|
+
/* @__PURE__ */ jsxs("thead", { children: [
|
|
4739
|
+
/* @__PURE__ */ jsx("tr", { className: "border-b border-gray-200 bg-gray-50", children: columns.map((h, hi) => {
|
|
4740
|
+
if (isGroup(h)) {
|
|
4741
|
+
return /* @__PURE__ */ jsx(
|
|
4742
|
+
"th",
|
|
4540
4743
|
{
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
className:
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4744
|
+
scope: "colgroup",
|
|
4745
|
+
colSpan: h.columns.length,
|
|
4746
|
+
className: [
|
|
4747
|
+
cellBase,
|
|
4748
|
+
"text-center",
|
|
4749
|
+
"font-semibold uppercase tracking-wide text-gray-500",
|
|
4750
|
+
size === "sm" ? "text-[10px]" : "text-xs",
|
|
4751
|
+
"border-b border-gray-200",
|
|
4752
|
+
h.headerClassName ?? ""
|
|
4753
|
+
].filter(Boolean).join(" "),
|
|
4754
|
+
children: h.title
|
|
4755
|
+
},
|
|
4756
|
+
h.key ?? `group-${hi}`
|
|
4757
|
+
);
|
|
4758
|
+
}
|
|
4759
|
+
return headerCell(h, leaves.indexOf(h), grouped ? 2 : 1);
|
|
4760
|
+
}) }),
|
|
4761
|
+
grouped && /* @__PURE__ */ jsx("tr", { className: "border-b border-gray-200 bg-gray-50", children: columns.flatMap((h) => isGroup(h) ? h.columns : []).map(
|
|
4762
|
+
(col) => headerCell(col, leaves.indexOf(col), 1)
|
|
4763
|
+
) })
|
|
4764
|
+
] }),
|
|
4765
|
+
/* @__PURE__ */ jsx("tbody", { children: data.length === 0 && !loading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: leaves.length, className: `${cellBase} py-10 text-center text-gray-500`, children: emptyText }) }) : data.map((row, i) => {
|
|
4555
4766
|
const rowProps = onRow?.(row, i);
|
|
4556
4767
|
return /* @__PURE__ */ jsx(
|
|
4557
4768
|
"tr",
|
|
4558
4769
|
{
|
|
4559
4770
|
onClick: rowProps?.onClick,
|
|
4771
|
+
...rowProps?.onClick ? {
|
|
4772
|
+
tabIndex: 0,
|
|
4773
|
+
onKeyDown: (e) => {
|
|
4774
|
+
if (e.target !== e.currentTarget) return;
|
|
4775
|
+
if (e.key !== "Enter" && e.key !== " ") return;
|
|
4776
|
+
e.preventDefault();
|
|
4777
|
+
rowProps.onClick?.();
|
|
4778
|
+
}
|
|
4779
|
+
} : {},
|
|
4560
4780
|
className: [
|
|
4561
4781
|
"border-b border-gray-100 last:border-b-0",
|
|
4562
|
-
rowProps?.onClick ? "cursor-pointer hover:bg-gray-50" : "",
|
|
4782
|
+
rowProps?.onClick ? "cursor-pointer hover:bg-gray-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-blue-400" : "",
|
|
4563
4783
|
rowClassName?.(row, i) ?? "",
|
|
4564
4784
|
rowProps?.className ?? ""
|
|
4565
4785
|
].filter(Boolean).join(" "),
|
|
4566
|
-
children:
|
|
4786
|
+
children: leaves.map((col, ci) => {
|
|
4567
4787
|
const pinned = col.fixed === "left";
|
|
4568
4788
|
return /* @__PURE__ */ jsx(
|
|
4569
4789
|
"td",
|
|
@@ -4571,7 +4791,8 @@ function DataTable({
|
|
|
4571
4791
|
style: pinned ? { left: offsets[ci] ?? 0 } : void 0,
|
|
4572
4792
|
className: [
|
|
4573
4793
|
cellBase,
|
|
4574
|
-
ALIGN2[col.align ?? "left"],
|
|
4794
|
+
ALIGN2[col.align ?? (col.numeric ? "right" : "left")],
|
|
4795
|
+
col.numeric ? "font-mono" : "",
|
|
4575
4796
|
"text-gray-900",
|
|
4576
4797
|
col.ellipsis ? "max-w-0 truncate" : "",
|
|
4577
4798
|
// A pinned cell needs its own background or the
|
|
@@ -5293,16 +5514,13 @@ var COPY2 = {
|
|
|
5293
5514
|
404: { title: "Page not found", body: "The page you're looking for doesn't exist or was moved." },
|
|
5294
5515
|
500: { title: "Something went wrong", body: "An unexpected error occurred. Please try again." }
|
|
5295
5516
|
};
|
|
5296
|
-
function ErrorPage({ code = 404 }) {
|
|
5517
|
+
function ErrorPage({ code = 404, actions }) {
|
|
5297
5518
|
const c = COPY2[code];
|
|
5298
5519
|
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center justify-center bg-gray-50 p-6 text-center", children: [
|
|
5299
5520
|
/* @__PURE__ */ jsx("div", { className: "text-7xl font-bold tracking-tight text-gray-400", children: code }),
|
|
5300
5521
|
/* @__PURE__ */ jsx("h1", { className: "mt-2 text-xl font-semibold text-gray-900", children: c.title }),
|
|
5301
5522
|
/* @__PURE__ */ jsx("p", { className: "mt-1 max-w-sm text-sm text-gray-500", children: c.body }),
|
|
5302
|
-
/* @__PURE__ */
|
|
5303
|
-
/* @__PURE__ */ jsx(Button_default, { variant: "secondary", children: "Go back" }),
|
|
5304
|
-
/* @__PURE__ */ jsx(Button_default, { children: "Take me home" })
|
|
5305
|
-
] })
|
|
5523
|
+
actions && /* @__PURE__ */ jsx("div", { className: "mt-6 flex items-center gap-2", children: actions })
|
|
5306
5524
|
] });
|
|
5307
5525
|
}
|
|
5308
5526
|
function subscribeMediaQuery(cb) {
|
|
@@ -5438,6 +5656,6 @@ var ALT_SHIFT_D = isMac ? "\u2325\u21E7D" : "Alt+Shift+D";
|
|
|
5438
5656
|
var ALT_SHIFT_E = isMac ? "\u2325\u21E7E" : "Alt+Shift+E";
|
|
5439
5657
|
var ALT_SHIFT_N = isMac ? "\u2325\u21E7N" : "Alt+Shift+N";
|
|
5440
5658
|
|
|
5441
|
-
export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, Accordion, AuthScreen, Avatar, AvatarGroup, Banner, BarChart, Button_default, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, CMD_SHIFT_Z, CMD_Z, Card, ChatTemplate, Checkbox_default, CheckoutTemplate, ColoredBadge, ContainerFillChart, CountBadge, DashboardTemplate, DataTable, DataTablePage, DatePicker_default, DateRangePicker, DescriptionList, Divider, DonutChart, Drawer, ENTER, EmailTemplate, EmptyState, ErrorPage, FilePicker, FormField, FormLayoutPage, GROUP_COLORS, GalleryTemplate, GlobalSearch, Grid, HelpCenter, INPUT_BASE, INPUT_SIZES, IconButton_default, Inline, InputNumber_default, Input_default, Kanban, Label, ListFooter, ListLoadError, LoadingSpinner, MAX_FRACTION_DIGITS, MOD, Markdown, MediaUploadField, MediaUploadGrid, MetricBar, MilestoneTimeline, NativeSelect, NumericKeypad, PageHeader, Pagination, Paragraph, Radio_default, Result, SHIFT, SearchableSelect, Segmented, Select_default, SidebarActionButton, SidebarGroupLabel, SidebarNavItem, Skeleton, Sparkline, Stack, StatCard, Statistic, StatusBadge, StatusBadgeProvider, Switch_default, Tabs, Text, Textarea_default, TileButton_default, Title, Tooltip, TopNav, appendKey, applyThemePrefs, backspace, firstEnabledIndex, formatDate, inputClasses, isMac, isSeverityTone, lastEnabledIndex, matchTypeahead, mediaFileName, nextEnabledIndex, resolveTheme, severityOf, tabButtonId, tabPanelId, toISODate, useClickOutside, useTheme };
|
|
5442
|
-
//# sourceMappingURL=chunk-
|
|
5443
|
-
//# sourceMappingURL=chunk-
|
|
5659
|
+
export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, Accordion, AuthScreen, Avatar, AvatarGroup, Banner, BarChart, Button_default, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, CMD_SHIFT_Z, CMD_Z, Card, ChatTemplate, Checkbox_default, CheckoutTemplate, ColoredBadge, ContainerFillChart, CountBadge, DashboardTemplate, DataTable, DataTablePage, DatePicker_default, DateRangePicker, DescriptionList, Divider, DonutChart, Drawer, DropdownMenu, ENTER, EmailTemplate, EmptyState, ErrorPage, FilePicker, FormField, FormLayoutPage, GROUP_COLORS, GalleryTemplate, GlobalSearch, Grid, HelpCenter, INPUT_BASE, INPUT_SIZES, IconButton_default, Inline, InputNumber_default, Input_default, Kanban, Label, ListFooter, ListLoadError, LoadingSpinner, MAX_FRACTION_DIGITS, MOD, Markdown, MediaUploadField, MediaUploadGrid, MetricBar, MilestoneTimeline, NativeSelect, NumericKeypad, PageHeader, Pagination, Paragraph, Radio_default, Result, SHIFT, SearchableSelect, Segmented, Select_default, SidebarActionButton, SidebarGroupLabel, SidebarNavItem, Skeleton, Sparkline, Stack, StatCard, Statistic, StatusBadge, StatusBadgeProvider, Switch_default, Tabs, Text, Textarea_default, TileButton_default, Title, Tooltip, TopNav, appendKey, applyThemePrefs, backspace, firstEnabledIndex, formatDate, inputClasses, isMac, isSeverityTone, lastEnabledIndex, matchTypeahead, mediaFileName, nextEnabledIndex, resolveTheme, severityOf, tabButtonId, tabPanelId, toISODate, useClickOutside, useTheme };
|
|
5660
|
+
//# sourceMappingURL=chunk-3SUSQHOW.js.map
|
|
5661
|
+
//# sourceMappingURL=chunk-3SUSQHOW.js.map
|