]> Eric's Git Repo - listv4.git/commitdiff
Mobile styling updates
authorEric Wertz <ericwertz@Erics-MacBook-Pro.local>
Mon, 9 Jun 2025 04:11:51 +0000 (00:11 -0400)
committerEric Wertz <ericwertz@Erics-MacBook-Pro.local>
Mon, 9 Jun 2025 04:11:51 +0000 (00:11 -0400)
backend/HTTPRequest.cpp
backend/StaticFileResponse.cpp
frontend/app/AppRouter.tsx
frontend/app_routes.tsx
frontend/components/ListContext.tsx
frontend/components/ListItem.tsx
frontend/components/Toolbar.tsx
frontend/styles.css
frontend/views/List.tsx

index 4aa284b2c6abc631fd71fd6f81367f7d3f5e7e82..3619be387009e2b38dc8024735cfad2852ae703a 100644 (file)
@@ -172,10 +172,12 @@ void CHTTPRequest::parsePath()
                 _queryParams[param] = "";
             }
         }
+
+        _path = pathWithoutQuery;
     }
     
     // Parse path components
-    std::istringstream pathStream(pathWithoutQuery);
+    std::istringstream pathStream(_path);
     std::string component;
     
     while (std::getline(pathStream, component, '/')) {
index 19e3f0e88cd999846b65a90bffa49c1e404addfc..1417e044d645816d2da1de52610d448dff50d0c0 100644 (file)
 // CStaticFileResponse Implementation
 CStaticFileResponse::CStaticFileResponse(const CHTTPRequest& request, std::string path) : CHTTPResponse(request)
 {
-    // Remove query string from path for routing decisions
-    std::string clean_path = path;
-    size_t query_pos = clean_path.find('?');
-    if (query_pos != std::string::npos) {
-        clean_path = clean_path.substr(0, query_pos);
-    }
-    
     // Index is easy enough to handle
-    if (clean_path == "/" )
+    if (path == "/" )
     {
         serveFileFromPath("index.html");
         return;
@@ -38,10 +31,6 @@ std::string CStaticFileResponse::sanitizePath(const std::string& requested_path)
 {
     // Remove query string if present
     std::string path = requested_path;
-    size_t query_pos = path.find('?');
-    if (query_pos != std::string::npos) {
-        path = path.substr(0, query_pos);
-    }
     
     // Basic path normalization - remove duplicate slashes and handle relative paths
     std::string normalized = "/";
index 9a56c34b03eff73f3ac1cc7a959f682085001fcb..868e85be55e8ab242c6a0502ab46a6e1e063cfa7 100644 (file)
@@ -7,7 +7,7 @@ import { AppContext } from './AppContext';
 import NotFound from 'views/NotFound';
 
 // Wrapper component to handle auth checks
-const AuthRoute = ({ component: Component, auth_required }: { component: ComponentType, auth_required: boolean }) => {
+const AuthRoute = ({ component: Component, auth_required, title }: { component: ComponentType, auth_required: boolean, title: string }) => {
     const { isLoading, loggedIn, checkAuth } = useContext(AppContext);
     const [, route] = useRouter();
 
@@ -29,6 +29,11 @@ const AuthRoute = ({ component: Component, auth_required }: { component: Compone
         }
     }, [isLoading, loggedIn, auth_required, route]);
 
+    // Set page title
+    useEffect(() => {
+        document.title = title;
+    }, [title]);
+
     if (isLoading) {
         return null;
     }
@@ -55,6 +60,7 @@ const AppRouter = () => {
                         <AuthRoute 
                             component={route.view} 
                             auth_required={route.auth_required}
+                            title={route.title}
                         />
                     )}
                 />
index 70380e0fd3b7b17688e5dede1d62575dec32ecbc..d6da90bf5e84075268b4a042dd5ae1711148198c 100644 (file)
@@ -14,21 +14,25 @@ export const AppRoutes = [
     {
         path: '/',
         view: List,
+        title: 'List',
         auth_required: true,
     },
     {
         path: '/list',
         view: List,
+        title: 'List',
         auth_required: true,
     },
     {
         path: '/signup',
         view: SignUp,
+        title: 'Sign Up',
         auth_required: false,
     },
     {
         path: '/login',
         view: Login,
+        title: 'Login',
         auth_required: false,
     },
 ];
index 0c2659a7e19540124e8295b3f2ef9e198440db54..c26a02e27fb61b98d00e75b3e1a357b8e44d62de 100644 (file)
@@ -369,10 +369,14 @@ export const useListState = () => {
             const previousItem = findPreviousItem(prevItems, currentItem._uuid);
             if (!previousItem) return prevItems;
 
-            // Update previous item and mark current as deleted
+            // Get the children of the item being deleted
+            const childrenToMove = currentItem._children.filter(child => !child.__is_deleted);
+
+            // Update previous item with remaining content and append deleted item's children
             let result = updateItemInTree(prevItems, previousItem._uuid, item => ({
                 ...item,
                 content: item.content + remainingContent,
+                _children: reorderItems([...item._children, ...childrenToMove]),
                 __is_dirty: true
             }));
 
index af4f250159a7504da2a07184a8c205c44d3db517..f9247ed412a1e1bfee1b2b65e643d655fe18b4ee 100644 (file)
@@ -101,14 +101,26 @@ export const ListItem = forwardRef<ListItemRef, ListItemProps>(({ item, onChange
 
     const handleKeyDown = (event: KeyboardEvent) => {
         if (event.key === 'Enter') {
-            // Enter key - create new item
-            event.preventDefault();
-            const target = event.target as HTMLDivElement;
-            const cursorPosition = getCursorPosition(target);
-            const fullContent = target.textContent || '';
-            const beforeContent = fullContent.substring(0, cursorPosition);
-            const afterContent = fullContent.substring(cursorPosition);
-            createItem(item, beforeContent, afterContent);
+            if (event.shiftKey === true) {
+                // Shift+Enter - add newline (allow default behavior, then update content)
+                setTimeout(() => {
+                    const target = event.target as HTMLDivElement;
+                    const content = target.innerHTML;
+                    if (item.content !== content) {
+                        onChange({ ...item, content, __is_dirty: true });
+                    }
+                }, 0);
+                return;
+            } else {
+                // Enter key - create new item
+                event.preventDefault();
+                const target = event.target as HTMLDivElement;
+                const cursorPosition = getCursorPosition(target);
+                const fullContent = target.textContent || '';
+                const beforeContent = fullContent.substring(0, cursorPosition);
+                const afterContent = fullContent.substring(cursorPosition);
+                createItem(item, beforeContent, afterContent);
+            }
         } else if (event.key === 'Backspace') {
             const target = event.target as HTMLDivElement;
             const cursorPosition = getCursorPosition(target);
index f1227c672945b17b639786a41afdd838eaedda28..4a3e89f3e022ce6755a660aa2cdbc54e9ff4e3f4 100644 (file)
@@ -1,5 +1,5 @@
 import { h, JSX } from 'preact';
-import { useContext } from 'preact/hooks';
+import { useContext, useEffect, useRef } from 'preact/hooks';
 import { AppContext } from 'app/AppContext';
 import LoadingSpinner from './LoadingSpinner';
 import { MenuIcon, CheckIcon, CircleIcon } from './Icons';
@@ -12,6 +12,7 @@ interface ToolbarProps {
 
 export const Toolbar = ({ buttons, onMenuClick }: ToolbarProps) => {
     const appContext = useContext(AppContext);
+    const toolbarRef = useRef<HTMLDivElement>(null);
 
     const handleMenuClick = () => {
         if (onMenuClick) {
@@ -22,61 +23,97 @@ export const Toolbar = ({ buttons, onMenuClick }: ToolbarProps) => {
         }
     };
 
+    useEffect(() => {
+        function resizeHandler() {
+            if( !toolbarRef.current) {
+                return;
+            }
+
+            if( window.visualViewport?.width && window.visualViewport.width > 480) {
+                return;
+            }
+
+            // viewport height
+            const viewportHeight = window.visualViewport?.height ?? 0;
+            const offsetTop = window.visualViewport?.offsetTop ?? 0;
+            const viewportScale = window.visualViewport?.scale ?? 1;
+            // math - removed scale transform to prevent event handling issues
+            toolbarRef.current.style.transform = `translate( 0px, ${viewportHeight - toolbarRef.current.offsetHeight + offsetTop}px)`;
+          }
+      
+          // run first time to initialize 
+          resizeHandler();
+      
+          // subscribe to events which affect scroll, or viewport position
+          window.visualViewport?.addEventListener('resize', resizeHandler);
+          window.visualViewport?.addEventListener('scroll', resizeHandler);
+          window?.addEventListener('touchmove', resizeHandler);
+      
+          // unsubscribe
+          return () => {
+            window.visualViewport?.removeEventListener('resize', resizeHandler);
+            window.visualViewport?.removeEventListener('scroll', resizeHandler);
+            window?.removeEventListener('touchmove', resizeHandler);
+          };
+    }, []);
+
     return (
-        <div class="toolbar">
-            <div class="toolbar-left">
-                <ToolbarButton
-                    icon={<MenuIcon size={20} />}
-                    onClick={handleMenuClick}
-                    title="Menu"
-                    menuOptions={[
-                        {
-                            label: 'List',
-                            onClick: () => {
-                                window.location.href = '/list';
+        <div class="toolbar-spacer">
+            <div class="toolbar" ref={toolbarRef}>
+                <div class="toolbar-left">
+                    <ToolbarButton
+                        icon={<MenuIcon size={20} />}
+                        onClick={handleMenuClick}
+                        title="Menu"
+                        menuOptions={[
+                            {
+                                label: 'List',
+                                onClick: () => {
+                                    window.location.href = '/list';
+                                }
+                            },
+                            {
+                                label: 'Chat',
+                                onClick: () => {
+                                    window.location.href = '/chat';
+                                }
+                            },
+                            {
+                                label: 'Logout',
+                                onClick: () => {
+                                    appContext.logout();
+                                }
                             }
-                        },
-                        {
-                            label: 'Chat',
-                            onClick: () => {
-                                window.location.href = '/chat';
-                            }
-                        },
-                        {
-                            label: 'Logout',
-                            onClick: () => {
-                                appContext.logout();
-                            }
-                        }
-                    ]}
-                />
-                <div class="toolbar-separator" />
-                {buttons.map((button, index) => (
-                    <div key={index} class="toolbar-button-container">
-                        <ToolbarButton
-                            icon={button.icon}
-                            onClick={button.onClick}
-                            title={button.title}
-                            disabled={button.disabled}
-                            active={button.active}
-                        />
-                        {button.separatorAfter && (
-                            <div class="toolbar-separator" />
-                        )}
-                    </div>
-                ))}
-            </div>
-            
-            <div class="toolbar-right">
-                {appContext.saveStatus === 'saving' ? (
-                    <LoadingSpinner />
-                ) : appContext.saveStatus === 'saved' ? (
-                    <CheckIcon size={20} />
-                ) : appContext.saveStatus === 'queued' ? (
-                    <CircleIcon size={20} />
-                ) : (
-                    <CheckIcon size={20} />
-                )}
+                        ]}
+                    />
+                    <div class="toolbar-separator" />
+                    {buttons.map((button, index) => (
+                        <div key={index} class="toolbar-button-container">
+                            <ToolbarButton
+                                icon={button.icon}
+                                onClick={button.onClick}
+                                title={button.title}
+                                disabled={button.disabled}
+                                active={button.active}
+                            />
+                            {button.separatorAfter && (
+                                <div class="toolbar-separator" />
+                            )}
+                        </div>
+                    ))}
+                </div>
+                
+                <div class="toolbar-right">
+                    {appContext.saveStatus === 'saving' ? (
+                        <LoadingSpinner />
+                    ) : appContext.saveStatus === 'saved' ? (
+                        <CheckIcon size={20} />
+                    ) : appContext.saveStatus === 'queued' ? (
+                        <CircleIcon size={20} />
+                    ) : (
+                        <CheckIcon size={20} />
+                    )}
+                </div>
             </div>
         </div>
     );
index af21cbdf8106bae5b4ba884dba2fe4b19676fbae..62fbc71916efcbf1923bd41418018f0a2d328d10 100644 (file)
@@ -3,6 +3,10 @@
 /* Base Styles */
 body {
     font-family: 'Lato', sans-serif;
+    padding-bottom: 3.25rem; /* Account for fixed bottom toolbar */
+    margin: 0;
+    min-height: 100vh;
+    -webkit-overflow-scrolling: touch; /* Smooth scrolling on iOS */
 }
 
 h1 {
@@ -10,49 +14,51 @@ h1 {
 }
 
 .loader {
-    width: 48px;
-    height: 48px;
+    width: 3rem;
+    height: 3rem;
     border-radius: 50%;
     position: relative;
-    animation: rotate 1s linear infinite
-  }
+    animation: rotate 1s linear infinite;
+}
+
 .loader-small {
-    width: 24px;
-    height: 24px;
+    width: 1.5rem;
+    height: 1.5rem;
     border-radius: 50%;
     position: relative;
-    animation: rotate 1s linear infinite
-  }
-  .loader::before, .loader-small::before {
+    animation: rotate 1s linear infinite;
+}
+
+.loader::before, .loader-small::before {
     content: "";
     box-sizing: border-box;
     position: absolute;
-    inset: 0px;
+    inset: 0;
     border-radius: 50%;
-    border: 5px solid #0074ff;
-    animation: prixClipFix 2s linear infinite ;
-  }
-
-  @keyframes rotate {
-    100%   {transform: rotate(360deg)}
-  }
-
-  @keyframes prixClipFix {
-      0%   {clip-path:polygon(50% 50%,0 0,0 0,0 0,0 0,0 0)}
-      25%  {clip-path:polygon(50% 50%,0 0,100% 0,100% 0,100% 0,100% 0)}
-      50%  {clip-path:polygon(50% 50%,0 0,100% 0,100% 100%,100% 100%,100% 100%)}
-      75%  {clip-path:polygon(50% 50%,0 0,100% 0,100% 100%,0 100%,0 100%)}
-      100% {clip-path:polygon(50% 50%,0 0,100% 0,100% 100%,0 100%,0 0)}
-  }
+    border: 0.3125rem solid #0074ff;
+    animation: prixClipFix 2s linear infinite;
+}
+
+@keyframes rotate {
+    100% { transform: rotate(360deg) }
+}
+
+@keyframes prixClipFix {
+    0%   { clip-path: polygon(50% 50%,0 0,0 0,0 0,0 0,0 0) }
+    25%  { clip-path: polygon(50% 50%,0 0,100% 0,100% 0,100% 0,100% 0) }
+    50%  { clip-path: polygon(50% 50%,0 0,100% 0,100% 100%,100% 100%,100% 100%) }
+    75%  { clip-path: polygon(50% 50%,0 0,100% 0,100% 100%,0 100%,0 100%) }
+    100% { clip-path: polygon(50% 50%,0 0,100% 0,100% 100%,0 100%,0 0) }
+}
 
 /* Form Styles */
 form {
-    max-width: 400px;
+    max-width: 25rem;
     margin: 2rem auto;
     padding: 2rem;
     background: white;
-    border-radius: 8px;
-    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+    border-radius: 0.5rem;
+    box-shadow: 0 0.125rem 0.625rem rgba(0, 0, 0, 0.1);
 }
 
 form h1 {
@@ -64,10 +70,10 @@ form h1 {
 
 form input {
     width: 100%;
-    padding: 12px;
+    padding: 0.75rem;
     margin-bottom: 1rem;
     border: 1px solid #ddd;
-    border-radius: 4px;
+    border-radius: 0.25rem;
     font-size: 1rem;
     transition: border-color 0.3s ease;
 }
@@ -75,16 +81,16 @@ form input {
 form input:focus {
     outline: none;
     border-color: #0074ff;
-    box-shadow: 0 0 0 2px rgba(0, 116, 255, 0.1);
+    box-shadow: 0 0 0 0.125rem rgba(0, 116, 255, 0.1);
 }
 
 form button {
     width: 100%;
-    padding: 12px;
+    padding: 0.75rem;
     background: #0074ff;
     color: white;
     border: none;
-    border-radius: 4px;
+    border-radius: 0.25rem;
     font-size: 1rem;
     cursor: pointer;
     transition: background-color 0.3s ease;
@@ -111,12 +117,12 @@ form button:active {
     animation: slideDown 0.3s ease forwards;
     z-index: 2000;
     border: 1px solid #000;
-    border-radius: 4px;
+    border-radius: 0.25rem;
     display: flex;
     align-items: center;
     justify-content: center;
     gap: 0.5rem;
-    backdrop-filter: blur(10px);
+    backdrop-filter: blur(0.625rem);
 }
 
 .status-bar.info {
@@ -166,21 +172,13 @@ form button:active {
 }
 
 @keyframes slideDown {
-    from {
-        transform: translateY(-100%);
-    }
-    to {
-        transform: translateY(0);
-    }
+    from { transform: translateY(-100%); }
+    to { transform: translateY(0); }
 }
 
 @keyframes slideUp {
-    from {
-        transform: translateY(0);
-    }
-    to {
-        transform: translateY(-100%);
-    }
+    from { transform: translateY(0); }
+    to { transform: translateY(-100%); }
 }
 
 /* List Item Styles */
@@ -211,7 +209,7 @@ li > div[contenteditable] {
     transition: all 0.2s ease;
     min-height: 1.2em;
     outline: none;
-    display: inline-block;
+    display: block;
 }
 
 li > div[contenteditable]:focus {
@@ -226,7 +224,7 @@ li > div[contenteditable]:hover {
 
 /* Indentation levels using CSS custom properties */
 li {
-    --indent-size: 24px;
+    --indent-size: 1.5rem;
 }
 
 .list-item-level-0 { 
@@ -257,47 +255,49 @@ li {
     font-style: italic;
 }
 
+/* Toolbar Styles */
 .toolbar {
     display: flex;
     justify-content: space-between;
     align-items: center;
-    padding: 8px 16px;
+    padding: 0.5rem 1rem;
     background: linear-gradient(135deg, rgba(248, 249, 250, 0.85) 0%, rgba(233, 236, 239, 0.85) 100%);
-    backdrop-filter: blur(8px);
-    -webkit-backdrop-filter: blur(8px);
+    backdrop-filter: blur(0.5rem);
+    -webkit-backdrop-filter: blur(0.5rem);
     border-bottom: 1px solid #dee2e6;
     position: fixed;
     top: 0;
     left: 0;
     right: 0;
     z-index: 1000;
-    height: 52px;
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+    height: 3.25rem;
+    box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.1);
+    -webkit-overflow-scrolling: touch;
 }
 
-.toolbar-left {
-    display: flex;
-    align-items: center;
-    gap: 8px;
+.toolbar-spacer {
+    display: block;
+    height: 3.75rem;
 }
 
+.toolbar-left,
 .toolbar-right {
     display: flex;
     align-items: center;
-    gap: 8px;
+    gap: 0.5rem;
 }
 
 .toolbar-button-container {
     display: flex;
     align-items: center;
-    gap: 8px;
+    gap: 0.5rem;
 }
 
 .toolbar-separator {
     width: 1px;
-    height: 24px;
+    height: 1.5rem;
     background: #dee2e6;
-    margin: 0 8px;
+    margin: 0 0.5rem;
 }
 
 /* Toolbar Button Wrapper for Menu Functionality */
@@ -310,10 +310,10 @@ li {
     display: flex;
     align-items: center;
     justify-content: center;
-    width: 40px;
-    height: 40px;
+    width: 2.5rem;
+    height: 2.5rem;
     border: 1px solid transparent;
-    border-radius: 6px;
+    border-radius: 0.375rem;
     background: transparent;
     color: #495057;
     cursor: pointer;
@@ -325,17 +325,17 @@ li {
 
 /* Menu indicator for buttons with menus */
 .toolbar-button.has-menu {
-    padding-right: 18px;
+    padding-right: 1.125rem;
     width: auto;
-    min-width: 40px;
+    min-width: 2.5rem;
 }
 
 .menu-indicator {
     position: absolute;
-    right: 4px;
+    right: 0.25rem;
     top: 50%;
     transform: translateY(-50%);
-    font-size: 8px;
+    font-size: 0.5rem;
     line-height: 1;
     opacity: 0.7;
     pointer-events: none;
@@ -384,22 +384,22 @@ li {
     position: absolute;
     top: 100%;
     left: 0;
-    min-width: 180px;
+    min-width: 11.25rem;
     background: white;
     border: 1px solid #dee2e6;
-    border-radius: 6px;
-    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+    border-radius: 0.375rem;
+    box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.15);
     z-index: 1001;
-    margin-top: 4px;
-    padding: 4px 0;
-    backdrop-filter: blur(10px);
+    margin-top: 0.25rem;
+    padding: 0.25rem 0;
+    backdrop-filter: blur(0.625rem);
     animation: menuFadeIn 0.15s ease-out;
 }
 
 @keyframes menuFadeIn {
     from {
         opacity: 0;
-        transform: translateY(-8px);
+        transform: translateY(-0.5rem);
     }
     to {
         opacity: 1;
@@ -411,15 +411,15 @@ li {
     display: flex;
     align-items: center;
     width: 100%;
-    padding: 8px 12px;
+    padding: 0.5rem 0.75rem;
     border: none;
     background: transparent;
     color: #495057;
-    font-size: 14px;
+    font-size: 0.875rem;
     text-align: left;
     cursor: pointer;
     transition: all 0.2s ease;
-    gap: 8px;
+    gap: 0.5rem;
 }
 
 .toolbar-menu-item:hover:not(.disabled) {
@@ -446,8 +446,8 @@ li {
     display: flex;
     align-items: center;
     justify-content: center;
-    width: 16px;
-    height: 16px;
+    width: 1rem;
+    height: 1rem;
     flex-shrink: 0;
 }
 
@@ -456,4 +456,115 @@ li {
     white-space: nowrap;
     overflow: hidden;
     text-overflow: ellipsis;
-}
\ No newline at end of file
+}
+
+/* Mobile and Responsive Styles */
+@media (max-width: 768px) {
+    .toolbar {
+        height: 2.75rem;
+        padding: 0.375rem 0.75rem;
+    }
+
+    .toolbar-spacer {
+        height: 3.0rem;
+    }
+
+    .toolbar-left,
+    .toolbar-right,
+    .toolbar-button-container {
+        gap: 0.375rem;
+    }
+
+    .toolbar-separator {
+        height: 1.25rem;
+        margin: 0 0.375rem;
+    }
+
+    .toolbar-button {
+        width: 2.25rem;
+        height: 2.25rem;
+        border-radius: 0.25rem;
+    }
+
+    .toolbar-button.has-menu {
+        padding-right: 1rem;
+        min-width: 2.25rem;
+    }
+
+    .menu-indicator {
+        right: 0.1875rem;
+        font-size: 0.4375rem;
+    }
+
+    .toolbar-menu {
+        min-width: 10rem;
+        margin-top: 0.1875rem;
+    }
+
+    .toolbar-menu-item {
+        padding: 0.375rem 0.625rem;
+        font-size: 0.8125rem;
+        gap: 0.375rem;
+    }
+
+    .menu-item-icon {
+        width: 0.875rem;
+        height: 0.875rem;
+    }
+}
+
+@media (max-width: 480px) {
+    .toolbar {
+        height: 2.5rem;
+        padding: 0.25rem 0.5rem;
+        /*top: auto;
+        bottom: 0;*/
+    }
+
+    .toolbar-spacer {
+        height: 0;
+    }
+
+    .toolbar-left,
+    .toolbar-right,
+    .toolbar-button-container {
+        gap: 0.25rem;
+    }
+
+    .toolbar-separator {
+        height: 1.125rem;
+        margin: 0 0.25rem;
+    }
+
+    .toolbar-button {
+        width: 2rem;
+        height: 2rem;
+    }
+
+    .toolbar-button.has-menu {
+        padding-right: 0.875rem;
+        min-width: 2rem;
+    }
+
+    .menu-indicator {
+        right: 0.125rem;
+        font-size: 0.375rem;
+    }
+
+    .toolbar-menu {
+        min-width: 8.75rem;
+        margin-top: 0.125rem;
+        padding: 0.125rem 0;
+    }
+
+    .toolbar-menu-item {
+        padding: 0.3125rem 0.5rem;
+        font-size: 0.75rem;
+        gap: 0.25rem;
+    }
+
+    .menu-item-icon {
+        width: 0.75rem;
+        height: 0.75rem;
+    }
+}
index 3bdc4bd3fb47ed467e9a98c471deff7bf52d24b6..f06b3a8ab7812aa16e9fc77af773b8408ee06a54 100644 (file)
@@ -55,7 +55,7 @@ const ListWithToolbar = () => {
     return (
         <div>
             <Toolbar buttons={buttons} />
-            <div style={{ marginTop: '72px' }}>
+            <div>
                 <ul>
                     {listContext.items.filter(item => !item.__is_deleted).map(item => (
                         <ListItem