react-os-shell 4.8.0 → 4.10.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-5ML7UNZG.js → Browser-KTPGFDE7.js} +6 -6
- package/dist/{Browser-5ML7UNZG.js.map → Browser-KTPGFDE7.js.map} +1 -1
- package/dist/{Calculator-APBKAUZ5.js → Calculator-BQQZETR7.js} +5 -5
- package/dist/{Calculator-APBKAUZ5.js.map → Calculator-BQQZETR7.js.map} +1 -1
- package/dist/ConfirmDialog-GRW3ZQQ2.js +4 -0
- package/dist/{ConfirmDialog-LO5WHLMD.js.map → ConfirmDialog-GRW3ZQQ2.js.map} +1 -1
- package/dist/{CurrencyConverter-YOWLTKY7.js → CurrencyConverter-QAC7SX3T.js} +5 -5
- package/dist/{CurrencyConverter-YOWLTKY7.js.map → CurrencyConverter-QAC7SX3T.js.map} +1 -1
- package/dist/{Documents-TGBZ4E2R.js → Documents-353VLYHV.js} +6 -6
- package/dist/{Documents-TGBZ4E2R.js.map → Documents-353VLYHV.js.map} +1 -1
- package/dist/{Files-LR5EBBSX.js → Files-QOTM6XX4.js} +8 -8
- package/dist/{Files-LR5EBBSX.js.map → Files-QOTM6XX4.js.map} +1 -1
- package/dist/{Notepad-HMTNO6IE.js → Notepad-OSEQE5B3.js} +6 -6
- package/dist/{Notepad-HMTNO6IE.js.map → Notepad-OSEQE5B3.js.map} +1 -1
- package/dist/{PomodoroTimer-NA3LPTTY.js → PomodoroTimer-U5VWYCVW.js} +6 -6
- package/dist/{PomodoroTimer-NA3LPTTY.js.map → PomodoroTimer-U5VWYCVW.js.map} +1 -1
- package/dist/{Preview-LXCNGCIK.js → Preview-MCB7KXQK.js} +6 -6
- package/dist/{Preview-LXCNGCIK.js.map → Preview-MCB7KXQK.js.map} +1 -1
- package/dist/{Sidebar-E553SOXC.js → Sidebar-ITLRERXE.js} +6 -5
- package/dist/Sidebar-ITLRERXE.js.map +1 -0
- package/dist/{Spreadsheet-VWUOANMV.js → Spreadsheet-BNNVXYL7.js} +6 -6
- package/dist/{Spreadsheet-VWUOANMV.js.map → Spreadsheet-BNNVXYL7.js.map} +1 -1
- package/dist/{Stock-OUVV3A7U.js → Stock-YVLKKFD2.js} +5 -5
- package/dist/{Stock-OUVV3A7U.js.map → Stock-YVLKKFD2.js.map} +1 -1
- package/dist/{Weather-INO44ZWL.js → Weather-QW5FVAMP.js} +5 -5
- package/dist/{Weather-INO44ZWL.js.map → Weather-QW5FVAMP.js.map} +1 -1
- package/dist/{WorldClock-K5IOWZ62.js → WorldClock-PMD62JKH.js} +5 -5
- package/dist/{WorldClock-K5IOWZ62.js.map → WorldClock-PMD62JKH.js.map} +1 -1
- package/dist/apps/index.js +18 -18
- package/dist/chunk-EQCNSQL4.js +7 -0
- package/dist/{chunk-FLHS7RBG.js.map → chunk-EQCNSQL4.js.map} +1 -1
- package/dist/{chunk-QAKURGOG.js → chunk-H5NDQZ4A.js} +3 -3
- package/dist/{chunk-QAKURGOG.js.map → chunk-H5NDQZ4A.js.map} +1 -1
- package/dist/{chunk-LBY7KH2W.js → chunk-HC6N2OXO.js} +3 -3
- package/dist/{chunk-LBY7KH2W.js.map → chunk-HC6N2OXO.js.map} +1 -1
- package/dist/{chunk-3NZSR3ZG.js → chunk-KILLK5UH.js} +3 -3
- package/dist/{chunk-3NZSR3ZG.js.map → chunk-KILLK5UH.js.map} +1 -1
- package/dist/{chunk-2Y6XUY65.js → chunk-P75F4NLD.js} +3 -3
- package/dist/{chunk-2Y6XUY65.js.map → chunk-P75F4NLD.js.map} +1 -1
- package/dist/{chunk-XRUVR7M7.js → chunk-QIVJUUPZ.js} +5 -5
- package/dist/{chunk-XRUVR7M7.js.map → chunk-QIVJUUPZ.js.map} +1 -1
- package/dist/{chunk-CKY62ZRU.js → chunk-QIY5BJJN.js} +13 -12
- package/dist/chunk-QIY5BJJN.js.map +1 -0
- package/dist/{chunk-DKDD5KXG.js → chunk-RVT2A2MO.js} +2 -2
- package/dist/chunk-RVT2A2MO.js.map +1 -0
- package/dist/{chunk-ITZB7RDX.js → chunk-YBRTKM4H.js} +3 -3
- package/dist/{chunk-ITZB7RDX.js.map → chunk-YBRTKM4H.js.map} +1 -1
- package/dist/index.d.ts +19 -5
- package/dist/index.js +197 -136
- package/dist/index.js.map +1 -1
- package/dist/styles.css +4 -3
- package/package.json +1 -1
- package/dist/ConfirmDialog-LO5WHLMD.js +0 -4
- package/dist/Sidebar-E553SOXC.js.map +0 -1
- package/dist/chunk-CKY62ZRU.js.map +0 -1
- package/dist/chunk-DKDD5KXG.js.map +0 -1
- package/dist/chunk-FLHS7RBG.js +0 -7
|
@@ -102,5 +102,5 @@ var GLASS_DIVIDER = "border-white/20";
|
|
|
102
102
|
var GLASS_INPUT_BG = "glass-input-bg";
|
|
103
103
|
|
|
104
104
|
export { GLASS_DIVIDER, GLASS_INPUT_BG, ShellAuthProvider, glassStyle, isReachable, isSection, navIcons, navSections, sectionIcons, setShellNavIcons, startMenuCategories, useShellAuth, visibleChildren };
|
|
105
|
-
//# sourceMappingURL=chunk-
|
|
106
|
-
//# sourceMappingURL=chunk-
|
|
105
|
+
//# sourceMappingURL=chunk-RVT2A2MO.js.map
|
|
106
|
+
//# sourceMappingURL=chunk-RVT2A2MO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shell/nav-types.ts","../src/shell-config/nav.tsx","../src/shell/ShellAuth.tsx","../src/utils/glass.ts"],"names":[],"mappings":"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","file":"chunk-RVT2A2MO.js","sourcesContent":["/**\n * Nav data types used by <Layout> + <StartMenu>. The actual sections, icons,\n * and categories are consumer-supplied via Layout props — the package never\n * ships nav DATA, only the shape it expects.\n */\nimport type { ReactNode } from 'react';\n\nexport interface NavItem {\n to: string;\n label: string;\n perms?: string[];\n dividerAfter?: boolean;\n /** Optional 3rd-level sub-items. Hovering the parent in <StartMenu> opens\n * a nested flyout; in <Sidebar> the parent becomes an inline sub-accordion. */\n children?: NavItem[];\n}\n\nexport interface NavSection {\n label: string;\n items: NavItem[];\n perms?: string[];\n /** Optional landing route for clicks on the section title itself\n * (e.g. R&D's `/rd` dashboard). */\n to?: string;\n /** Draw a divider under this section's row, so a consumer can split one\n * flat group into visual bands (e.g. an operator console pinned above the\n * ERP sections). Same knob as `NavItem.dividerAfter`, and drawn INSIDE the\n * section's wrapper so it stays below the row in the `flex-col-reverse`\n * Start menu a side/top taskbar renders. */\n dividerAfter?: boolean;\n}\n\nexport interface VirtualSection {\n label: string;\n items: NavItem[];\n icon?: ReactNode;\n}\n\nexport interface StartMenuCategories {\n /** Section labels rendered in the \"ERP\" group (bold, with section icon). */\n erp: string[];\n /** Section labels rendered in the \"system\" group. */\n system: string[];\n /** Optional virtual flyouts (e.g. a \"Utilities\" tray). */\n virtual?: VirtualSection[];\n /** Optional section labels pinned to the bottom of the menu, next to the user\n * profile, separated from the ERP group by a divider. */\n footer?: string[];\n /** Optional flat top-level items pinned to the bottom of the menu, next to\n * the user profile, separated from the ERP group by a divider. Unlike\n * `footer` (section labels rendered as flyouts), these render as direct\n * clickable rows — use for standalone destinations like System Preferences\n * or a bug-report link. */\n footerItems?: NavItem[];\n}\n\nexport function isSection(item: NavSection | NavItem): item is NavSection {\n return 'items' in item;\n}\n\n/** The host app's permission predicate — `useAuth().hasAnyPerm`. */\ntype HasAnyPerm = (perms: string[]) => boolean;\n\n/**\n * The sub-items of `item` this user may actually see.\n *\n * Every affordance for a nested group has to be derived from THIS list — the\n * chevron that advertises it, the hover handler that opens it, and the flyout\n * itself. Reading the raw `item.children` for the chevron while filtering only\n * for the flyout put an arrow on groups whose children were all\n * permission-hidden: hovering one highlighted the row and opened nothing.\n */\nexport function visibleChildren(item: NavItem, hasAnyPerm: HasAnyPerm): NavItem[] {\n return (item.children ?? []).filter(c => !c.perms || hasAnyPerm(c.perms));\n}\n\n/**\n * Whether a nav row leads anywhere for this user: either it's a plain\n * destination, or it's a group with at least one visible child. A group whose\n * children are all hidden has nothing to open — and by convention a group's\n * `to` is a synthetic key that never navigates, so there is nothing to fall\n * back to either. Such a row is dropped rather than rendered inert.\n */\nexport function isReachable(item: NavItem, hasAnyPerm: HasAnyPerm): boolean {\n return !item.children?.length || visibleChildren(item, hasAnyPerm).length > 0;\n}\n","/**\n * INTERNAL stub — package-side compatibility for files that legacy-imported\n * default nav data from `shell-config/nav`. The package never ships nav\n * DATA; consumers always supply `navSections` / `navIcons` / `sectionIcons` /\n * `categories` as Layout props.\n *\n * Empty defaults exported here so the copied files compile during the\n * extraction transition. Each consumer-facing field is also re-exported as\n * a TYPE alias for code that only needed the shape.\n */\nimport type { ReactNode } from 'react';\nimport type { NavItem, NavSection, StartMenuCategories, VirtualSection } from '../shell/nav-types';\n\n// Live proxy: WindowManager reads window-title icons from this module-level\n// map. Consumers register their full icon set once at app startup so the\n// title bars show the same glyphs as the start menu.\nconst _navIcons: Record<string, ReactNode> = {};\nexport const navIcons: Record<string, ReactNode> = new Proxy(_navIcons, {\n get(_t, k: string) { return _navIcons[k]; },\n has(_t, k: string) { return k in _navIcons; },\n ownKeys() { return Object.keys(_navIcons); },\n getOwnPropertyDescriptor(_t, k: string) {\n if (k in _navIcons) return { configurable: true, enumerable: true, value: _navIcons[k] };\n return undefined;\n },\n});\nexport function setShellNavIcons(icons: Record<string, ReactNode>): void {\n for (const k of Object.keys(_navIcons)) delete _navIcons[k];\n Object.assign(_navIcons, icons);\n}\n\nexport const sectionIcons: Record<string, ReactNode> = {};\nexport const navSections: (NavSection | NavItem)[] = [];\nexport const startMenuCategories: StartMenuCategories = { erp: [], system: [], virtual: [], footer: [] };\n\nexport { isSection } from '../shell/nav-types';\nexport type { NavItem, NavSection, StartMenuCategories, VirtualSection };\n","/**\n * Shell-side auth surface — JUST permission checking. The shell never\n * authenticates anyone or holds tokens; it only asks \"is the current user\n * allowed to see this nav item?\".\n *\n * Consumer wraps the app:\n *\n * <ShellAuthProvider value={{ hasAnyPerm: (perms) => myAuth.has(...perms) }}>\n * <Layout ... />\n * </ShellAuthProvider>\n *\n * When no provider is mounted, every permission check returns true — useful\n * for demos and consumers that don't gate their UI.\n */\nimport { createContext, useContext, type ReactNode } from 'react';\n\nexport interface ShellAuth {\n /** Returns true if the current user has any of the listed permission codes. */\n hasAnyPerm: (perms: string[]) => boolean;\n}\n\nconst DEFAULT: ShellAuth = { hasAnyPerm: () => true };\n\nconst ShellAuthContext = createContext<ShellAuth>(DEFAULT);\n\nexport function ShellAuthProvider({ value, children }: { value: ShellAuth; children: ReactNode }) {\n return <ShellAuthContext.Provider value={value}>{children}</ShellAuthContext.Provider>;\n}\n\nexport function useShellAuth(): ShellAuth {\n return useContext(ShellAuthContext);\n}\n","import type { CSSProperties } from 'react';\n\n/** Read the system menu opacity from CSS custom property set by Layout */\nfunction getMenuOpacity(): number {\n try {\n const val = getComputedStyle(document.documentElement).getPropertyValue('--menu-opacity')?.trim();\n if (val) return parseFloat(val);\n } catch {}\n return 0.95;\n}\n\nfunction isDarkTheme(): boolean {\n try {\n return document.documentElement.getAttribute('data-theme') === 'dark';\n } catch {\n return false;\n }\n}\n\n/** Whether the \"Reduce transparency\" preference is active (root class set by\n * Layout). When on, glass surfaces render solid + blur-free — the blur is the\n * GPU-expensive part, and dropping it is the point of the setting. */\nfunction reduceTransparency(): boolean {\n try {\n return document.documentElement.classList.contains('rosh-reduce-transparency');\n } catch {\n return false;\n }\n}\n\n/** Frosted glass style — shared across all menus, popups, and glass UI elements.\n * Reads --menu-opacity CSS variable set by the theme system, and adapts the\n * base tint to dark mode so menus don't stay light-cream when text is light. */\nexport function glassStyle(opacity?: number): CSSProperties {\n const o = opacity ?? getMenuOpacity();\n if (reduceTransparency()) {\n // Reduce-transparency: a fully opaque, blur-free surface. No\n // backdrop-filter (the expensive part on low-end GPUs) and a solid\n // background so menus/popups stay legible over any wallpaper. The global\n // stylesheet rule also strips backdrop-filter, but returning a solid\n // background here is what keeps the surface from reading as washed-out\n // translucent glass with the blur gone.\n return isDarkTheme()\n ? {\n background: '#1e1e2e',\n border: '1px solid rgba(255,255,255,0.12)',\n boxShadow: '0 8px 24px rgba(0,0,0,0.5)',\n }\n : {\n background: '#ffffff',\n border: '1px solid rgba(0,0,0,0.12)',\n boxShadow: '0 8px 24px rgba(0,0,0,0.18)',\n };\n }\n if (isDarkTheme()) {\n // Dark frosted glass — Catppuccin-aligned base (#1e1e2e / 30,30,46) with\n // a subtle gradient and lighter inner highlight.\n return {\n background: `linear-gradient(135deg, rgba(30,30,46,${o * 0.85}) 0%, rgba(24,24,37,${o * 0.75}) 50%, rgba(30,30,46,${o * 0.85}) 100%)`,\n backdropFilter: 'blur(40px) saturate(1.6)',\n WebkitBackdropFilter: 'blur(40px) saturate(1.6)',\n border: '1px solid rgba(255,255,255,0.08)',\n boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.06), inset 0 -1px 0 rgba(0,0,0,0.4), 0 8px 32px rgba(0,0,0,0.5), 0 2px 8px rgba(0,0,0,0.3)',\n };\n }\n return {\n background: `linear-gradient(135deg, rgba(255,255,255,${o * 0.85}) 0%, rgba(255,255,255,${o * 0.65}) 50%, rgba(255,255,255,${o * 0.75}) 100%)`,\n backdropFilter: 'blur(40px) saturate(1.8)',\n WebkitBackdropFilter: 'blur(40px) saturate(1.8)',\n border: '1px solid rgba(255,255,255,0.35)',\n boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.4), inset 0 -1px 0 rgba(255,255,255,0.1), 0 8px 32px rgba(0,0,0,0.15), 0 2px 8px rgba(0,0,0,0.08)',\n };\n}\n\n/** Glass divider border color */\nexport const GLASS_DIVIDER = 'border-white/20';\n\n/** Glass input/search bar background — declared in styles.css so it can adapt\n * to dark mode (a flat `bg-white/15` reads as a too-bright tile on the dark\n * glass gradient). */\nexport const GLASS_INPUT_BG = 'glass-input-bg';\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Modal } from './chunk-
|
|
1
|
+
import { Modal } from './chunk-QIY5BJJN.js';
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
var DEFAULT_APPEARANCE = { activeOpacity: 70, inactiveOpacity: 50, activeBlur: 0, inactiveBlur: 0 };
|
|
@@ -138,5 +138,5 @@ function WidgetSettingsModal({ open, onClose, title, appearance, onAppearanceCha
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
export { WidgetSettingsModal, loadAppearance };
|
|
141
|
-
//# sourceMappingURL=chunk-
|
|
142
|
-
//# sourceMappingURL=chunk-
|
|
141
|
+
//# sourceMappingURL=chunk-YBRTKM4H.js.map
|
|
142
|
+
//# sourceMappingURL=chunk-YBRTKM4H.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shell/WidgetSettingsModal.tsx"],"names":[],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/shell/WidgetSettingsModal.tsx"],"names":[],"mappings":"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","file":"chunk-YBRTKM4H.js","sourcesContent":["import Modal from './Modal';\n\nexport interface WidgetAppearance {\n activeOpacity: number;\n inactiveOpacity: number;\n activeBlur: number;\n inactiveBlur: number;\n}\n\nexport const DEFAULT_APPEARANCE: WidgetAppearance = { activeOpacity: 70, inactiveOpacity: 50, activeBlur: 0, inactiveBlur: 0 };\n\nexport function loadAppearance(key: string): WidgetAppearance {\n try {\n const saved = JSON.parse(localStorage.getItem(key) || '');\n // Migrate old single `blur` field to activeBlur/inactiveBlur\n if (saved.blur != null && saved.activeBlur == null) {\n saved.activeBlur = saved.blur;\n saved.inactiveBlur = saved.blur;\n delete saved.blur;\n }\n return { ...DEFAULT_APPEARANCE, ...saved };\n }\n catch { return DEFAULT_APPEARANCE; }\n}\n\n/** Reusable settings modal for widgets — renders appearance sliders + optional extra content above */\nexport default function WidgetSettingsModal({ open, onClose, title, appearance, onAppearanceChange, onSave, children }: {\n open: boolean;\n onClose: () => void;\n title: string;\n appearance: WidgetAppearance;\n onAppearanceChange: (a: WidgetAppearance) => void;\n onSave: () => void;\n children?: React.ReactNode;\n}) {\n if (!open) return null;\n\n const inp = 'w-full h-1.5 rounded-full appearance-none bg-gray-200 cursor-pointer accent-blue-500';\n const lbl = 'flex items-center justify-between text-xs text-gray-500';\n\n return (\n <div onPointerDown={e => e.stopPropagation()} onContextMenu={e => e.stopPropagation()}>\n <Modal open={open} onClose={onClose} title={title} size=\"sm\">\n <div className=\"space-y-4\">\n {children}\n\n {/* Appearance */}\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-3\">Appearance</h3>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <div className=\"text-xs font-medium text-gray-600 mb-2\">Active</div>\n <div className=\"space-y-2\">\n <div>\n <div className={lbl}><span>Opacity</span><span>{appearance.activeOpacity}%</span></div>\n <input type=\"range\" min={20} max={100} value={appearance.activeOpacity}\n onChange={e => onAppearanceChange({ ...appearance, activeOpacity: +e.target.value })} className={inp} />\n </div>\n <div>\n <div className={lbl}><span>Blur</span><span>{appearance.activeBlur}px</span></div>\n <input type=\"range\" min={0} max={20} value={appearance.activeBlur}\n onChange={e => onAppearanceChange({ ...appearance, activeBlur: +e.target.value })} className={inp} />\n </div>\n </div>\n </div>\n <div>\n <div className=\"text-xs font-medium text-gray-600 mb-2\">Inactive</div>\n <div className=\"space-y-2\">\n <div>\n <div className={lbl}><span>Opacity</span><span>{appearance.inactiveOpacity}%</span></div>\n <input type=\"range\" min={20} max={100} value={appearance.inactiveOpacity}\n onChange={e => onAppearanceChange({ ...appearance, inactiveOpacity: +e.target.value })} className={inp} />\n </div>\n <div>\n <div className={lbl}><span>Blur</span><span>{appearance.inactiveBlur}px</span></div>\n <input type=\"range\" min={0} max={20} value={appearance.inactiveBlur}\n onChange={e => onAppearanceChange({ ...appearance, inactiveBlur: +e.target.value })} className={inp} />\n </div>\n </div>\n </div>\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"flex gap-2 pt-2\">\n <button onClick={onSave}\n className=\"flex-1 text-sm font-medium py-2 rounded-lg bg-blue-600 text-white hover:bg-blue-700 transition\">Save</button>\n <button onClick={onClose}\n className=\"flex-1 text-sm font-medium py-2 rounded-lg border border-gray-300 text-gray-600 hover:bg-gray-50 transition\">Cancel</button>\n </div>\n </div>\n </Modal>\n </div>\n );\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -44,6 +44,12 @@ interface NavSection {
|
|
|
44
44
|
/** Optional landing route for clicks on the section title itself
|
|
45
45
|
* (e.g. R&D's `/rd` dashboard). */
|
|
46
46
|
to?: string;
|
|
47
|
+
/** Draw a divider under this section's row, so a consumer can split one
|
|
48
|
+
* flat group into visual bands (e.g. an operator console pinned above the
|
|
49
|
+
* ERP sections). Same knob as `NavItem.dividerAfter`, and drawn INSIDE the
|
|
50
|
+
* section's wrapper so it stays below the row in the `flex-col-reverse`
|
|
51
|
+
* Start menu a side/top taskbar renders. */
|
|
52
|
+
dividerAfter?: boolean;
|
|
47
53
|
}
|
|
48
54
|
interface VirtualSection {
|
|
49
55
|
label: string;
|
|
@@ -225,11 +231,16 @@ interface ModalProps {
|
|
|
225
231
|
openedFromKey?: string;
|
|
226
232
|
/** Per-section window accent (SG#00372): an `R G B` triple (e.g.
|
|
227
233
|
* '91 141 190'). When set, the panel publishes it as the
|
|
228
|
-
* `--window-accent-rgb` CSS custom property and
|
|
229
|
-
*
|
|
234
|
+
* `--window-accent-rgb` CSS custom property, and — if the user has turned
|
|
235
|
+
* the `window_accent_stripe` preference on — renders a thin accent stripe
|
|
236
|
+
* between the title bar and the body, so overlapping windows from
|
|
230
237
|
* different app sections are distinguishable at a glance. The header
|
|
231
238
|
* itself stays theme-neutral — themes and the user's custom header
|
|
232
|
-
* colour are untouched. Absent = exactly the previous rendering.
|
|
239
|
+
* colour are untouched. Absent = exactly the previous rendering.
|
|
240
|
+
*
|
|
241
|
+
* The CSS custom property is published whenever `accentRgb` is passed,
|
|
242
|
+
* independent of the preference, so consumer CSS can key off the section
|
|
243
|
+
* accent even with the stripe switched off. */
|
|
233
244
|
accentRgb?: string;
|
|
234
245
|
children: React.ReactNode;
|
|
235
246
|
}
|
|
@@ -956,8 +967,11 @@ declare function WindowManagerProvider({ children, windowAccentForRoute }: {
|
|
|
956
967
|
children: ReactNode;
|
|
957
968
|
/** SG#00372: optional per-section window accent. Called with each open
|
|
958
969
|
* window's route ('/sales-orders', '/payments', …); return an `R G B`
|
|
959
|
-
* triple (e.g. '91 141 190') to give that window a thin accent stripe
|
|
960
|
-
* its title bar (see Modal's `accentRgb`), or undefined
|
|
970
|
+
* triple (e.g. '91 141 190') to give that window a thin accent stripe
|
|
971
|
+
* between its title bar and body (see Modal's `accentRgb`), or undefined
|
|
972
|
+
* for no accent. The stripe is drawn only for users who have switched it
|
|
973
|
+
* on in Customization → Windows; the mapping is still worth wiring
|
|
974
|
+
* regardless, since it also publishes `--window-accent-rgb` per window.
|
|
961
975
|
* The consumer owns the route→section→colour mapping; omitting the prop
|
|
962
976
|
* keeps every window exactly as before. */
|
|
963
977
|
windowAccentForRoute?: (route: string) => string | undefined;
|
package/dist/index.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import { PREVIEW_OPENED_EVENT, openPreviewFile } from './chunk-DINNWYVB.js';
|
|
2
2
|
export { Breadcrumbs } from './chunk-DINNWYVB.js';
|
|
3
|
-
import { subscribePomo, getPomoSnapshot } from './chunk-
|
|
4
|
-
export { setShellTodoProvider } from './chunk-
|
|
3
|
+
import { subscribePomo, getPomoSnapshot } from './chunk-P75F4NLD.js';
|
|
4
|
+
export { setShellTodoProvider } from './chunk-P75F4NLD.js';
|
|
5
5
|
import { SidebarLayout } from './chunk-YG45DAUT.js';
|
|
6
6
|
export { SidebarLayout } from './chunk-YG45DAUT.js';
|
|
7
7
|
export { ImageAnnotator_default as ImageAnnotator } from './chunk-QU5L5ZYM.js';
|
|
8
8
|
import { toast_default } from './chunk-VENYVK3L.js';
|
|
9
9
|
export { toast_default as toast } from './chunk-VENYVK3L.js';
|
|
10
|
-
import { publishDesktopFolders, requestFilesTrashView, FolderGlyph, requestFilesDesktopFolderView, FileIconTile } from './chunk-
|
|
10
|
+
import { publishDesktopFolders, requestFilesTrashView, FolderGlyph, requestFilesDesktopFolderView, FileIconTile } from './chunk-H5NDQZ4A.js';
|
|
11
11
|
import { setPdfPreview } from './chunk-BV6SQ46N.js';
|
|
12
12
|
import { playNotification, playStartup, soundsEnabled, getSoundConfig, SOUND_PACK_KEYS, SOUND_PACKS, SOUND_TYPES, SOUND_TYPE_LABELS, setSoundForType, previewSound, setAllSounds, playLogout } from './chunk-D7PYW2QS.js';
|
|
13
|
-
import { useAuth } from './chunk-
|
|
14
|
-
export { setShellAuthBridge } from './chunk-
|
|
13
|
+
import { useAuth } from './chunk-KILLK5UH.js';
|
|
14
|
+
export { setShellAuthBridge } from './chunk-KILLK5UH.js';
|
|
15
15
|
import { EditableGrid } from './chunk-GP4Y3VCB.js';
|
|
16
16
|
export { EditableGrid } from './chunk-GP4Y3VCB.js';
|
|
17
17
|
import './chunk-4SQU5YV6.js';
|
|
18
|
-
import { APP_VERSION, VERSION } from './chunk-
|
|
19
|
-
export { VERSION } from './chunk-
|
|
20
|
-
import { registerModalEscapeInterceptor, useIsMobile, cancelWindowFront, requestWindowFront, useWindowManager, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, WINDOW_REGISTRY, isPageEntry, Modal, setPerfCollecting, drainPerfEvents, useShellPrefs, markMenuOpen, SIDEBAR_STRIP_W, forgetMaximizedWindowBoxes, ModalActions, useModalActive, client_default, LoadingSpinner, isShellApiClientConfigured, useUndo, CancelButton, setWindowPosition } from './chunk-
|
|
21
|
-
export { CancelButton, ConfirmProvider, CopyButton, DocFavStar, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, ShellPrefsProvider, UndoProvider, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, beginWindowGesture, commitExposeHighlight, confirm, confirmDestructive, exitExposeMode, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, markMenuOpen, prompt, registerModalEscapeInterceptor, requestWindowFront, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useIsActiveWindow, useLocalStoragePrefs, useModalActive, useShellPrefs, useUndo, useUndoable, useUndoableState, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-
|
|
22
|
-
import { glassStyle, startMenuCategories, navSections, isSection, GLASS_INPUT_BG, navIcons, isReachable, sectionIcons, useShellAuth, visibleChildren } from './chunk-
|
|
23
|
-
export { GLASS_DIVIDER, GLASS_INPUT_BG, ShellAuthProvider, glassStyle, setShellNavIcons, useShellAuth } from './chunk-
|
|
18
|
+
import { APP_VERSION, VERSION } from './chunk-EQCNSQL4.js';
|
|
19
|
+
export { VERSION } from './chunk-EQCNSQL4.js';
|
|
20
|
+
import { registerModalEscapeInterceptor, useIsMobile, cancelWindowFront, requestWindowFront, useWindowManager, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, WINDOW_REGISTRY, isPageEntry, Modal, setPerfCollecting, drainPerfEvents, useShellPrefs, markMenuOpen, SIDEBAR_STRIP_W, forgetMaximizedWindowBoxes, ModalActions, useModalActive, client_default, LoadingSpinner, isShellApiClientConfigured, useUndo, CancelButton, setWindowPosition } from './chunk-QIY5BJJN.js';
|
|
21
|
+
export { CancelButton, ConfirmProvider, CopyButton, DocFavStar, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, ShellPrefsProvider, UndoProvider, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, beginWindowGesture, commitExposeHighlight, confirm, confirmDestructive, exitExposeMode, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, markMenuOpen, prompt, registerModalEscapeInterceptor, requestWindowFront, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useIsActiveWindow, useLocalStoragePrefs, useModalActive, useShellPrefs, useUndo, useUndoable, useUndoableState, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-QIY5BJJN.js';
|
|
22
|
+
import { glassStyle, startMenuCategories, navSections, isSection, GLASS_INPUT_BG, navIcons, isReachable, sectionIcons, useShellAuth, visibleChildren } from './chunk-RVT2A2MO.js';
|
|
23
|
+
export { GLASS_DIVIDER, GLASS_INPUT_BG, ShellAuthProvider, glassStyle, setShellNavIcons, useShellAuth } from './chunk-RVT2A2MO.js';
|
|
24
24
|
import { createContext, lazy, forwardRef, useCallback, useState, useRef, useId, useEffect, useLayoutEffect, useSyncExternalStore, useMemo, useContext, isValidElement, cloneElement, Suspense, Fragment as Fragment$1, Children } from 'react';
|
|
25
25
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
26
26
|
import { Dialog, DialogBackdrop, DialogPanel } from '@headlessui/react';
|
|
@@ -3809,18 +3809,21 @@ function StartMenu({
|
|
|
3809
3809
|
const items = getVisibleItems(section);
|
|
3810
3810
|
if (items.length === 0) return null;
|
|
3811
3811
|
const isHovered = hoveredSection === section.label;
|
|
3812
|
-
return /* @__PURE__ */
|
|
3812
|
+
return /* @__PURE__ */ jsxs(
|
|
3813
3813
|
"div",
|
|
3814
3814
|
{
|
|
3815
3815
|
onMouseEnter: (e) => handleSectionHover(section.label, e),
|
|
3816
3816
|
onMouseLeave: () => {
|
|
3817
3817
|
hoverTimeout.current = setTimeout(() => setHoveredSection(null), 200);
|
|
3818
3818
|
},
|
|
3819
|
-
children:
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3819
|
+
children: [
|
|
3820
|
+
/* @__PURE__ */ jsxs("button", { className: `${itemCls} transition-colors ${isHovered ? "bg-blue-50 text-blue-700" : "text-gray-700 hover:bg-blue-50 hover:text-blue-700"}`, children: [
|
|
3821
|
+
secIcon(section.label),
|
|
3822
|
+
/* @__PURE__ */ jsx("span", { className: isErp ? "font-medium" : "", children: section.label }),
|
|
3823
|
+
/* @__PURE__ */ jsx("svg", { className: "h-3.5 w-3.5 ml-auto text-gray-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8.25 4.5l7.5 7.5-7.5 7.5" }) })
|
|
3824
|
+
] }),
|
|
3825
|
+
section.dividerAfter && /* @__PURE__ */ jsx("div", { className: "border-t border-white/20 my-1.5 mx-2" })
|
|
3826
|
+
]
|
|
3824
3827
|
},
|
|
3825
3828
|
section.label
|
|
3826
3829
|
);
|
|
@@ -4141,7 +4144,7 @@ function MobileAppLanding({
|
|
|
4141
4144
|
}
|
|
4142
4145
|
);
|
|
4143
4146
|
}
|
|
4144
|
-
var Sidebar = lazy(() => import('./Sidebar-
|
|
4147
|
+
var Sidebar = lazy(() => import('./Sidebar-ITLRERXE.js'));
|
|
4145
4148
|
function useFavorites(wallpapers) {
|
|
4146
4149
|
const { prefs, save } = useShellPrefs();
|
|
4147
4150
|
const favorites = prefs.favorite_pages || [];
|
|
@@ -5135,6 +5138,24 @@ function Customization({ omit, section } = {}) {
|
|
|
5135
5138
|
}
|
|
5136
5139
|
)
|
|
5137
5140
|
] }),
|
|
5141
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
5142
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900 mb-3", children: "Windows" }),
|
|
5143
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-start gap-2 cursor-pointer", children: [
|
|
5144
|
+
/* @__PURE__ */ jsx(
|
|
5145
|
+
"input",
|
|
5146
|
+
{
|
|
5147
|
+
type: "checkbox",
|
|
5148
|
+
checked: !!pref("window_accent_stripe"),
|
|
5149
|
+
onChange: (e) => savePref("window_accent_stripe", e.target.checked),
|
|
5150
|
+
className: "h-4 w-4 mt-0.5 rounded border-gray-300 text-blue-600"
|
|
5151
|
+
}
|
|
5152
|
+
),
|
|
5153
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-700", children: [
|
|
5154
|
+
"Show section colour stripe",
|
|
5155
|
+
/* @__PURE__ */ jsx("span", { className: "block text-xs text-gray-400", children: "Draws a thin coloured line between a window's title bar and its content, one colour per area of the app, so overlapping windows are easier to tell apart at a glance." })
|
|
5156
|
+
] })
|
|
5157
|
+
] })
|
|
5158
|
+
] }),
|
|
5138
5159
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
5139
5160
|
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900 mb-3", children: "Diagnostics" }),
|
|
5140
5161
|
/* @__PURE__ */ jsxs("label", { className: "flex items-start gap-2 cursor-pointer", children: [
|
|
@@ -7607,6 +7628,18 @@ var MONTH_NAMES = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep"
|
|
|
7607
7628
|
var YEARS_PER_PAGE = 12;
|
|
7608
7629
|
var yearPageStart = (y) => Math.floor(y / YEARS_PER_PAGE) * YEARS_PER_PAGE;
|
|
7609
7630
|
var pad = (n) => String(n).padStart(2, "0");
|
|
7631
|
+
var EDGE_MARGIN = 8;
|
|
7632
|
+
function clipBounds(el) {
|
|
7633
|
+
for (let node = el.parentElement; node; node = node.parentElement) {
|
|
7634
|
+
const style = getComputedStyle(node);
|
|
7635
|
+
const overflowX = style.overflowX || style.overflow;
|
|
7636
|
+
if (overflowX && overflowX !== "visible") {
|
|
7637
|
+
const rect = node.getBoundingClientRect();
|
|
7638
|
+
if (rect.width > 0) return { left: rect.left, right: rect.right };
|
|
7639
|
+
}
|
|
7640
|
+
}
|
|
7641
|
+
return { left: 0, right: window.innerWidth };
|
|
7642
|
+
}
|
|
7610
7643
|
function toISODate2(d) {
|
|
7611
7644
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
|
7612
7645
|
}
|
|
@@ -7631,6 +7664,8 @@ function DateRangePicker({
|
|
|
7631
7664
|
const [tempTo, setTempTo] = useState(to);
|
|
7632
7665
|
const [activePreset, setActivePreset] = useState(null);
|
|
7633
7666
|
const ref = useRef(null);
|
|
7667
|
+
const panelRef = useRef(null);
|
|
7668
|
+
const [align, setAlign] = useState("left");
|
|
7634
7669
|
const now = /* @__PURE__ */ new Date();
|
|
7635
7670
|
const [month, setMonth] = useState(from ? parseDate(from).getMonth() : now.getMonth());
|
|
7636
7671
|
const [year, setYear] = useState(from ? parseDate(from).getFullYear() : now.getFullYear());
|
|
@@ -7640,6 +7675,22 @@ function DateRangePicker({
|
|
|
7640
7675
|
useClickOutside(ref, useCallback(() => {
|
|
7641
7676
|
if (open) setOpen(false);
|
|
7642
7677
|
}, [open]));
|
|
7678
|
+
useLayoutEffect(() => {
|
|
7679
|
+
if (!open) return;
|
|
7680
|
+
const place = () => {
|
|
7681
|
+
const anchor = ref.current, panel = panelRef.current;
|
|
7682
|
+
if (!anchor || !panel) return;
|
|
7683
|
+
const trigger = anchor.getBoundingClientRect();
|
|
7684
|
+
const width = panel.getBoundingClientRect().width;
|
|
7685
|
+
const bounds = clipBounds(anchor);
|
|
7686
|
+
const fitsLeftAligned = trigger.left + width <= bounds.right - EDGE_MARGIN;
|
|
7687
|
+
const fitsRightAligned = trigger.right - width >= bounds.left + EDGE_MARGIN;
|
|
7688
|
+
setAlign(fitsLeftAligned || !fitsRightAligned ? "left" : "right");
|
|
7689
|
+
};
|
|
7690
|
+
place();
|
|
7691
|
+
window.addEventListener("resize", place);
|
|
7692
|
+
return () => window.removeEventListener("resize", place);
|
|
7693
|
+
}, [open]);
|
|
7643
7694
|
const handleOpen = () => {
|
|
7644
7695
|
setTempFrom(from);
|
|
7645
7696
|
setTempTo(to);
|
|
@@ -7793,135 +7844,145 @@ function DateRangePicker({
|
|
|
7793
7844
|
]
|
|
7794
7845
|
}
|
|
7795
7846
|
),
|
|
7796
|
-
open && /* @__PURE__ */ jsxs(
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
/* @__PURE__ */
|
|
7806
|
-
|
|
7807
|
-
|
|
7808
|
-
|
|
7809
|
-
/* @__PURE__ */ jsxs("div", { className: "w-64", children: [
|
|
7810
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2 px-1", children: [
|
|
7811
|
-
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => handleStep(-1), "aria-label": "Previous", className: "p-1 rounded-full hover:bg-gray-100 text-gray-600", children: /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 19l-7-7 7-7" }) }) }),
|
|
7812
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-sm font-semibold text-gray-800", children: [
|
|
7813
|
-
view === "days" && /* @__PURE__ */ jsx(
|
|
7814
|
-
"button",
|
|
7815
|
-
{
|
|
7816
|
-
type: "button",
|
|
7817
|
-
onClick: () => setView("months"),
|
|
7818
|
-
className: "px-1.5 py-0.5 rounded-md hover:bg-gray-100 transition-colors",
|
|
7819
|
-
children: monthName
|
|
7820
|
-
}
|
|
7821
|
-
),
|
|
7822
|
-
view === "years" ? /* @__PURE__ */ jsxs("span", { className: "px-1.5 py-0.5", children: [
|
|
7823
|
-
yearPage,
|
|
7824
|
-
" \u2013 ",
|
|
7825
|
-
yearPage + YEARS_PER_PAGE - 1
|
|
7826
|
-
] }) : /* @__PURE__ */ jsx(
|
|
7827
|
-
"button",
|
|
7828
|
-
{
|
|
7829
|
-
type: "button",
|
|
7830
|
-
onClick: openYears,
|
|
7831
|
-
className: "px-1.5 py-0.5 rounded-md hover:bg-gray-100 transition-colors",
|
|
7832
|
-
children: year
|
|
7833
|
-
}
|
|
7834
|
-
)
|
|
7847
|
+
open && /* @__PURE__ */ jsxs(
|
|
7848
|
+
"div",
|
|
7849
|
+
{
|
|
7850
|
+
ref: panelRef,
|
|
7851
|
+
role: "dialog",
|
|
7852
|
+
"aria-label": "Date range",
|
|
7853
|
+
className: "absolute z-50 mt-1 rounded-2xl p-4",
|
|
7854
|
+
style: { ...align === "right" ? { right: 0 } : { left: 0 }, ...glassStyle() },
|
|
7855
|
+
children: [
|
|
7856
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 mb-3", children: [
|
|
7857
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
7858
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-500", children: "From" }),
|
|
7859
|
+
/* @__PURE__ */ jsx("span", { className: `text-sm px-2 py-1 rounded border min-w-[90px] ${tempFrom ? "border-blue-300 bg-blue-50 text-blue-700" : "border-gray-200 bg-gray-50 text-gray-400"}`, children: tempFrom ? displayDate(tempFrom) : "Start" })
|
|
7835
7860
|
] }),
|
|
7836
|
-
/* @__PURE__ */ jsx("
|
|
7861
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-300", children: "\u2014" }),
|
|
7862
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
7863
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-500", children: "To" }),
|
|
7864
|
+
/* @__PURE__ */ jsx("span", { className: `text-sm px-2 py-1 rounded border min-w-[90px] ${tempTo ? "border-blue-300 bg-blue-50 text-blue-700" : "border-gray-200 bg-gray-50 text-gray-400"}`, children: tempTo ? displayDate(tempTo) : "End" })
|
|
7865
|
+
] })
|
|
7837
7866
|
] }),
|
|
7838
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
7839
|
-
|
|
7840
|
-
/* @__PURE__ */
|
|
7841
|
-
|
|
7842
|
-
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7867
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
7868
|
+
/* @__PURE__ */ jsxs("div", { className: "w-64", children: [
|
|
7869
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2 px-1", children: [
|
|
7870
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => handleStep(-1), "aria-label": "Previous", className: "p-1 rounded-full hover:bg-gray-100 text-gray-600", children: /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 19l-7-7 7-7" }) }) }),
|
|
7871
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-sm font-semibold text-gray-800", children: [
|
|
7872
|
+
view === "days" && /* @__PURE__ */ jsx(
|
|
7873
|
+
"button",
|
|
7874
|
+
{
|
|
7875
|
+
type: "button",
|
|
7876
|
+
onClick: () => setView("months"),
|
|
7877
|
+
className: "px-1.5 py-0.5 rounded-md hover:bg-gray-100 transition-colors",
|
|
7878
|
+
children: monthName
|
|
7879
|
+
}
|
|
7880
|
+
),
|
|
7881
|
+
view === "years" ? /* @__PURE__ */ jsxs("span", { className: "px-1.5 py-0.5", children: [
|
|
7882
|
+
yearPage,
|
|
7883
|
+
" \u2013 ",
|
|
7884
|
+
yearPage + YEARS_PER_PAGE - 1
|
|
7885
|
+
] }) : /* @__PURE__ */ jsx(
|
|
7886
|
+
"button",
|
|
7887
|
+
{
|
|
7888
|
+
type: "button",
|
|
7889
|
+
onClick: openYears,
|
|
7890
|
+
className: "px-1.5 py-0.5 rounded-md hover:bg-gray-100 transition-colors",
|
|
7891
|
+
children: year
|
|
7892
|
+
}
|
|
7893
|
+
)
|
|
7894
|
+
] }),
|
|
7895
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => handleStep(1), "aria-label": "Next", className: "p-1 rounded-full hover:bg-gray-100 text-gray-600", children: /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) }) })
|
|
7896
|
+
] }),
|
|
7897
|
+
/* @__PURE__ */ jsxs("div", { className: "min-h-[13.75rem]", children: [
|
|
7898
|
+
view === "days" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7899
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 text-center text-xs font-medium text-gray-500 mb-1", children: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((d) => /* @__PURE__ */ jsx("div", { className: "py-1", children: d }, d)) }),
|
|
7900
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 text-center text-sm", children: cells.map((c, i) => {
|
|
7901
|
+
const isStart = c.date === tempFrom;
|
|
7902
|
+
const isEnd = c.date === tempTo;
|
|
7903
|
+
const isSelected = isStart || isEnd;
|
|
7904
|
+
const inRange = isInRange(c.date);
|
|
7905
|
+
return /* @__PURE__ */ jsx(
|
|
7906
|
+
"button",
|
|
7907
|
+
{
|
|
7908
|
+
type: "button",
|
|
7909
|
+
onClick: () => handleCalendarSelect(c.date),
|
|
7910
|
+
className: `py-1.5 rounded-md transition-colors ${!c.current ? "text-gray-300" : isSelected ? "bg-blue-600 text-white font-semibold" : inRange ? "bg-blue-100 text-blue-800" : "text-gray-700 hover:bg-gray-100"}`,
|
|
7911
|
+
children: c.day
|
|
7912
|
+
},
|
|
7913
|
+
i
|
|
7914
|
+
);
|
|
7915
|
+
}) })
|
|
7916
|
+
] }),
|
|
7917
|
+
view === "months" && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-1 text-center text-sm", children: MONTH_NAMES.map((name, m) => {
|
|
7918
|
+
const isCurrent = m === month;
|
|
7919
|
+
const isThisMonth = m === now.getMonth() && year === now.getFullYear();
|
|
7920
|
+
return /* @__PURE__ */ jsx(
|
|
7921
|
+
"button",
|
|
7922
|
+
{
|
|
7923
|
+
type: "button",
|
|
7924
|
+
onClick: () => selectMonth(m),
|
|
7925
|
+
className: `py-4 rounded-md transition-colors ${isCurrent ? "bg-blue-600 text-white font-semibold" : isThisMonth ? "text-blue-600 font-medium hover:bg-gray-100" : "text-gray-700 hover:bg-gray-100"}`,
|
|
7926
|
+
children: name
|
|
7927
|
+
},
|
|
7928
|
+
name
|
|
7929
|
+
);
|
|
7930
|
+
}) }),
|
|
7931
|
+
view === "years" && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-1 text-center text-sm", children: Array.from({ length: YEARS_PER_PAGE }, (_, i) => yearPage + i).map((y) => {
|
|
7932
|
+
const isCurrent = y === year;
|
|
7933
|
+
const isThisYear = y === now.getFullYear();
|
|
7934
|
+
return /* @__PURE__ */ jsx(
|
|
7935
|
+
"button",
|
|
7936
|
+
{
|
|
7937
|
+
type: "button",
|
|
7938
|
+
onClick: () => selectYear(y),
|
|
7939
|
+
className: `py-4 rounded-md transition-colors ${isCurrent ? "bg-blue-600 text-white font-semibold" : isThisYear ? "text-blue-600 font-medium hover:bg-gray-100" : "text-gray-700 hover:bg-gray-100"}`,
|
|
7940
|
+
children: y
|
|
7941
|
+
},
|
|
7942
|
+
y
|
|
7943
|
+
);
|
|
7944
|
+
}) })
|
|
7945
|
+
] })
|
|
7857
7946
|
] }),
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
const isThisMonth = m === now.getMonth() && year === now.getFullYear();
|
|
7861
|
-
return /* @__PURE__ */ jsx(
|
|
7947
|
+
/* @__PURE__ */ jsxs("div", { className: "border-l border-gray-200 pl-4 flex flex-col gap-1 min-w-[130px]", children: [
|
|
7948
|
+
PRESET_LABELS.map((label) => /* @__PURE__ */ jsx(
|
|
7862
7949
|
"button",
|
|
7863
7950
|
{
|
|
7864
7951
|
type: "button",
|
|
7865
|
-
onClick: () =>
|
|
7866
|
-
className: `py-
|
|
7867
|
-
children:
|
|
7952
|
+
onClick: () => handlePreset(label),
|
|
7953
|
+
className: `text-left px-3 py-1.5 text-sm rounded-md transition-colors ${activePreset === label ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-50"}`,
|
|
7954
|
+
children: label
|
|
7868
7955
|
},
|
|
7869
|
-
|
|
7870
|
-
)
|
|
7871
|
-
|
|
7872
|
-
view === "years" && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-1 text-center text-sm", children: Array.from({ length: YEARS_PER_PAGE }, (_, i) => yearPage + i).map((y) => {
|
|
7873
|
-
const isCurrent = y === year;
|
|
7874
|
-
const isThisYear = y === now.getFullYear();
|
|
7875
|
-
return /* @__PURE__ */ jsx(
|
|
7956
|
+
label
|
|
7957
|
+
)),
|
|
7958
|
+
/* @__PURE__ */ jsx(
|
|
7876
7959
|
"button",
|
|
7877
7960
|
{
|
|
7878
7961
|
type: "button",
|
|
7879
|
-
onClick: () =>
|
|
7880
|
-
className: `py-
|
|
7881
|
-
children:
|
|
7882
|
-
}
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7962
|
+
onClick: () => setActivePreset("Custom"),
|
|
7963
|
+
className: `text-left px-3 py-1.5 text-sm rounded-md transition-colors ${activePreset === "Custom" ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-50"}`,
|
|
7964
|
+
children: "Custom"
|
|
7965
|
+
}
|
|
7966
|
+
)
|
|
7967
|
+
] })
|
|
7968
|
+
] }),
|
|
7969
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2 mt-4 pt-3 border-t border-gray-200", children: [
|
|
7970
|
+
clearable && /* @__PURE__ */ jsx("button", { type: "button", onClick: handleClear, className: "px-3 py-1.5 text-sm text-gray-500 hover:text-gray-700", children: "Clear" }),
|
|
7971
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => setOpen(false), className: "px-3 py-1.5 text-sm text-gray-600 border border-gray-300 rounded-md hover:bg-gray-50", children: "Cancel" }),
|
|
7972
|
+
/* @__PURE__ */ jsx(
|
|
7973
|
+
"button",
|
|
7974
|
+
{
|
|
7975
|
+
type: "button",
|
|
7976
|
+
onClick: handleApply,
|
|
7977
|
+
disabled: !tempFrom || !tempTo,
|
|
7978
|
+
className: "px-4 py-1.5 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 disabled:opacity-50",
|
|
7979
|
+
children: "Apply"
|
|
7980
|
+
}
|
|
7981
|
+
)
|
|
7886
7982
|
] })
|
|
7887
|
-
]
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
"button",
|
|
7891
|
-
{
|
|
7892
|
-
type: "button",
|
|
7893
|
-
onClick: () => handlePreset(label),
|
|
7894
|
-
className: `text-left px-3 py-1.5 text-sm rounded-md transition-colors ${activePreset === label ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-50"}`,
|
|
7895
|
-
children: label
|
|
7896
|
-
},
|
|
7897
|
-
label
|
|
7898
|
-
)),
|
|
7899
|
-
/* @__PURE__ */ jsx(
|
|
7900
|
-
"button",
|
|
7901
|
-
{
|
|
7902
|
-
type: "button",
|
|
7903
|
-
onClick: () => setActivePreset("Custom"),
|
|
7904
|
-
className: `text-left px-3 py-1.5 text-sm rounded-md transition-colors ${activePreset === "Custom" ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-50"}`,
|
|
7905
|
-
children: "Custom"
|
|
7906
|
-
}
|
|
7907
|
-
)
|
|
7908
|
-
] })
|
|
7909
|
-
] }),
|
|
7910
|
-
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2 mt-4 pt-3 border-t border-gray-200", children: [
|
|
7911
|
-
clearable && /* @__PURE__ */ jsx("button", { type: "button", onClick: handleClear, className: "px-3 py-1.5 text-sm text-gray-500 hover:text-gray-700", children: "Clear" }),
|
|
7912
|
-
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => setOpen(false), className: "px-3 py-1.5 text-sm text-gray-600 border border-gray-300 rounded-md hover:bg-gray-50", children: "Cancel" }),
|
|
7913
|
-
/* @__PURE__ */ jsx(
|
|
7914
|
-
"button",
|
|
7915
|
-
{
|
|
7916
|
-
type: "button",
|
|
7917
|
-
onClick: handleApply,
|
|
7918
|
-
disabled: !tempFrom || !tempTo,
|
|
7919
|
-
className: "px-4 py-1.5 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 disabled:opacity-50",
|
|
7920
|
-
children: "Apply"
|
|
7921
|
-
}
|
|
7922
|
-
)
|
|
7923
|
-
] })
|
|
7924
|
-
] })
|
|
7983
|
+
]
|
|
7984
|
+
}
|
|
7985
|
+
)
|
|
7925
7986
|
] });
|
|
7926
7987
|
}
|
|
7927
7988
|
function Card({ children, header, footer, padded = true, className = "" }) {
|