react-os-shell 2.9.2 → 2.9.3

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.
Files changed (51) hide show
  1. package/dist/Browser-23ULR34J.js +7 -0
  2. package/dist/{Browser-D5BGCK2V.js.map → Browser-23ULR34J.js.map} +1 -1
  3. package/dist/{Calculator-7SW642IT.js → Calculator-RI2AXFNQ.js} +4 -4
  4. package/dist/{Calculator-7SW642IT.js.map → Calculator-RI2AXFNQ.js.map} +1 -1
  5. package/dist/{CurrencyConverter-L6IJFZVY.js → CurrencyConverter-TVSLZLYL.js} +5 -6
  6. package/dist/CurrencyConverter-TVSLZLYL.js.map +1 -0
  7. package/dist/{Documents-4T4L7GRO.js → Documents-BGCOIW5E.js} +4 -4
  8. package/dist/{Documents-4T4L7GRO.js.map → Documents-BGCOIW5E.js.map} +1 -1
  9. package/dist/Files-X7ERMLDM.js +13 -0
  10. package/dist/{Files-TRZNQCJM.js.map → Files-X7ERMLDM.js.map} +1 -1
  11. package/dist/{Notepad-TYDVXKKL.js → Notepad-OTOYAF4L.js} +4 -4
  12. package/dist/{Notepad-TYDVXKKL.js.map → Notepad-OTOYAF4L.js.map} +1 -1
  13. package/dist/{PomodoroTimer-2FSXRTKE.js → PomodoroTimer-FZP7SKPY.js} +5 -5
  14. package/dist/{PomodoroTimer-2FSXRTKE.js.map → PomodoroTimer-FZP7SKPY.js.map} +1 -1
  15. package/dist/Preview-XSX4HVK6.js +9 -0
  16. package/dist/{Preview-UH7CQOX4.js.map → Preview-XSX4HVK6.js.map} +1 -1
  17. package/dist/Spreadsheet-4FOA6E6K.js +7 -0
  18. package/dist/{Spreadsheet-3P4UXPPO.js.map → Spreadsheet-4FOA6E6K.js.map} +1 -1
  19. package/dist/{Stock-YVSTTX3E.js → Stock-36BKWEUO.js} +5 -6
  20. package/dist/Stock-36BKWEUO.js.map +1 -0
  21. package/dist/{Weather-66JXIJYS.js → Weather-QUHBOFVA.js} +4 -4
  22. package/dist/{Weather-66JXIJYS.js.map → Weather-QUHBOFVA.js.map} +1 -1
  23. package/dist/{WorldClock-AQAGIWJI.js → WorldClock-2UY5R4L3.js} +4 -4
  24. package/dist/{WorldClock-AQAGIWJI.js.map → WorldClock-2UY5R4L3.js.map} +1 -1
  25. package/dist/apps/index.js +19 -19
  26. package/dist/{chunk-ALUQWTMS.js → chunk-BJS5UCR6.js} +2 -2
  27. package/dist/{chunk-ALUQWTMS.js.map → chunk-BJS5UCR6.js.map} +1 -1
  28. package/dist/{chunk-KRW43W6H.js → chunk-DVXRDQEN.js} +4 -4
  29. package/dist/{chunk-KRW43W6H.js.map → chunk-DVXRDQEN.js.map} +1 -1
  30. package/dist/{chunk-CHHD3HXH.js → chunk-HKBUFA4V.js} +4 -4
  31. package/dist/{chunk-CHHD3HXH.js.map → chunk-HKBUFA4V.js.map} +1 -1
  32. package/dist/{chunk-SX2EDREN.js → chunk-HMV37F2X.js} +4 -4
  33. package/dist/{chunk-SX2EDREN.js.map → chunk-HMV37F2X.js.map} +1 -1
  34. package/dist/{chunk-ACV2G34L.js → chunk-MIFS2574.js} +3 -3
  35. package/dist/{chunk-ACV2G34L.js.map → chunk-MIFS2574.js.map} +1 -1
  36. package/dist/{chunk-CRPM7MJP.js → chunk-T2P7CZ3S.js} +3 -3
  37. package/dist/{chunk-CRPM7MJP.js.map → chunk-T2P7CZ3S.js.map} +1 -1
  38. package/dist/{chunk-KEE2ECYO.js → chunk-UWNETCYO.js} +4 -4
  39. package/dist/{chunk-KEE2ECYO.js.map → chunk-UWNETCYO.js.map} +1 -1
  40. package/dist/{chunk-YSB3FL3X.js → chunk-Y2L2DBL6.js} +5 -5
  41. package/dist/{chunk-YSB3FL3X.js.map → chunk-Y2L2DBL6.js.map} +1 -1
  42. package/dist/{chunk-RJ3H4GK6.js → chunk-YWANIOU6.js} +4 -4
  43. package/dist/{chunk-RJ3H4GK6.js.map → chunk-YWANIOU6.js.map} +1 -1
  44. package/dist/index.js +10 -10
  45. package/package.json +1 -1
  46. package/dist/Browser-D5BGCK2V.js +0 -7
  47. package/dist/CurrencyConverter-L6IJFZVY.js.map +0 -1
  48. package/dist/Files-TRZNQCJM.js +0 -13
  49. package/dist/Preview-UH7CQOX4.js +0 -9
  50. package/dist/Spreadsheet-3P4UXPPO.js +0 -7
  51. package/dist/Stock-YVSTTX3E.js.map +0 -1
@@ -1,9 +0,0 @@
1
- export { Preview as default, setPdfPreview } from './chunk-CHHD3HXH.js';
2
- import './chunk-NUPYEVU4.js';
3
- import './chunk-VENYVK3L.js';
4
- import './chunk-RJ3H4GK6.js';
5
- import './chunk-ALUQWTMS.js';
6
- import './chunk-UBN4IUDE.js';
7
- import './chunk-ZF6AYO4G.js';
8
- //# sourceMappingURL=Preview-UH7CQOX4.js.map
9
- //# sourceMappingURL=Preview-UH7CQOX4.js.map
@@ -1,7 +0,0 @@
1
- export { Spreadsheet as default, setSpreadsheetPreview } from './chunk-KEE2ECYO.js';
2
- import './chunk-RJ3H4GK6.js';
3
- import './chunk-ALUQWTMS.js';
4
- import './chunk-UBN4IUDE.js';
5
- import './chunk-ZF6AYO4G.js';
6
- //# sourceMappingURL=Spreadsheet-3P4UXPPO.js.map
7
- //# sourceMappingURL=Spreadsheet-3P4UXPPO.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/apps/Stock.tsx"],"names":[],"mappings":"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","file":"Stock-YVSTTX3E.js","sourcesContent":["import { useState, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\n\n/**\n * Stock ticker widget — track a watchlist of equities with demo prices.\n *\n * Prices are static, in-file demo data (DEMO_QUOTES) so the widget works with\n * no API key and no server. \"Setup\" is just picking which demo tickers to show.\n */\n\n/** Cap the watchlist — keeps the widget compact. */\nconst MAX_SYMBOLS = 8;\nconst DEFAULT_SYMBOLS = ['AAPL', 'MSFT', 'GOOGL', 'TSLA', 'NVDA'];\n\nconst SYMBOLS_KEY = 'stock_symbols';\nconst SETTINGS_KEY = 'stock_appearance';\n\ninterface Quote { price: number; change: number; changePct: number }\n\n/** Static demo quotes — realistic-ish values, a mix of gainers and losers. */\nconst DEMO_QUOTES: Record<string, Quote> = {\n AAPL: { price: 229.87, change: 1.42, changePct: 0.62 },\n MSFT: { price: 451.16, change: -2.31, changePct: -0.51 },\n GOOGL: { price: 178.34, change: 0.89, changePct: 0.50 },\n AMZN: { price: 201.45, change: -1.08, changePct: -0.53 },\n TSLA: { price: 248.92, change: 6.74, changePct: 2.78 },\n NVDA: { price: 134.81, change: -3.12, changePct: -2.26 },\n META: { price: 563.27, change: 4.55, changePct: 0.81 },\n};\n\n/** Demo tickers offered in the symbol picker. */\nconst DEMO_TICKERS = Object.keys(DEMO_QUOTES);\n\nfunction loadSymbols(): string[] {\n try { const s = JSON.parse(localStorage.getItem(SYMBOLS_KEY) || ''); if (Array.isArray(s) && s.length) return s.slice(0, MAX_SYMBOLS); } catch {}\n return DEFAULT_SYMBOLS;\n}\n\nconst fmtPrice = (n: number) => `$${n.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;\nconst fmtSigned = (n: number) => `${n >= 0 ? '+' : ''}${n.toFixed(2)}`;\n\nexport default function Stock() {\n const [symbols, setSymbols] = useState(loadSymbols);\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configSymbols, setConfigSymbols] = useState<string[]>([]);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n const [newSymbol, setNewSymbol] = useState('');\n\n const openSettings = useCallback(() => {\n setConfigSymbols([...symbols]);\n setConfigAppearance({ ...appearance });\n setNewSymbol('');\n setSettingsOpen(true);\n }, [symbols, appearance]);\n\n useWidgetSettings(openSettings);\n\n const addSymbol = () => {\n const s = newSymbol.trim().toUpperCase();\n if (!s || configSymbols.includes(s) || configSymbols.length >= MAX_SYMBOLS) return;\n setConfigSymbols(p => [...p, s]);\n setNewSymbol('');\n };\n\n const saveSettings = () => {\n const cleaned = configSymbols.map(s => s.toUpperCase()).slice(0, MAX_SYMBOLS);\n setSymbols(cleaned); setAppearance(configAppearance);\n localStorage.setItem(SYMBOLS_KEY, JSON.stringify(cleaned));\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n // Tickers the picker can still offer (demo set minus what's already added).\n const availableTickers = DEMO_TICKERS.filter(t => !configSymbols.includes(t));\n\n return (\n <>\n {/* Theme-aware panel — mirrors the taskbar's `--taskbar-bg-rgb` so the\n * widget matches it across themes; gray-* classes auto-invert in dark. */}\n <div className=\"flex flex-col h-full\"\n style={{ backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`, backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined }}>\n <div className=\"px-4 py-3 flex-1\">\n {symbols.length === 0 ? (\n <div className=\"text-xs text-gray-500 text-center py-6\">No symbols yet — add some in settings.</div>\n ) : (\n <div className=\"space-y-0.5\">\n {symbols.map(sym => {\n const q = DEMO_QUOTES[sym];\n const up = (q?.change ?? 0) >= 0;\n const color = !q ? 'text-gray-400' : q.change > 0 ? 'text-green-600' : q.change < 0 ? 'text-red-600' : 'text-gray-500';\n return (\n <div key={sym} className=\"flex items-center justify-between px-2 py-2 border-b border-gray-200 last:border-0\">\n <span className=\"text-sm font-bold text-gray-800 tracking-tight\">{sym}</span>\n {q ? (\n <div className=\"flex flex-col items-end leading-tight\">\n <span className=\"text-sm font-mono font-semibold text-gray-900 tabular-nums\">{fmtPrice(q.price)}</span>\n <span className={`text-[11px] font-medium tabular-nums ${color}`}>{up ? '▲' : '▼'} {fmtSigned(q.change)} ({fmtSigned(q.changePct)}%)</span>\n </div>\n ) : (\n <span className=\"text-sm font-mono text-gray-400 tabular-nums\">—</span>\n )}\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"Stock Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Symbols <span className=\"text-[11px] font-normal text-gray-400\">({configSymbols.length}/{MAX_SYMBOLS})</span></h3>\n <div className=\"space-y-1 mb-2\">\n {configSymbols.map((s, i) => (\n <div key={i} className=\"flex items-center justify-between py-1 px-2 bg-gray-50 rounded\">\n <span className=\"text-sm font-semibold text-gray-700\">{s}</span>\n <button onClick={() => setConfigSymbols(p => p.filter((_, idx) => idx !== i))} className=\"text-red-400 hover:text-red-600\">&times;</button>\n </div>\n ))}\n {configSymbols.length === 0 && <p className=\"text-[11px] text-gray-400 italic\">No symbols — add a ticker below.</p>}\n </div>\n {configSymbols.length < MAX_SYMBOLS ? (\n <div className=\"flex items-center gap-2\">\n <input value={newSymbol} onChange={e => setNewSymbol(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') addSymbol(); }}\n placeholder=\"e.g. NVDA\" className=\"flex-1 bg-gray-50 border border-gray-200 rounded px-2 py-1 text-sm uppercase focus:outline-none focus:ring-1 focus:ring-blue-500\" />\n <button onClick={addSymbol} className=\"text-sm font-medium text-blue-600 hover:text-blue-800 px-2\">+ Add</button>\n </div>\n ) : (\n <p className=\"text-[11px] text-gray-400 italic\">Max {MAX_SYMBOLS} symbols — remove one to add another.</p>\n )}\n {availableTickers.length > 0 && configSymbols.length < MAX_SYMBOLS && (\n <div className=\"flex flex-wrap gap-1.5 mt-2\">\n {availableTickers.map(t => (\n <button key={t} onClick={() => setConfigSymbols(p => p.length < MAX_SYMBOLS ? [...p, t] : p)}\n className=\"text-[11px] font-medium text-gray-600 bg-gray-100 hover:bg-gray-200 rounded px-2 py-0.5 transition-colors\">{t}</button>\n ))}\n </div>\n )}\n <p className=\"text-[11px] text-gray-400 mt-2\">Demo prices — static sample data, no live feed.</p>\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}