@tuturuuu/ui 0.30.2 → 0.32.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.
Files changed (92) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/biome.json +1 -1
  3. package/package.json +95 -49
  4. package/src/components/ui/calendar-app/calendar-client-page.test.tsx +57 -0
  5. package/src/components/ui/calendar-app/calendar-client-page.tsx +13 -4
  6. package/src/components/ui/calendar-app/calendar-page-shell.tsx +7 -1
  7. package/src/components/ui/calendar-app/components/calendar-connections-compact.tsx +47 -39
  8. package/src/components/ui/calendar-app/components/calendar-connections-settings-content.tsx +14 -0
  9. package/src/components/ui/calendar-app/components/calendar-connections-unified.tsx +4 -0
  10. package/src/components/ui/calendar-app/components/calendar-sync-attention-button.tsx +47 -0
  11. package/src/components/ui/calendar-app/components/calendar-sync-recovery.test.tsx +112 -0
  12. package/src/components/ui/calendar-app/components/calendar-sync-recovery.tsx +206 -0
  13. package/src/components/ui/calendar-app/components/calendar-types.ts +1 -1
  14. package/src/components/ui/calendar-app/components/use-calendar-connections-manager.ts +86 -90
  15. package/src/components/ui/chat/ai-message-markdown.tsx +17 -2
  16. package/src/components/ui/custom/language-dropdown-item.tsx +6 -14
  17. package/src/components/ui/custom/nav-link.tsx +7 -7
  18. package/src/components/ui/custom/nav.tsx +15 -63
  19. package/src/components/ui/custom/notification-card.tsx +361 -0
  20. package/src/components/ui/custom/notification-list.tsx +178 -0
  21. package/src/components/ui/custom/notification-popover-client.tsx +12 -780
  22. package/src/components/ui/custom/notification-runtime.tsx +23 -0
  23. package/src/components/ui/custom/onboarding-settings-panel.tsx +8 -55
  24. package/src/components/ui/custom/satellite-account-switcher-menu.tsx +212 -0
  25. package/src/components/ui/custom/satellite-brand.tsx +122 -0
  26. package/src/components/ui/custom/satellite-content.tsx +148 -0
  27. package/src/components/ui/custom/satellite-footer-actions.tsx +350 -0
  28. package/src/components/ui/custom/satellite-language-item.tsx +26 -0
  29. package/src/components/ui/custom/satellite-navigation.tsx +86 -0
  30. package/src/components/ui/custom/satellite-notification-popover.tsx +272 -0
  31. package/src/components/ui/custom/satellite-onboarding-settings-panel.tsx +80 -0
  32. package/src/components/ui/custom/satellite-settings-dialog-shell.tsx +621 -0
  33. package/src/components/ui/custom/satellite-shell-utils.ts +163 -0
  34. package/src/components/ui/custom/satellite-shell.test.tsx +169 -0
  35. package/src/components/ui/custom/satellite-shell.tsx +50 -0
  36. package/src/components/ui/custom/satellite-theme-dropdown-items.tsx +92 -0
  37. package/src/components/ui/custom/satellite-user-menu-items.tsx +190 -0
  38. package/src/components/ui/custom/satellite-user-menu.tsx +93 -0
  39. package/src/components/ui/custom/satellite-workspace-section.tsx +46 -0
  40. package/src/components/ui/custom/settings/keyboard-shortcuts-settings.tsx +16 -0
  41. package/src/components/ui/custom/settings-dialog-shell.tsx +21 -600
  42. package/src/components/ui/custom/sidebar-context.tsx +5 -14
  43. package/src/components/ui/custom/sidebar-footer-actions.tsx +19 -322
  44. package/src/components/ui/custom/structure.tsx +14 -0
  45. package/src/components/ui/custom/system-language-dropdown-item.tsx +7 -14
  46. package/src/components/ui/custom/theme-dropdown-items.tsx +2 -85
  47. package/src/components/ui/custom/use-satellite-shell.tsx +165 -0
  48. package/src/components/ui/legacy/calendar/agenda-view.tsx +139 -47
  49. package/src/components/ui/legacy/calendar/calendar-content.test.tsx +116 -0
  50. package/src/components/ui/legacy/calendar/calendar-content.tsx +38 -74
  51. package/src/components/ui/legacy/calendar/calendar-event-tone.ts +20 -0
  52. package/src/components/ui/legacy/calendar/calendar-meeting-link.test.ts +27 -0
  53. package/src/components/ui/legacy/calendar/calendar-meeting-link.ts +34 -0
  54. package/src/components/ui/legacy/calendar/calendar-period.ts +28 -0
  55. package/src/components/ui/legacy/calendar/calendar-shortcuts.test.tsx +107 -0
  56. package/src/components/ui/legacy/calendar/calendar-views.test.tsx +169 -0
  57. package/src/components/ui/legacy/calendar/event-modal-header.tsx +52 -0
  58. package/src/components/ui/legacy/calendar/event-modal.tsx +107 -156
  59. package/src/components/ui/legacy/calendar/month-calendar.tsx +242 -933
  60. package/src/components/ui/legacy/calendar/save-calendar-event-drafts.test.ts +25 -0
  61. package/src/components/ui/legacy/calendar/save-calendar-event-drafts.ts +32 -0
  62. package/src/components/ui/legacy/calendar/smart-calendar.tsx +3 -0
  63. package/src/components/ui/legacy/calendar/use-calendar-view-shortcuts.ts +54 -0
  64. package/src/components/ui/legacy/calendar/use-event-draft-session.test.tsx +59 -0
  65. package/src/components/ui/legacy/calendar/use-event-draft-session.ts +20 -0
  66. package/src/components/ui/legacy/calendar/year-calendar.tsx +34 -16
  67. package/src/components/ui/pwa-status.test.tsx +53 -0
  68. package/src/components/ui/pwa-status.tsx +113 -0
  69. package/src/components/ui/report-problem-dialog-content.tsx +350 -0
  70. package/src/components/ui/report-problem-dialog.tsx +6 -975
  71. package/src/components/ui/report-problem-model.ts +133 -0
  72. package/src/components/ui/report-problem-mutation.ts +122 -0
  73. package/src/components/ui/save-notification.test.tsx +36 -0
  74. package/src/components/ui/save-notification.tsx +17 -0
  75. package/src/components/ui/use-report-problem.ts +488 -0
  76. package/src/declarations.d.ts +2 -0
  77. package/src/hooks/__tests__/use-calendar-readonly.test.tsx +46 -4
  78. package/src/hooks/__tests__/use-calendar-sync.test.tsx +24 -0
  79. package/src/hooks/calendar-date-utils.ts +11 -0
  80. package/src/hooks/calendar-event-lookup.test.ts +77 -0
  81. package/src/hooks/calendar-event-lookup.ts +47 -0
  82. package/src/hooks/calendar-range-cache.ts +52 -0
  83. package/src/hooks/pwa-install-prompt.ts +44 -0
  84. package/src/hooks/use-calendar-sync.tsx +23 -100
  85. package/src/hooks/use-calendar.tsx +21 -77
  86. package/src/hooks/use-notifications.ts +9 -24
  87. package/src/hooks/use-open-initial-calendar-event.ts +27 -0
  88. package/src/hooks/use-settings-dialog-shortcut.test.tsx +41 -0
  89. package/src/hooks/use-settings-dialog-shortcut.ts +12 -14
  90. package/src/hooks/use-workspace-presence.ts +0 -18
  91. package/src/lib/tasks-app-url.test.ts +25 -0
  92. package/src/lib/tasks-app-url.ts +8 -0
@@ -0,0 +1,93 @@
1
+ 'use client';
2
+
3
+ import { User } from '@tuturuuu/icons';
4
+ import { cn } from '@tuturuuu/utils/format';
5
+ import { getInitials } from '@tuturuuu/utils/name-helper';
6
+ import type { ReactNode } from 'react';
7
+ import { Avatar, AvatarFallback, AvatarImage } from '../avatar';
8
+ import {
9
+ DropdownMenu,
10
+ DropdownMenuContent,
11
+ DropdownMenuLabel,
12
+ DropdownMenuSeparator,
13
+ DropdownMenuTrigger,
14
+ } from '../dropdown-menu';
15
+ import { AnimatedSlotText } from './animated-slot-text';
16
+
17
+ /** Shared profile trigger and menu frame; adapters supply account services and preferences. */
18
+ export function SatelliteUserMenu({
19
+ name,
20
+ email,
21
+ avatarUrl,
22
+ secondaryLabel,
23
+ hideMetadata = false,
24
+ online = false,
25
+ label,
26
+ loading = false,
27
+ children,
28
+ }: {
29
+ name: string;
30
+ email?: string | null;
31
+ avatarUrl?: string | null;
32
+ secondaryLabel?: string;
33
+ hideMetadata?: boolean;
34
+ online?: boolean;
35
+ label?: string;
36
+ loading?: boolean;
37
+ children: ReactNode;
38
+ }) {
39
+ return (
40
+ <DropdownMenu modal={false}>
41
+ <DropdownMenuTrigger asChild>
42
+ <button
43
+ type="button"
44
+ aria-label={label}
45
+ aria-busy={loading || undefined}
46
+ disabled={loading}
47
+ className={cn(
48
+ 'flex h-10 w-full gap-2 rounded-md p-1 text-start transition',
49
+ hideMetadata
50
+ ? 'items-center justify-center'
51
+ : 'items-center justify-start hover:bg-foreground/5'
52
+ )}
53
+ >
54
+ <Avatar className="relative h-8 w-8 cursor-pointer overflow-visible font-semibold">
55
+ <AvatarImage
56
+ src={avatarUrl ?? undefined}
57
+ className="aspect-square overflow-clip rounded-lg object-cover"
58
+ />
59
+ <AvatarFallback className="rounded-lg font-semibold">
60
+ {name ? getInitials(name) : <User className="h-5 w-5" />}
61
+ </AvatarFallback>
62
+ {online && (
63
+ <div className="pointer-events-none absolute right-0 bottom-0 z-20 size-2.5 rounded-full bg-dynamic-green ring-2 ring-background" />
64
+ )}
65
+ </Avatar>
66
+ {!hideMetadata && (
67
+ <div className="flex w-full min-w-0 flex-col items-start justify-center">
68
+ <div className="line-clamp-1 break-all font-semibold text-sm">
69
+ {name}
70
+ </div>
71
+ <AnimatedSlotText
72
+ className="text-xs opacity-70"
73
+ text={secondaryLabel ?? email ?? ''}
74
+ />
75
+ </div>
76
+ )}
77
+ </button>
78
+ </DropdownMenuTrigger>
79
+ <DropdownMenuContent className="w-56" side="right" align="end" forceMount>
80
+ <DropdownMenuLabel className="font-normal">
81
+ <div className="flex flex-col">
82
+ <span className="line-clamp-1 break-all font-medium text-sm">
83
+ {name}
84
+ </span>
85
+ <p className="line-clamp-1 break-all text-xs opacity-70">{email}</p>
86
+ </div>
87
+ </DropdownMenuLabel>
88
+ <DropdownMenuSeparator />
89
+ {children}
90
+ </DropdownMenuContent>
91
+ </DropdownMenu>
92
+ );
93
+ }
@@ -0,0 +1,46 @@
1
+ import { WorkspaceSelectRevealProvider } from '@tuturuuu/ui/custom/workspace-select-reveal';
2
+ import { cn } from '@tuturuuu/utils/format';
3
+ import type { ReactNode } from 'react';
4
+
5
+ interface SidebarWorkspaceSelectSectionProps {
6
+ children?: ReactNode;
7
+ visible: boolean;
8
+ }
9
+
10
+ /**
11
+ * Keeps the workspace selector in the sidebar flow while animating its height.
12
+ * The closed state intentionally collapses to zero so navigation keeps the
13
+ * same top gap in apps that do not expose a workspace selector at all.
14
+ */
15
+ export function SidebarWorkspaceSelectSection({
16
+ children,
17
+ visible,
18
+ }: SidebarWorkspaceSelectSectionProps) {
19
+ return (
20
+ <WorkspaceSelectRevealProvider revealed={visible}>
21
+ <div
22
+ aria-hidden={!visible}
23
+ className={cn(
24
+ 'grid shrink-0 overflow-hidden px-2 transition-[grid-template-rows,opacity,border-color,padding] duration-200 ease-out',
25
+ visible
26
+ ? 'grid-rows-[1fr] border-b pb-2 opacity-100'
27
+ : 'pointer-events-none grid-rows-[0fr] border-transparent pb-0 opacity-0'
28
+ )}
29
+ data-sidebar-workspace-select
30
+ data-state={visible ? 'open' : 'closed'}
31
+ id="sidebar-workspace-selector"
32
+ inert={visible ? undefined : true}
33
+ style={{
34
+ // Satellite source files are outside each app's Tailwind scan root.
35
+ // Keep the critical height transition identical to apps/web even when
36
+ // arbitrary grid utilities are not emitted by a satellite build.
37
+ gridTemplateRows: visible ? '1fr' : '0fr',
38
+ transitionProperty:
39
+ 'grid-template-rows, opacity, border-color, padding',
40
+ }}
41
+ >
42
+ <div className="min-h-0 overflow-hidden">{children}</div>
43
+ </div>
44
+ </WorkspaceSelectRevealProvider>
45
+ );
46
+ }
@@ -56,6 +56,8 @@ export function KeyboardShortcutsSettings() {
56
56
  const { modKey, modKeyAlt } = usePlatform();
57
57
 
58
58
  const globalRows: ShortcutRow[] = [
59
+ { label: t('open_commands'), keys: [[modKey, 'K']] },
60
+ { label: t('open_apps'), keys: [[modKey, 'Shift', 'K']] },
59
61
  {
60
62
  label: t('open_settings'),
61
63
  keys: [[modKey, ',']],
@@ -100,6 +102,20 @@ export function KeyboardShortcutsSettings() {
100
102
  return (
101
103
  <div className="space-y-6">
102
104
  <ShortcutGroup rows={globalRows} title={t('global')} />
105
+ <ShortcutGroup
106
+ title={t('calendar_views')}
107
+ rows={[
108
+ { label: t('calendar_day'), keys: [['D']] },
109
+ { label: t('calendar_four_days'), keys: [['4']] },
110
+ { label: t('calendar_week'), keys: [['W']] },
111
+ { label: t('calendar_month'), keys: [['M']] },
112
+ { label: t('calendar_year'), keys: [['Y']] },
113
+ { label: t('calendar_agenda'), keys: [['A']] },
114
+ ]}
115
+ />
116
+ <p className="text-muted-foreground text-sm">
117
+ {t('page_shortcuts_hint')}
118
+ </p>
103
119
  <ShortcutGroup rows={dialogRows} title={t('settings_dialog')} />
104
120
  </div>
105
121
  );