@activecollab/components 2.0.305 → 2.0.308

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 (59) hide show
  1. package/dist/cjs/components/SelectDate/SelectDate.js +5 -1
  2. package/dist/cjs/components/SelectDate/SelectDate.js.map +1 -1
  3. package/dist/cjs/presentation/shared/FloatingControls.js +32 -0
  4. package/dist/cjs/presentation/shared/FloatingControls.js.map +1 -0
  5. package/dist/cjs/presentation/shared/MainLogo.js +50 -0
  6. package/dist/cjs/presentation/shared/MainLogo.js.map +1 -0
  7. package/dist/cjs/presentation/shared/PresentationShell.js +299 -0
  8. package/dist/cjs/presentation/shared/PresentationShell.js.map +1 -0
  9. package/dist/cjs/presentation/shared/RoundAvatar.js +38 -0
  10. package/dist/cjs/presentation/shared/RoundAvatar.js.map +1 -0
  11. package/dist/cjs/presentation/shared/TaskOptionsMenu.js +148 -0
  12. package/dist/cjs/presentation/shared/TaskOptionsMenu.js.map +1 -0
  13. package/dist/cjs/presentation/shared/headers.js +221 -0
  14. package/dist/cjs/presentation/shared/headers.js.map +1 -0
  15. package/dist/cjs/presentation/shared/index.js +96 -0
  16. package/dist/cjs/presentation/shared/index.js.map +1 -0
  17. package/dist/cjs/presentation/shared/tokens.js +28 -0
  18. package/dist/cjs/presentation/shared/tokens.js.map +1 -0
  19. package/dist/esm/components/SelectDate/SelectDate.d.ts +2 -2
  20. package/dist/esm/components/SelectDate/SelectDate.d.ts.map +1 -1
  21. package/dist/esm/components/SelectDate/SelectDate.js +5 -1
  22. package/dist/esm/components/SelectDate/SelectDate.js.map +1 -1
  23. package/dist/esm/presentation/shared/FloatingControls.d.ts +7 -0
  24. package/dist/esm/presentation/shared/FloatingControls.d.ts.map +1 -0
  25. package/dist/esm/presentation/shared/FloatingControls.js +23 -0
  26. package/dist/esm/presentation/shared/FloatingControls.js.map +1 -0
  27. package/dist/esm/presentation/shared/MainLogo.d.ts +10 -0
  28. package/dist/esm/presentation/shared/MainLogo.d.ts.map +1 -0
  29. package/dist/esm/presentation/shared/MainLogo.js +42 -0
  30. package/dist/esm/presentation/shared/MainLogo.js.map +1 -0
  31. package/dist/esm/presentation/shared/PresentationShell.d.ts +22 -0
  32. package/dist/esm/presentation/shared/PresentationShell.d.ts.map +1 -0
  33. package/dist/esm/presentation/shared/PresentationShell.js +272 -0
  34. package/dist/esm/presentation/shared/PresentationShell.js.map +1 -0
  35. package/dist/esm/presentation/shared/RoundAvatar.d.ts +13 -0
  36. package/dist/esm/presentation/shared/RoundAvatar.d.ts.map +1 -0
  37. package/dist/esm/presentation/shared/RoundAvatar.js +26 -0
  38. package/dist/esm/presentation/shared/RoundAvatar.js.map +1 -0
  39. package/dist/esm/presentation/shared/TaskOptionsMenu.d.ts +22 -0
  40. package/dist/esm/presentation/shared/TaskOptionsMenu.d.ts.map +1 -0
  41. package/dist/esm/presentation/shared/TaskOptionsMenu.js +119 -0
  42. package/dist/esm/presentation/shared/TaskOptionsMenu.js.map +1 -0
  43. package/dist/esm/presentation/shared/headers.d.ts +28 -0
  44. package/dist/esm/presentation/shared/headers.d.ts.map +1 -0
  45. package/dist/esm/presentation/shared/headers.js +194 -0
  46. package/dist/esm/presentation/shared/headers.js.map +1 -0
  47. package/dist/esm/presentation/shared/index.d.ts +17 -0
  48. package/dist/esm/presentation/shared/index.d.ts.map +1 -0
  49. package/dist/esm/presentation/shared/index.js +14 -0
  50. package/dist/esm/presentation/shared/index.js.map +1 -0
  51. package/dist/esm/presentation/shared/tokens.d.ts +21 -0
  52. package/dist/esm/presentation/shared/tokens.d.ts.map +1 -0
  53. package/dist/esm/presentation/shared/tokens.js +22 -0
  54. package/dist/esm/presentation/shared/tokens.js.map +1 -0
  55. package/dist/index.js +5 -1
  56. package/dist/index.js.map +1 -1
  57. package/dist/index.min.js +1 -1
  58. package/dist/index.min.js.map +1 -1
  59. package/package.json +2 -2
@@ -0,0 +1,272 @@
1
+ import React, { useCallback, useEffect, useRef, useState } from "react";
2
+ import styled from "styled-components";
3
+ import { MainLogo } from "./MainLogo";
4
+ import { BREAKPOINT, SM, TRANSITION, XL } from "./tokens";
5
+ import { IconButton } from "../../components/IconButton";
6
+ import { ActivityIcon, CalendarIcon, ClockStopwatchIndicatorIcon, CloseIcon, CollapsIcon, EstimatesIcon, InvoicesIcon, MobileMenuIcon, MyWorkIcon, NotificationBellIcon, PeopleIcon, ProjectsIcon, ReportTimeIcon, ReportsIcon, RocketIcon, SearchIcon } from "../../components/Icons";
7
+ import { Modal } from "../../components/Modal";
8
+ import { Paper } from "../../components/Paper";
9
+ import { Tooltip } from "../../components/Tooltip";
10
+ import { Body2, Caption1 } from "../../components/Typography";
11
+ import { useResizeObserver } from "../../utils";
12
+ const MENU_ITEMS = [{
13
+ icon: RocketIcon,
14
+ text: "Getting Started"
15
+ }, {
16
+ icon: ProjectsIcon,
17
+ text: "Projects",
18
+ active: true
19
+ }, {
20
+ icon: MyWorkIcon,
21
+ text: "My Work"
22
+ }, {
23
+ icon: ActivityIcon,
24
+ text: "Activity"
25
+ }, {
26
+ icon: CalendarIcon,
27
+ text: "Calendar"
28
+ }, {
29
+ icon: PeopleIcon,
30
+ text: "People"
31
+ }, {
32
+ icon: ReportTimeIcon,
33
+ text: "Time"
34
+ }, {
35
+ icon: ReportsIcon,
36
+ text: "Reports"
37
+ }, {
38
+ icon: InvoicesIcon,
39
+ text: "Invoices"
40
+ }, {
41
+ icon: EstimatesIcon,
42
+ text: "Estimates"
43
+ }];
44
+
45
+ /* ------------------------------------------------------------------ */
46
+ /* Layout shell (mirrors Layout.js) */
47
+ /* ------------------------------------------------------------------ */
48
+
49
+ const StyledLayout = styled.div.withConfig({
50
+ displayName: "PresentationShell__StyledLayout",
51
+ componentId: "sc-12j90o1-0"
52
+ })(["height:100vh;display:flex;flex-direction:column;background-color:var(--body-bg-main);"]);
53
+ const StyledContentRow = styled.div.withConfig({
54
+ displayName: "PresentationShell__StyledContentRow",
55
+ componentId: "sc-12j90o1-1"
56
+ })(["position:relative;display:flex;flex-direction:row-reverse;flex:1 1 0%;flex-grow:1;overflow-y:auto;"]);
57
+ const StyledRightWindow = styled.div.withConfig({
58
+ displayName: "PresentationShell__StyledRightWindow",
59
+ componentId: "sc-12j90o1-2"
60
+ })(["position:relative;display:flex;flex-direction:column;flex:1 1 0%;flex-grow:1;width:100%;height:100%;overflow-y:auto;padding:0 16px;@media (min-width:", "){padding-right:32px;}"], SM);
61
+
62
+ /* ------------------------------------------------------------------ */
63
+ /* Main menu (mirrors MainMenu.js + MainMenu.less) */
64
+ /* ------------------------------------------------------------------ */
65
+
66
+ const StyledMainMenu = styled.div.withConfig({
67
+ displayName: "PresentationShell__StyledMainMenu",
68
+ componentId: "sc-12j90o1-3"
69
+ })(["position:relative;z-index:1;display:none;flex-direction:column;height:100%;margin-right:4px;flex-shrink:0;width:240px;transition:width ", ";@media (min-width:", "){display:flex;}&.collapsed{width:72px;}.menu-item-text,.menu-section,#logotype{transition:all ", ";}&.collapsed .menu-item-text{opacity:0;visibility:hidden;width:0;margin-left:0;}&.collapsed .menu-section{transform:scaleY(0);opacity:0;max-height:0;margin-bottom:0;}&.collapsed #logotype{transform:translateX(-5%);opacity:0;}&.collapsed .collapse-expand-menu svg{transform:rotate(180deg);}&:not(.mobile){@media (max-width:1279.98px){width:72px;.menu-item-text{opacity:0;visibility:hidden;width:0;margin-left:0;}.menu-section{transform:scaleY(0);opacity:0;max-height:0;margin-bottom:0;}#logotype{transform:translateX(-5%);opacity:0;}}}&.mobile{display:flex;position:absolute;left:0;top:0;width:240px;background-color:var(--page-paper-main);}"], TRANSITION, SM, TRANSITION);
70
+ const StyledMenuHeader = styled.div.withConfig({
71
+ displayName: "PresentationShell__StyledMenuHeader",
72
+ componentId: "sc-12j90o1-4"
73
+ })(["position:relative;height:68px;display:flex;align-items:center;flex-shrink:0;overflow:hidden;.main-logo{position:absolute;left:20px;color:var(--color-secondary);path{fill:var(--color-secondary);}}.collapse-expand-menu{position:absolute;right:4px;display:none;@media (min-width:", "){display:flex;}}"], XL);
74
+ const StyledMenuScroll = styled.div.withConfig({
75
+ displayName: "PresentationShell__StyledMenuScroll",
76
+ componentId: "sc-12j90o1-5"
77
+ })(["display:flex;flex-direction:column;flex-grow:1;min-height:0;margin:12px 0;overflow-y:auto;overflow-x:hidden;"]);
78
+ const StyledMenuSection = styled.div.withConfig({
79
+ displayName: "PresentationShell__StyledMenuSection",
80
+ componentId: "sc-12j90o1-6"
81
+ })(["display:flex;align-items:center;margin:0 12px 8px;padding:0 4px 0 12px;"]);
82
+ const StyledMenuItem = styled.a.withConfig({
83
+ displayName: "PresentationShell__StyledMenuItem",
84
+ componentId: "sc-12j90o1-7"
85
+ })(["display:flex;align-items:center;height:40px;padding:0 4px 0 12px;margin:0 12px 2px;border-radius:8px;cursor:pointer;text-decoration:none;svg{flex-shrink:0;fill:var(--color-theme-700);opacity:0.7;}.menu-item-text{margin-left:12px;min-width:0;overflow:hidden;text-overflow:ellipsis;}&:hover{transition:all ", ";background-color:var(--color-theme-300);svg{fill:var(--color-theme-900);opacity:1;}.menu-item-text{color:var(--color-theme-900);}}&.active{background-color:var(--color-secondary-200);svg{fill:var(--color-secondary);opacity:1;}.menu-item-text{color:var(--color-secondary);}}"], TRANSITION);
86
+ const StyledMobileMenuClose = styled(IconButton).withConfig({
87
+ displayName: "PresentationShell__StyledMobileMenuClose",
88
+ componentId: "sc-12j90o1-8"
89
+ })(["position:absolute;right:16px;"]);
90
+
91
+ /* ------------------------------------------------------------------ */
92
+ /* Top bars */
93
+ /* ------------------------------------------------------------------ */
94
+
95
+ const StyledMobileMenuHeader = styled.div.withConfig({
96
+ displayName: "PresentationShell__StyledMobileMenuHeader",
97
+ componentId: "sc-12j90o1-9"
98
+ })(["display:flex;align-items:center;justify-content:space-between;padding:8px 16px;background-color:var(--color-primary);z-index:50;@media (min-width:", "){display:none;}.mobile-menu-icon{fill:var(--color-theme-300);}"], SM);
99
+ const StyledIconRow = styled.div.withConfig({
100
+ displayName: "PresentationShell__StyledIconRow",
101
+ componentId: "sc-12j90o1-10"
102
+ })(["display:flex;align-items:center;"]);
103
+ const StyledTopRightControls = styled.div.withConfig({
104
+ displayName: "PresentationShell__StyledTopRightControls",
105
+ componentId: "sc-12j90o1-11"
106
+ })(["position:absolute;top:0;right:0;display:none;align-items:center;justify-content:flex-end;padding:12px 32px 12px 0;@media (min-width:", "){display:flex;}"], SM);
107
+ const StyledHeaderAvatar = styled.div.withConfig({
108
+ displayName: "PresentationShell__StyledHeaderAvatar",
109
+ componentId: "sc-12j90o1-12"
110
+ })(["width:28px;height:28px;border-radius:50%;background-color:var(--color-secondary);color:var(--only-white);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600;margin:0 8px;flex-shrink:0;cursor:pointer;.neon &{color:var(--page-paper-main);}"]);
111
+
112
+ /* ------------------------------------------------------------------ */
113
+ /* Page region (mirrors Page.jsx / PageBody.jsx) */
114
+ /* ------------------------------------------------------------------ */
115
+
116
+ const StyledPage = styled.div.withConfig({
117
+ displayName: "PresentationShell__StyledPage",
118
+ componentId: "sc-12j90o1-13"
119
+ })(["display:flex;flex-direction:column;flex-grow:1;"]);
120
+ const StyledPageBody = styled.div.withConfig({
121
+ displayName: "PresentationShell__StyledPageBody",
122
+ componentId: "sc-12j90o1-14"
123
+ })(["display:flex;flex-direction:column;flex-grow:1;margin-bottom:32px;min-height:0;"]);
124
+
125
+ /** The paper card that holds page content (used by list view & empty pages). */
126
+ export const StyledPagePaper = styled(Paper).withConfig({
127
+ displayName: "PresentationShell__StyledPagePaper",
128
+ componentId: "sc-12j90o1-15"
129
+ })(["flex-grow:1;width:100%;"]);
130
+
131
+ /* ------------------------------------------------------------------ */
132
+ /* Mocked layout building blocks */
133
+ /* ------------------------------------------------------------------ */
134
+
135
+ const MenuItemsMock = _ref => {
136
+ let _ref$mobile = _ref.mobile,
137
+ mobile = _ref$mobile === void 0 ? false : _ref$mobile;
138
+ return /*#__PURE__*/React.createElement(StyledMenuScroll, null, /*#__PURE__*/React.createElement(StyledMenuSection, {
139
+ className: "menu-section"
140
+ }, /*#__PURE__*/React.createElement(Caption1, {
141
+ weight: "bold",
142
+ color: "tertiary"
143
+ }, "MENU")), MENU_ITEMS.map(_ref2 => {
144
+ let Icon = _ref2.icon,
145
+ text = _ref2.text,
146
+ active = _ref2.active;
147
+ return /*#__PURE__*/React.createElement(Tooltip, {
148
+ key: text,
149
+ title: text,
150
+ placement: "right",
151
+ disable: mobile
152
+ }, /*#__PURE__*/React.createElement(StyledMenuItem, {
153
+ className: active ? "active" : undefined
154
+ }, /*#__PURE__*/React.createElement(Icon, null), /*#__PURE__*/React.createElement(Body2, {
155
+ weight: "medium",
156
+ color: "secondary",
157
+ whitespace: "no-wrap",
158
+ className: "menu-item-text"
159
+ }, text)));
160
+ }));
161
+ };
162
+ const MainMenuMock = _ref3 => {
163
+ let collapsed = _ref3.collapsed,
164
+ onToggleCollapsed = _ref3.onToggleCollapsed;
165
+ return /*#__PURE__*/React.createElement(StyledMainMenu, {
166
+ className: collapsed ? "collapsed" : undefined,
167
+ "data-testid": "main-menu"
168
+ }, /*#__PURE__*/React.createElement(StyledMenuHeader, null, /*#__PURE__*/React.createElement("a", {
169
+ className: "main-logo"
170
+ }, /*#__PURE__*/React.createElement(MainLogo, null)), /*#__PURE__*/React.createElement("div", {
171
+ className: "collapse-expand-menu"
172
+ }, /*#__PURE__*/React.createElement(IconButton, {
173
+ variant: "text gray",
174
+ size: "small",
175
+ onClick: onToggleCollapsed
176
+ }, /*#__PURE__*/React.createElement(CollapsIcon, null)))), /*#__PURE__*/React.createElement(MenuItemsMock, null));
177
+ };
178
+ const MainMenuMobileMock = _ref4 => {
179
+ let open = _ref4.open,
180
+ close = _ref4.close;
181
+ return open ? /*#__PURE__*/React.createElement(Modal, {
182
+ open: open,
183
+ onClose: close
184
+ }, /*#__PURE__*/React.createElement(StyledMainMenu, {
185
+ className: "mobile",
186
+ "data-testid": "main-menu-mobile"
187
+ }, /*#__PURE__*/React.createElement(StyledMenuHeader, null, /*#__PURE__*/React.createElement("a", {
188
+ className: "main-logo"
189
+ }, /*#__PURE__*/React.createElement(MainLogo, null)), /*#__PURE__*/React.createElement(StyledMobileMenuClose, {
190
+ onClick: close,
191
+ variant: "text gray"
192
+ }, /*#__PURE__*/React.createElement(CloseIcon, null))), /*#__PURE__*/React.createElement(MenuItemsMock, {
193
+ mobile: true
194
+ }))) : null;
195
+ };
196
+ const MobileMenuHeaderMock = _ref5 => {
197
+ let onOpenMobileMenu = _ref5.onOpenMobileMenu;
198
+ return /*#__PURE__*/React.createElement(StyledMobileMenuHeader, null, /*#__PURE__*/React.createElement(IconButton, {
199
+ size: "big",
200
+ variant: "circle raised",
201
+ onClick: onOpenMobileMenu
202
+ }, /*#__PURE__*/React.createElement(MobileMenuIcon, {
203
+ className: "mobile-menu-icon"
204
+ })), /*#__PURE__*/React.createElement(StyledIconRow, null, /*#__PURE__*/React.createElement(IconButton, {
205
+ variant: "text gray"
206
+ }, /*#__PURE__*/React.createElement(SearchIcon, null)), /*#__PURE__*/React.createElement(StyledHeaderAvatar, null, "JS"), /*#__PURE__*/React.createElement(IconButton, {
207
+ variant: "text gray"
208
+ }, /*#__PURE__*/React.createElement(NotificationBellIcon, null))));
209
+ };
210
+ const TopRightControlsMock = () => /*#__PURE__*/React.createElement(StyledTopRightControls, null, /*#__PURE__*/React.createElement(IconButton, {
211
+ variant: "text gray"
212
+ }, /*#__PURE__*/React.createElement(ClockStopwatchIndicatorIcon, null)), /*#__PURE__*/React.createElement(IconButton, {
213
+ variant: "text gray"
214
+ }, /*#__PURE__*/React.createElement(SearchIcon, null)), /*#__PURE__*/React.createElement(StyledHeaderAvatar, null, "JS"), /*#__PURE__*/React.createElement(IconButton, {
215
+ variant: "text gray"
216
+ }, /*#__PURE__*/React.createElement(NotificationBellIcon, null)));
217
+
218
+ /* ------------------------------------------------------------------ */
219
+ /* PresentationShell */
220
+ /* ------------------------------------------------------------------ */
221
+
222
+ /**
223
+ * The full application shell shared by every presentation mock-up: the main
224
+ * menu on the left (auto-collapsing below 1280px, modal below 640px), the
225
+ * top-right controls and the scrollable page area. Pass the page header via
226
+ * `header` and the body via `children`.
227
+ */
228
+ export const PresentationShell = _ref6 => {
229
+ let header = _ref6.header,
230
+ children = _ref6.children,
231
+ floating = _ref6.floating;
232
+ const _useState = useState(false),
233
+ mobileMenuOpen = _useState[0],
234
+ setMobileMenuOpen = _useState[1];
235
+ const _useState2 = useState(false),
236
+ collapsed = _useState2[0],
237
+ setCollapsed = _useState2[1];
238
+ const _useState3 = useState(),
239
+ isMobileView = _useState3[0],
240
+ setIsMobileView = _useState3[1];
241
+ const ref = useRef(null);
242
+ const dimensions = useResizeObserver(ref);
243
+ const width = dimensions == null ? void 0 : dimensions.width;
244
+ useEffect(() => {
245
+ if (width) {
246
+ if (width < BREAKPOINT) {
247
+ setIsMobileView(true);
248
+ } else {
249
+ setIsMobileView(false);
250
+ setMobileMenuOpen(false);
251
+ }
252
+ }
253
+ }, [width]);
254
+ const handleOpenMobileMenu = useCallback(() => setMobileMenuOpen(true), []);
255
+ const handleCloseMobileMenu = useCallback(() => setMobileMenuOpen(false), []);
256
+ const handleToggleCollapsed = useCallback(() => setCollapsed(prev => !prev), []);
257
+ return /*#__PURE__*/React.createElement(StyledLayout, {
258
+ ref: ref
259
+ }, isMobileView ? /*#__PURE__*/React.createElement(MobileMenuHeaderMock, {
260
+ onOpenMobileMenu: handleOpenMobileMenu
261
+ }) : null, /*#__PURE__*/React.createElement(StyledContentRow, null, /*#__PURE__*/React.createElement(StyledRightWindow, {
262
+ id: "right-window"
263
+ }, /*#__PURE__*/React.createElement(StyledPage, null, header, /*#__PURE__*/React.createElement(StyledPageBody, null, children)), isMobileView === false ? /*#__PURE__*/React.createElement(TopRightControlsMock, null) : null), isMobileView ? /*#__PURE__*/React.createElement(MainMenuMobileMock, {
264
+ open: mobileMenuOpen,
265
+ close: handleCloseMobileMenu
266
+ }) : /*#__PURE__*/React.createElement(MainMenuMock, {
267
+ collapsed: collapsed,
268
+ onToggleCollapsed: handleToggleCollapsed
269
+ })), floating);
270
+ };
271
+ PresentationShell.displayName = "PresentationShell";
272
+ //# sourceMappingURL=PresentationShell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PresentationShell.js","names":["React","useCallback","useEffect","useRef","useState","styled","MainLogo","BREAKPOINT","SM","TRANSITION","XL","IconButton","ActivityIcon","CalendarIcon","ClockStopwatchIndicatorIcon","CloseIcon","CollapsIcon","EstimatesIcon","InvoicesIcon","MobileMenuIcon","MyWorkIcon","NotificationBellIcon","PeopleIcon","ProjectsIcon","ReportTimeIcon","ReportsIcon","RocketIcon","SearchIcon","Modal","Paper","Tooltip","Body2","Caption1","useResizeObserver","MENU_ITEMS","icon","text","active","StyledLayout","div","withConfig","displayName","componentId","StyledContentRow","StyledRightWindow","StyledMainMenu","StyledMenuHeader","StyledMenuScroll","StyledMenuSection","StyledMenuItem","a","StyledMobileMenuClose","StyledMobileMenuHeader","StyledIconRow","StyledTopRightControls","StyledHeaderAvatar","StyledPage","StyledPageBody","StyledPagePaper","MenuItemsMock","_ref","_ref$mobile","mobile","createElement","className","weight","color","map","_ref2","Icon","key","title","placement","disable","undefined","whitespace","MainMenuMock","_ref3","collapsed","onToggleCollapsed","variant","size","onClick","MainMenuMobileMock","_ref4","open","close","onClose","MobileMenuHeaderMock","_ref5","onOpenMobileMenu","TopRightControlsMock","PresentationShell","_ref6","header","children","floating","_useState","mobileMenuOpen","setMobileMenuOpen","_useState2","setCollapsed","_useState3","isMobileView","setIsMobileView","ref","dimensions","width","handleOpenMobileMenu","handleCloseMobileMenu","handleToggleCollapsed","prev","id"],"sources":["../../../../src/presentation/shared/PresentationShell.tsx"],"sourcesContent":["import React, {\n ReactElement,\n ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\n\nimport styled from \"styled-components\";\n\nimport { MainLogo } from \"./MainLogo\";\nimport { BREAKPOINT, SM, TRANSITION, XL } from \"./tokens\";\nimport { IconButton } from \"../../components/IconButton\";\nimport {\n ActivityIcon,\n CalendarIcon,\n ClockStopwatchIndicatorIcon,\n CloseIcon,\n CollapsIcon,\n EstimatesIcon,\n InvoicesIcon,\n MobileMenuIcon,\n MyWorkIcon,\n NotificationBellIcon,\n PeopleIcon,\n ProjectsIcon,\n ReportTimeIcon,\n ReportsIcon,\n RocketIcon,\n SearchIcon,\n} from \"../../components/Icons\";\nimport { Modal } from \"../../components/Modal\";\nimport { Paper } from \"../../components/Paper\";\nimport { Tooltip } from \"../../components/Tooltip\";\nimport { Body2, Caption1 } from \"../../components/Typography\";\nimport { useResizeObserver } from \"../../utils\";\n\nconst MENU_ITEMS: {\n icon: React.FC<React.SVGProps<SVGSVGElement>>;\n text: string;\n active?: boolean;\n}[] = [\n { icon: RocketIcon, text: \"Getting Started\" },\n { icon: ProjectsIcon, text: \"Projects\", active: true },\n { icon: MyWorkIcon, text: \"My Work\" },\n { icon: ActivityIcon, text: \"Activity\" },\n { icon: CalendarIcon, text: \"Calendar\" },\n { icon: PeopleIcon, text: \"People\" },\n { icon: ReportTimeIcon, text: \"Time\" },\n { icon: ReportsIcon, text: \"Reports\" },\n { icon: InvoicesIcon, text: \"Invoices\" },\n { icon: EstimatesIcon, text: \"Estimates\" },\n];\n\n/* ------------------------------------------------------------------ */\n/* Layout shell (mirrors Layout.js) */\n/* ------------------------------------------------------------------ */\n\nconst StyledLayout = styled.div`\n height: 100vh;\n display: flex;\n flex-direction: column;\n background-color: var(--body-bg-main);\n`;\n\nconst StyledContentRow = styled.div`\n position: relative;\n display: flex;\n flex-direction: row-reverse;\n flex: 1 1 0%;\n flex-grow: 1;\n overflow-y: auto;\n`;\n\nconst StyledRightWindow = styled.div`\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1 1 0%;\n flex-grow: 1;\n width: 100%;\n height: 100%;\n overflow-y: auto;\n padding: 0 16px;\n\n @media (min-width: ${SM}) {\n padding-right: 32px;\n }\n`;\n\n/* ------------------------------------------------------------------ */\n/* Main menu (mirrors MainMenu.js + MainMenu.less) */\n/* ------------------------------------------------------------------ */\n\nconst StyledMainMenu = styled.div`\n position: relative;\n z-index: 1;\n display: none;\n flex-direction: column;\n height: 100%;\n margin-right: 4px;\n flex-shrink: 0;\n width: 240px;\n transition: width ${TRANSITION};\n\n @media (min-width: ${SM}) {\n display: flex;\n }\n\n &.collapsed {\n width: 72px;\n }\n\n .menu-item-text,\n .menu-section,\n #logotype {\n transition: all ${TRANSITION};\n }\n\n &.collapsed .menu-item-text {\n opacity: 0;\n visibility: hidden;\n width: 0;\n margin-left: 0;\n }\n\n &.collapsed .menu-section {\n transform: scaleY(0);\n opacity: 0;\n max-height: 0;\n margin-bottom: 0;\n }\n\n &.collapsed #logotype {\n transform: translateX(-5%);\n opacity: 0;\n }\n\n &.collapsed .collapse-expand-menu svg {\n transform: rotate(180deg);\n }\n\n &:not(.mobile) {\n @media (max-width: 1279.98px) {\n width: 72px;\n\n .menu-item-text {\n opacity: 0;\n visibility: hidden;\n width: 0;\n margin-left: 0;\n }\n\n .menu-section {\n transform: scaleY(0);\n opacity: 0;\n max-height: 0;\n margin-bottom: 0;\n }\n\n #logotype {\n transform: translateX(-5%);\n opacity: 0;\n }\n }\n }\n\n &.mobile {\n display: flex;\n position: absolute;\n left: 0;\n top: 0;\n width: 240px;\n background-color: var(--page-paper-main);\n }\n`;\n\nconst StyledMenuHeader = styled.div`\n position: relative;\n height: 68px;\n display: flex;\n align-items: center;\n flex-shrink: 0;\n overflow: hidden;\n\n .main-logo {\n position: absolute;\n left: 20px;\n color: var(--color-secondary);\n\n path {\n fill: var(--color-secondary);\n }\n }\n\n .collapse-expand-menu {\n position: absolute;\n right: 4px;\n display: none;\n\n @media (min-width: ${XL}) {\n display: flex;\n }\n }\n`;\n\nconst StyledMenuScroll = styled.div`\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n min-height: 0;\n margin: 12px 0;\n overflow-y: auto;\n overflow-x: hidden;\n`;\n\nconst StyledMenuSection = styled.div`\n display: flex;\n align-items: center;\n margin: 0 12px 8px;\n padding: 0 4px 0 12px;\n`;\n\nconst StyledMenuItem = styled.a`\n display: flex;\n align-items: center;\n height: 40px;\n padding: 0 4px 0 12px;\n margin: 0 12px 2px;\n border-radius: 8px;\n cursor: pointer;\n text-decoration: none;\n\n svg {\n flex-shrink: 0;\n fill: var(--color-theme-700);\n opacity: 0.7;\n }\n\n .menu-item-text {\n margin-left: 12px;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n &:hover {\n transition: all ${TRANSITION};\n background-color: var(--color-theme-300);\n\n svg {\n fill: var(--color-theme-900);\n opacity: 1;\n }\n\n .menu-item-text {\n color: var(--color-theme-900);\n }\n }\n\n &.active {\n background-color: var(--color-secondary-200);\n\n svg {\n fill: var(--color-secondary);\n opacity: 1;\n }\n\n .menu-item-text {\n color: var(--color-secondary);\n }\n }\n`;\n\nconst StyledMobileMenuClose = styled(IconButton)`\n position: absolute;\n right: 16px;\n`;\n\n/* ------------------------------------------------------------------ */\n/* Top bars */\n/* ------------------------------------------------------------------ */\n\nconst StyledMobileMenuHeader = styled.div`\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 16px;\n background-color: var(--color-primary);\n z-index: 50;\n\n @media (min-width: ${SM}) {\n display: none;\n }\n\n .mobile-menu-icon {\n fill: var(--color-theme-300);\n }\n`;\n\nconst StyledIconRow = styled.div`\n display: flex;\n align-items: center;\n`;\n\nconst StyledTopRightControls = styled.div`\n position: absolute;\n top: 0;\n right: 0;\n display: none;\n align-items: center;\n justify-content: flex-end;\n padding: 12px 32px 12px 0;\n\n @media (min-width: ${SM}) {\n display: flex;\n }\n`;\n\nconst StyledHeaderAvatar = styled.div`\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background-color: var(--color-secondary);\n color: var(--only-white);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n font-weight: 600;\n margin: 0 8px;\n flex-shrink: 0;\n cursor: pointer;\n\n /* neon theme: use paper colour for the initials */\n .neon & {\n color: var(--page-paper-main);\n }\n`;\n\n/* ------------------------------------------------------------------ */\n/* Page region (mirrors Page.jsx / PageBody.jsx) */\n/* ------------------------------------------------------------------ */\n\nconst StyledPage = styled.div`\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n`;\n\nconst StyledPageBody = styled.div`\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n margin-bottom: 32px;\n min-height: 0;\n`;\n\n/** The paper card that holds page content (used by list view & empty pages). */\nexport const StyledPagePaper = styled(Paper)`\n flex-grow: 1;\n width: 100%;\n`;\n\n/* ------------------------------------------------------------------ */\n/* Mocked layout building blocks */\n/* ------------------------------------------------------------------ */\n\ninterface MenuItemsProps {\n mobile?: boolean;\n}\n\nconst MenuItemsMock = ({ mobile = false }: MenuItemsProps): ReactElement => (\n <StyledMenuScroll>\n <StyledMenuSection className=\"menu-section\">\n <Caption1 weight=\"bold\" color=\"tertiary\">\n MENU\n </Caption1>\n </StyledMenuSection>\n {MENU_ITEMS.map(({ icon: Icon, text, active }) => (\n <Tooltip key={text} title={text} placement=\"right\" disable={mobile}>\n <StyledMenuItem className={active ? \"active\" : undefined}>\n <Icon />\n <Body2\n weight=\"medium\"\n color=\"secondary\"\n whitespace=\"no-wrap\"\n className=\"menu-item-text\"\n >\n {text}\n </Body2>\n </StyledMenuItem>\n </Tooltip>\n ))}\n </StyledMenuScroll>\n);\n\ninterface MainMenuMockProps {\n collapsed: boolean;\n onToggleCollapsed: () => void;\n}\n\nconst MainMenuMock = ({\n collapsed,\n onToggleCollapsed,\n}: MainMenuMockProps): ReactElement => (\n <StyledMainMenu\n className={collapsed ? \"collapsed\" : undefined}\n data-testid=\"main-menu\"\n >\n <StyledMenuHeader>\n <a className=\"main-logo\">\n <MainLogo />\n </a>\n <div className=\"collapse-expand-menu\">\n <IconButton\n variant=\"text gray\"\n size=\"small\"\n onClick={onToggleCollapsed}\n >\n <CollapsIcon />\n </IconButton>\n </div>\n </StyledMenuHeader>\n <MenuItemsMock />\n </StyledMainMenu>\n);\n\ninterface MainMenuMobileMockProps {\n open: boolean;\n close: () => void;\n}\n\nconst MainMenuMobileMock = ({\n open,\n close,\n}: MainMenuMobileMockProps): ReactElement | null =>\n open ? (\n <Modal open={open} onClose={close}>\n <StyledMainMenu className=\"mobile\" data-testid=\"main-menu-mobile\">\n <StyledMenuHeader>\n <a className=\"main-logo\">\n <MainLogo />\n </a>\n <StyledMobileMenuClose onClick={close} variant=\"text gray\">\n <CloseIcon />\n </StyledMobileMenuClose>\n </StyledMenuHeader>\n <MenuItemsMock mobile />\n </StyledMainMenu>\n </Modal>\n ) : null;\n\ninterface MobileMenuHeaderMockProps {\n onOpenMobileMenu: () => void;\n}\n\nconst MobileMenuHeaderMock = ({\n onOpenMobileMenu,\n}: MobileMenuHeaderMockProps): ReactElement => (\n <StyledMobileMenuHeader>\n <IconButton size=\"big\" variant=\"circle raised\" onClick={onOpenMobileMenu}>\n <MobileMenuIcon className=\"mobile-menu-icon\" />\n </IconButton>\n <StyledIconRow>\n <IconButton variant=\"text gray\">\n <SearchIcon />\n </IconButton>\n <StyledHeaderAvatar>JS</StyledHeaderAvatar>\n <IconButton variant=\"text gray\">\n <NotificationBellIcon />\n </IconButton>\n </StyledIconRow>\n </StyledMobileMenuHeader>\n);\n\nconst TopRightControlsMock = (): ReactElement => (\n <StyledTopRightControls>\n <IconButton variant=\"text gray\">\n <ClockStopwatchIndicatorIcon />\n </IconButton>\n <IconButton variant=\"text gray\">\n <SearchIcon />\n </IconButton>\n <StyledHeaderAvatar>JS</StyledHeaderAvatar>\n <IconButton variant=\"text gray\">\n <NotificationBellIcon />\n </IconButton>\n </StyledTopRightControls>\n);\n\n/* ------------------------------------------------------------------ */\n/* PresentationShell */\n/* ------------------------------------------------------------------ */\n\nexport interface PresentationShellProps {\n /** Page header row (e.g. <ProjectPageHeader /> or <PageHeader title=\"…\" />). */\n header: ReactNode;\n /** Page body content rendered inside the scrollable page area. */\n children: ReactNode;\n /** Optional fixed controls (e.g. <FloatingControls />). */\n floating?: ReactNode;\n}\n\n/**\n * The full application shell shared by every presentation mock-up: the main\n * menu on the left (auto-collapsing below 1280px, modal below 640px), the\n * top-right controls and the scrollable page area. Pass the page header via\n * `header` and the body via `children`.\n */\nexport const PresentationShell = ({\n header,\n children,\n floating,\n}: PresentationShellProps): ReactElement => {\n const [mobileMenuOpen, setMobileMenuOpen] = useState(false);\n const [collapsed, setCollapsed] = useState(false);\n const [isMobileView, setIsMobileView] = useState<boolean>();\n\n const ref = useRef<HTMLDivElement>(null);\n const dimensions = useResizeObserver(ref);\n const width = dimensions?.width;\n\n useEffect(() => {\n if (width) {\n if (width < BREAKPOINT) {\n setIsMobileView(true);\n } else {\n setIsMobileView(false);\n setMobileMenuOpen(false);\n }\n }\n }, [width]);\n\n const handleOpenMobileMenu = useCallback(() => setMobileMenuOpen(true), []);\n const handleCloseMobileMenu = useCallback(() => setMobileMenuOpen(false), []);\n const handleToggleCollapsed = useCallback(\n () => setCollapsed((prev) => !prev),\n []\n );\n\n return (\n <StyledLayout ref={ref}>\n {isMobileView ? (\n <MobileMenuHeaderMock onOpenMobileMenu={handleOpenMobileMenu} />\n ) : null}\n <StyledContentRow>\n <StyledRightWindow id=\"right-window\">\n <StyledPage>\n {header}\n <StyledPageBody>{children}</StyledPageBody>\n </StyledPage>\n {isMobileView === false ? <TopRightControlsMock /> : null}\n </StyledRightWindow>\n {isMobileView ? (\n <MainMenuMobileMock\n open={mobileMenuOpen}\n close={handleCloseMobileMenu}\n />\n ) : (\n <MainMenuMock\n collapsed={collapsed}\n onToggleCollapsed={handleToggleCollapsed}\n />\n )}\n </StyledContentRow>\n {floating}\n </StyledLayout>\n );\n};\n\nPresentationShell.displayName = \"PresentationShell\";\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * A simple round initials avatar used across the presentation mock-ups in
3
+ * place of real user images. `$overlap` makes stacked avatars overlap (task
4
+ * rows / cards), `$bordered` draws the paper-coloured ring that separates
5
+ * overlapping avatars.
6
+ */
7
+ export declare const RoundAvatar: import("styled-components").StyledComponent<"div", any, {
8
+ $bg: string;
9
+ $size?: number;
10
+ $overlap?: boolean;
11
+ $bordered?: boolean;
12
+ }, never>;
13
+ //# sourceMappingURL=RoundAvatar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RoundAvatar.d.ts","sourceRoot":"","sources":["../../../../src/presentation/shared/RoundAvatar.tsx"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,WAAW;SACjB,MAAM;YACH,MAAM;eACH,OAAO;gBACN,OAAO;SA0BpB,CAAC"}
@@ -0,0 +1,26 @@
1
+ import styled from "styled-components";
2
+
3
+ /**
4
+ * A simple round initials avatar used across the presentation mock-ups in
5
+ * place of real user images. `$overlap` makes stacked avatars overlap (task
6
+ * rows / cards), `$bordered` draws the paper-coloured ring that separates
7
+ * overlapping avatars.
8
+ */
9
+ export const RoundAvatar = styled.div.withConfig({
10
+ displayName: "RoundAvatar",
11
+ componentId: "sc-1s5jx6y-0"
12
+ })(["width:", "px;height:", "px;border-radius:50%;background-color:", ";color:#fff;display:flex;align-items:center;justify-content:center;font-size:", "px;font-weight:700;flex-shrink:0;", " &:not(:first-child){margin-left:", ";}"], props => {
13
+ var _props$$size;
14
+ return (_props$$size = props.$size) != null ? _props$$size : 28;
15
+ }, props => {
16
+ var _props$$size2;
17
+ return (_props$$size2 = props.$size) != null ? _props$$size2 : 28;
18
+ }, props => props.$bg, props => {
19
+ var _props$$size3;
20
+ const size = (_props$$size3 = props.$size) != null ? _props$$size3 : 28;
21
+ if (size <= 22) return 9;
22
+ if (size <= 26) return 10;
23
+ return 11;
24
+ }, props => props.$bordered === false ? "" : "border: 2px solid var(--page-paper-main);", props => props.$overlap ? "-8px" : "0");
25
+ RoundAvatar.displayName = "RoundAvatar";
26
+ //# sourceMappingURL=RoundAvatar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RoundAvatar.js","names":["styled","RoundAvatar","div","withConfig","displayName","componentId","props","_props$$size","$size","_props$$size2","$bg","_props$$size3","size","$bordered","$overlap"],"sources":["../../../../src/presentation/shared/RoundAvatar.tsx"],"sourcesContent":["import styled from \"styled-components\";\n\n/**\n * A simple round initials avatar used across the presentation mock-ups in\n * place of real user images. `$overlap` makes stacked avatars overlap (task\n * rows / cards), `$bordered` draws the paper-coloured ring that separates\n * overlapping avatars.\n */\nexport const RoundAvatar = styled.div<{\n $bg: string;\n $size?: number;\n $overlap?: boolean;\n $bordered?: boolean;\n}>`\n width: ${(props) => props.$size ?? 28}px;\n height: ${(props) => props.$size ?? 28}px;\n border-radius: 50%;\n background-color: ${(props) => props.$bg};\n color: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: ${(props) => {\n const size = props.$size ?? 28;\n if (size <= 22) return 9;\n if (size <= 26) return 10;\n return 11;\n }}px;\n font-weight: 700;\n flex-shrink: 0;\n ${(props) =>\n props.$bordered === false\n ? \"\"\n : \"border: 2px solid var(--page-paper-main);\"}\n\n &:not(:first-child) {\n margin-left: ${(props) => (props.$overlap ? \"-8px\" : \"0\")};\n }\n`;\n\nRoundAvatar.displayName = \"RoundAvatar\";\n"],"mappings":"AAAA,OAAOA,MAAM,MAAM,mBAAmB;;AAEtC;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,WAAW,GAAGD,MAAM,CAACE,GAAG,CAAAC,UAAA;EAAAC,WAAA;EAAAC,WAAA;AAAA,wOAMzBC,KAAK;EAAA,IAAAC,YAAA;EAAA,QAAAA,YAAA,GAAKD,KAAK,CAACE,KAAK,YAAAD,YAAA,GAAI,EAAE;AAAA,GAC1BD,KAAK;EAAA,IAAAG,aAAA;EAAA,QAAAA,aAAA,GAAKH,KAAK,CAACE,KAAK,YAAAC,aAAA,GAAI,EAAE;AAAA,GAEjBH,KAAK,IAAKA,KAAK,CAACI,GAAG,EAK1BJ,KAAK,IAAK;EAAA,IAAAK,aAAA;EACtB,MAAMC,IAAI,IAAAD,aAAA,GAAGL,KAAK,CAACE,KAAK,YAAAG,aAAA,GAAI,EAAE;EAC9B,IAAIC,IAAI,IAAI,EAAE,EAAE,OAAO,CAAC;EACxB,IAAIA,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE;EACzB,OAAO,EAAE;AACX,CAAC,EAGEN,KAAK,IACNA,KAAK,CAACO,SAAS,KAAK,KAAK,GACrB,EAAE,GACF,2CAA2C,EAG/BP,KAAK,IAAMA,KAAK,CAACQ,QAAQ,GAAG,MAAM,GAAG,GAAI,CAE5D;AAEDb,WAAW,CAACG,WAAW,GAAG,aAAa","ignoreList":[]}
@@ -0,0 +1,22 @@
1
+ import { ReactElement } from "react";
2
+ export interface TaskOptionsMenuProps {
3
+ /** Class on the TreeDots trigger (parent controls its hover visibility). */
4
+ targetClassName?: string;
5
+ /** IconButton size of the trigger (omit for the default/regular size). */
6
+ size?: "small" | "big";
7
+ }
8
+ export declare const TaskOptionsMenu: {
9
+ ({ targetClassName, size, }: TaskOptionsMenuProps): ReactElement;
10
+ displayName: string;
11
+ };
12
+ export interface TaskListOptionsMenuProps {
13
+ /** Class on the TreeDots trigger (parent controls its hover visibility). */
14
+ targetClassName?: string;
15
+ /** IconButton size of the trigger (omit for the default/regular size). */
16
+ size?: "small" | "big";
17
+ }
18
+ export declare const TaskListOptionsMenu: {
19
+ ({ targetClassName, size, }: TaskListOptionsMenuProps): ReactElement;
20
+ displayName: string;
21
+ };
22
+ //# sourceMappingURL=TaskOptionsMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskOptionsMenu.d.ts","sourceRoot":"","sources":["../../../../src/presentation/shared/TaskOptionsMenu.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,YAAY,EAAyB,MAAM,OAAO,CAAC;AA8DnE,MAAM,WAAW,oBAAoB;IACnC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;CACxB;AAED,eAAO,MAAM,eAAe;iCAGzB,oBAAoB,GAAG,YAAY;;CA0ErC,CAAC;AAIF,MAAM,WAAW,wBAAwB;IACvC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;CACxB;AAKD,eAAO,MAAM,mBAAmB;iCAG7B,wBAAwB,GAAG,YAAY;;CAoDzC,CAAC"}
@@ -0,0 +1,119 @@
1
+ import React, { useCallback, useState } from "react";
2
+ import styled from "styled-components";
3
+ import { Checkbox } from "../../components/Checkbox";
4
+ import { IconButton } from "../../components/IconButton";
5
+ import { ArrowRightIcon, CopyIcon, DuplicateIcon, EditIcon, RecurringCheckmarkIcon, TaskListCompleteIcon, TrashIcon, TreeDotsIcon } from "../../components/Icons";
6
+ import { List, ListItem, ListSeparator } from "../../components/List";
7
+ import { Menu } from "../../components/Menu";
8
+ import { Tooltip } from "../../components/Tooltip";
9
+
10
+ /* Task three-dot options menu — same component as the real TaskItem
11
+ (Menu in "normal" mode = 260px, List/ListItem + TreeDots target), shared by
12
+ the List view and Column view presentations. Spacing is styled-components
13
+ (this Storybook has no runtime Tailwind). Clicks are intentionally no-ops. */
14
+ const StyledTaskMenu = styled.div.withConfig({
15
+ displayName: "TaskOptionsMenu__StyledTaskMenu",
16
+ componentId: "sc-1hrykzg-0"
17
+ })([".menu-list{padding:8px 0;}.menu-item{justify-content:space-between;}.menu-item .label{min-width:0;padding-right:8px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.menu-bottom{display:flex;justify-content:space-between;padding:0 16px;margin:16px 0 12px;}"]);
18
+ const MENU_PICKER_ITEMS = ["Task List", "Assignees", "Due Date", "Label", "Estimate"];
19
+ export const TaskOptionsMenu = _ref => {
20
+ let targetClassName = _ref.targetClassName,
21
+ size = _ref.size;
22
+ const _useState = useState(false),
23
+ open = _useState[0],
24
+ setOpen = _useState[1];
25
+ const handleOpen = useCallback(() => setOpen(true), []);
26
+ const handleClose = useCallback(() => setOpen(false), []);
27
+ const triggerClassName = [targetClassName, open ? "open" : ""].filter(Boolean).join(" ") || undefined;
28
+ return /*#__PURE__*/React.createElement(Menu, {
29
+ open: open,
30
+ onOpen: handleOpen,
31
+ onClose: handleClose,
32
+ position: "bottom-end",
33
+ target: /*#__PURE__*/React.createElement(IconButton, {
34
+ type: "button",
35
+ variant: "text gray",
36
+ size: size,
37
+ className: triggerClassName,
38
+ active: open
39
+ }, /*#__PURE__*/React.createElement(TreeDotsIcon, null))
40
+ }, /*#__PURE__*/React.createElement(StyledTaskMenu, null, /*#__PURE__*/React.createElement(List, {
41
+ className: "menu-list",
42
+ tabIndex: 0
43
+ }, MENU_PICKER_ITEMS.map(name => /*#__PURE__*/React.createElement(ListItem, {
44
+ key: name,
45
+ className: "menu-item"
46
+ }, /*#__PURE__*/React.createElement("div", {
47
+ className: "label"
48
+ }, name), /*#__PURE__*/React.createElement(ArrowRightIcon, null))), /*#__PURE__*/React.createElement(ListSeparator, null), /*#__PURE__*/React.createElement(ListItem, {
49
+ className: "menu-item"
50
+ }, /*#__PURE__*/React.createElement("div", {
51
+ className: "label"
52
+ }, "Hidden from clients"), /*#__PURE__*/React.createElement(Checkbox, {
53
+ id: "task-menu-hidden-from-clients",
54
+ onChange: () => undefined
55
+ })), /*#__PURE__*/React.createElement(ListItem, {
56
+ className: "menu-item"
57
+ }, /*#__PURE__*/React.createElement("div", {
58
+ className: "label"
59
+ }, "High priority"), /*#__PURE__*/React.createElement(Checkbox, {
60
+ id: "task-menu-high-priority",
61
+ onChange: () => undefined
62
+ })), /*#__PURE__*/React.createElement(ListSeparator, null), /*#__PURE__*/React.createElement("div", {
63
+ className: "menu-bottom"
64
+ }, /*#__PURE__*/React.createElement(Tooltip, {
65
+ title: "Edit"
66
+ }, /*#__PURE__*/React.createElement(IconButton, {
67
+ type: "button",
68
+ variant: "text gray"
69
+ }, /*#__PURE__*/React.createElement(EditIcon, null))), /*#__PURE__*/React.createElement(Tooltip, {
70
+ title: "Duplicate"
71
+ }, /*#__PURE__*/React.createElement(IconButton, {
72
+ type: "button",
73
+ variant: "text gray"
74
+ }, /*#__PURE__*/React.createElement(DuplicateIcon, null))), /*#__PURE__*/React.createElement(Tooltip, {
75
+ title: "Create Recurring Task"
76
+ }, /*#__PURE__*/React.createElement(IconButton, {
77
+ type: "button",
78
+ variant: "text gray"
79
+ }, /*#__PURE__*/React.createElement(RecurringCheckmarkIcon, null))), /*#__PURE__*/React.createElement(Tooltip, {
80
+ title: "Delete"
81
+ }, /*#__PURE__*/React.createElement(IconButton, {
82
+ type: "button",
83
+ variant: "text gray"
84
+ }, /*#__PURE__*/React.createElement(TrashIcon, null)))))));
85
+ };
86
+ TaskOptionsMenu.displayName = "TaskOptionsMenu";
87
+ /* Task-LIST three-dot menu (Menu + List with leading-icon items) — same
88
+ options as the real TaskListOptions. Shared by List & Column views.
89
+ Clicks are intentionally no-ops. */
90
+ export const TaskListOptionsMenu = _ref2 => {
91
+ let targetClassName = _ref2.targetClassName,
92
+ size = _ref2.size;
93
+ const _useState2 = useState(false),
94
+ open = _useState2[0],
95
+ setOpen = _useState2[1];
96
+ const handleOpen = useCallback(() => setOpen(true), []);
97
+ const handleClose = useCallback(() => setOpen(false), []);
98
+ const triggerClassName = [targetClassName, open ? "open" : ""].filter(Boolean).join(" ") || undefined;
99
+ return /*#__PURE__*/React.createElement(Menu, {
100
+ open: open,
101
+ onOpen: handleOpen,
102
+ onClose: handleClose,
103
+ position: "bottom-end",
104
+ target: /*#__PURE__*/React.createElement(IconButton, {
105
+ type: "button",
106
+ variant: "text gray",
107
+ size: size,
108
+ className: triggerClassName,
109
+ active: open
110
+ }, /*#__PURE__*/React.createElement(TreeDotsIcon, null))
111
+ }, /*#__PURE__*/React.createElement(List, {
112
+ style: {
113
+ padding: "8px 0"
114
+ },
115
+ tabIndex: -1
116
+ }, /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(EditIcon, null), "Rename"), /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(DuplicateIcon, null), "Duplicate"), /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(CopyIcon, null), "Move/Copy to Project"), /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(TaskListCompleteIcon, null), "Complete"), /*#__PURE__*/React.createElement(ListSeparator, null), /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(TrashIcon, null), "Delete")));
117
+ };
118
+ TaskListOptionsMenu.displayName = "TaskListOptionsMenu";
119
+ //# sourceMappingURL=TaskOptionsMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskOptionsMenu.js","names":["React","useCallback","useState","styled","Checkbox","IconButton","ArrowRightIcon","CopyIcon","DuplicateIcon","EditIcon","RecurringCheckmarkIcon","TaskListCompleteIcon","TrashIcon","TreeDotsIcon","List","ListItem","ListSeparator","Menu","Tooltip","StyledTaskMenu","div","withConfig","displayName","componentId","MENU_PICKER_ITEMS","TaskOptionsMenu","_ref","targetClassName","size","_useState","open","setOpen","handleOpen","handleClose","triggerClassName","filter","Boolean","join","undefined","createElement","onOpen","onClose","position","target","type","variant","className","active","tabIndex","map","name","key","id","onChange","title","TaskListOptionsMenu","_ref2","_useState2","style","padding"],"sources":["../../../../src/presentation/shared/TaskOptionsMenu.tsx"],"sourcesContent":["import React, { ReactElement, useCallback, useState } from \"react\";\n\nimport styled from \"styled-components\";\n\nimport { Checkbox } from \"../../components/Checkbox\";\nimport { IconButton } from \"../../components/IconButton\";\nimport {\n ArrowRightIcon,\n CopyIcon,\n DuplicateIcon,\n EditIcon,\n RecurringCheckmarkIcon,\n TaskListCompleteIcon,\n TrashIcon,\n TreeDotsIcon,\n} from \"../../components/Icons\";\nimport { List, ListItem, ListSeparator } from \"../../components/List\";\nimport { Menu } from \"../../components/Menu\";\nimport { Tooltip } from \"../../components/Tooltip\";\n\n/* Task three-dot options menu — same component as the real TaskItem\n (Menu in \"normal\" mode = 260px, List/ListItem + TreeDots target), shared by\n the List view and Column view presentations. Spacing is styled-components\n (this Storybook has no runtime Tailwind). Clicks are intentionally no-ops. */\nconst StyledTaskMenu = styled.div`\n /* no width — fills the 260px Menu bubble */\n\n .menu-list {\n padding: 8px 0;\n }\n\n /* text on the left, control (arrow / checkbox) on the right */\n .menu-item {\n justify-content: space-between;\n }\n\n .menu-item .label {\n min-width: 0;\n padding-right: 8px;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n /* bottom action icons: same horizontal padding as a list item (0 1rem),\n spread evenly */\n .menu-bottom {\n display: flex;\n justify-content: space-between;\n padding: 0 16px;\n margin: 16px 0 12px;\n }\n`;\n\nconst MENU_PICKER_ITEMS = [\n \"Task List\",\n \"Assignees\",\n \"Due Date\",\n \"Label\",\n \"Estimate\",\n];\n\nexport interface TaskOptionsMenuProps {\n /** Class on the TreeDots trigger (parent controls its hover visibility). */\n targetClassName?: string;\n /** IconButton size of the trigger (omit for the default/regular size). */\n size?: \"small\" | \"big\";\n}\n\nexport const TaskOptionsMenu = ({\n targetClassName,\n size,\n}: TaskOptionsMenuProps): ReactElement => {\n const [open, setOpen] = useState(false);\n const handleOpen = useCallback(() => setOpen(true), []);\n const handleClose = useCallback(() => setOpen(false), []);\n\n const triggerClassName =\n [targetClassName, open ? \"open\" : \"\"].filter(Boolean).join(\" \") ||\n undefined;\n\n return (\n <Menu\n open={open}\n onOpen={handleOpen}\n onClose={handleClose}\n position=\"bottom-end\"\n target={\n <IconButton\n type=\"button\"\n variant=\"text gray\"\n size={size}\n className={triggerClassName}\n active={open}\n >\n <TreeDotsIcon />\n </IconButton>\n }\n >\n <StyledTaskMenu>\n <List className=\"menu-list\" tabIndex={0}>\n {MENU_PICKER_ITEMS.map((name) => (\n <ListItem key={name} className=\"menu-item\">\n <div className=\"label\">{name}</div>\n <ArrowRightIcon />\n </ListItem>\n ))}\n <ListSeparator />\n <ListItem className=\"menu-item\">\n <div className=\"label\">Hidden from clients</div>\n <Checkbox\n id=\"task-menu-hidden-from-clients\"\n onChange={() => undefined}\n />\n </ListItem>\n <ListItem className=\"menu-item\">\n <div className=\"label\">High priority</div>\n <Checkbox id=\"task-menu-high-priority\" onChange={() => undefined} />\n </ListItem>\n <ListSeparator />\n <div className=\"menu-bottom\">\n <Tooltip title=\"Edit\">\n <IconButton type=\"button\" variant=\"text gray\">\n <EditIcon />\n </IconButton>\n </Tooltip>\n <Tooltip title=\"Duplicate\">\n <IconButton type=\"button\" variant=\"text gray\">\n <DuplicateIcon />\n </IconButton>\n </Tooltip>\n <Tooltip title=\"Create Recurring Task\">\n <IconButton type=\"button\" variant=\"text gray\">\n <RecurringCheckmarkIcon />\n </IconButton>\n </Tooltip>\n <Tooltip title=\"Delete\">\n <IconButton type=\"button\" variant=\"text gray\">\n <TrashIcon />\n </IconButton>\n </Tooltip>\n </div>\n </List>\n </StyledTaskMenu>\n </Menu>\n );\n};\n\nTaskOptionsMenu.displayName = \"TaskOptionsMenu\";\n\nexport interface TaskListOptionsMenuProps {\n /** Class on the TreeDots trigger (parent controls its hover visibility). */\n targetClassName?: string;\n /** IconButton size of the trigger (omit for the default/regular size). */\n size?: \"small\" | \"big\";\n}\n\n/* Task-LIST three-dot menu (Menu + List with leading-icon items) — same\n options as the real TaskListOptions. Shared by List & Column views.\n Clicks are intentionally no-ops. */\nexport const TaskListOptionsMenu = ({\n targetClassName,\n size,\n}: TaskListOptionsMenuProps): ReactElement => {\n const [open, setOpen] = useState(false);\n const handleOpen = useCallback(() => setOpen(true), []);\n const handleClose = useCallback(() => setOpen(false), []);\n\n const triggerClassName =\n [targetClassName, open ? \"open\" : \"\"].filter(Boolean).join(\" \") ||\n undefined;\n\n return (\n <Menu\n open={open}\n onOpen={handleOpen}\n onClose={handleClose}\n position=\"bottom-end\"\n target={\n <IconButton\n type=\"button\"\n variant=\"text gray\"\n size={size}\n className={triggerClassName}\n active={open}\n >\n <TreeDotsIcon />\n </IconButton>\n }\n >\n <List style={{ padding: \"8px 0\" }} tabIndex={-1}>\n <ListItem>\n <EditIcon />\n Rename\n </ListItem>\n <ListItem>\n <DuplicateIcon />\n Duplicate\n </ListItem>\n <ListItem>\n <CopyIcon />\n Move/Copy to Project\n </ListItem>\n <ListItem>\n <TaskListCompleteIcon />\n Complete\n </ListItem>\n <ListSeparator />\n <ListItem>\n <TrashIcon />\n Delete\n </ListItem>\n </List>\n </Menu>\n );\n};\n\nTaskListOptionsMenu.displayName = \"TaskListOptionsMenu\";\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,28 @@
1
+ import { ReactElement, ReactNode } from "react";
2
+ export interface PageHeaderProps {
3
+ title: string;
4
+ children?: ReactNode;
5
+ }
6
+ /** Generic page header (title + optional controls), mirrors PageHeader.jsx. */
7
+ export declare const PageHeader: {
8
+ ({ title, children, }: PageHeaderProps): ReactElement;
9
+ displayName: string;
10
+ };
11
+ export interface ProjectPageHeaderProps {
12
+ title?: string;
13
+ }
14
+ /** The project page header: back arrow, title, progress, info, people, options. */
15
+ export declare const ProjectPageHeader: {
16
+ ({ title, }: ProjectPageHeaderProps): ReactElement;
17
+ displayName: string;
18
+ };
19
+ export interface TabHeaderProps {
20
+ /** Which view-mode toggle is highlighted as active. */
21
+ activeView?: "list" | "column" | "timeline";
22
+ }
23
+ /** The Tasks/Discussions/… tab bar plus the right-hand view toolbar. */
24
+ export declare const TabHeader: {
25
+ ({ activeView, }: TabHeaderProps): ReactElement;
26
+ displayName: string;
27
+ };
28
+ //# sourceMappingURL=headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../../../src/presentation/shared/headers.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,YAAY,EAAE,SAAS,EAAY,MAAM,OAAO,CAAC;AAqHjE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,+EAA+E;AAC/E,eAAO,MAAM,UAAU;2BAGpB,eAAe,GAAG,YAAY;;CAShC,CAAC;AA8GF,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,mFAAmF;AACnF,eAAO,MAAM,iBAAiB;iBAE3B,sBAAsB,GAAG,YAAY;;CAkCvC,CAAC;AAsCF,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;CAC7C;AAED,wEAAwE;AACxE,eAAO,MAAM,SAAS;sBAEnB,cAAc,GAAG,YAAY;;CA8C/B,CAAC"}