浏览代码

Remove Safari 14 support in Wagtail admin – update browserslist and TypeScript (#11258)

Co-authored-by: Sage Abdullah <sage.abdullah@torchbox.com>
Thibaud Colas 1 年之前
父节点
当前提交
b7d2618d93

+ 18 - 0
.babelrc.json

@@ -0,0 +1,18 @@
+{
+  "sourceType": "unambiguous",
+  "presets": [
+    [
+      "@babel/preset-env",
+      {
+        "targets": {
+          "chrome": 100,
+          "safari": 15,
+          "firefox": 91
+        }
+      }
+    ],
+    "@babel/preset-typescript",
+    "@babel/preset-react"
+  ],
+  "plugins": []
+}

+ 1 - 0
.eslintrc.js

@@ -2,6 +2,7 @@ module.exports = {
   extends: [
   extends: [
     '@wagtail/eslint-config-wagtail',
     '@wagtail/eslint-config-wagtail',
     'plugin:@typescript-eslint/recommended',
     'plugin:@typescript-eslint/recommended',
+    'plugin:storybook/recommended',
   ],
   ],
   parser: '@typescript-eslint/parser',
   parser: '@typescript-eslint/parser',
   plugins: ['@typescript-eslint'],
   plugins: ['@typescript-eslint'],

+ 0 - 6
client/scss/components/_button.scss

@@ -102,13 +102,7 @@
       height: 100%;
       height: 100%;
       box-sizing: content-box;
       box-sizing: content-box;
       text-align: center;
       text-align: center;
-      // Remove once we drop support for Safari 14.
-      // stylelint-disable-next-line property-disallowed-list
-      border-top-left-radius: inherit;
       border-start-start-radius: inherit;
       border-start-start-radius: inherit;
-      // Remove once we drop support for Safari 14.
-      // stylelint-disable-next-line property-disallowed-list
-      border-bottom-left-radius: inherit;
       border-end-start-radius: inherit;
       border-end-start-radius: inherit;
     }
     }
 
 

+ 0 - 12
client/scss/components/_userbar.scss

@@ -154,24 +154,12 @@ $positions: (
   }
   }
 
 
   &:first-child {
   &:first-child {
-    // Remove once we drop support for Safari 14.
-    // stylelint-disable-next-line property-disallowed-list
-    border-top-left-radius: $userbar-radius;
     border-start-start-radius: $userbar-radius;
     border-start-start-radius: $userbar-radius;
-    // Remove once we drop support for Safari 14.
-    // stylelint-disable-next-line property-disallowed-list
-    border-top-right-radius: $userbar-radius;
     border-start-end-radius: $userbar-radius;
     border-start-end-radius: $userbar-radius;
   }
   }
 
 
   &:last-child {
   &:last-child {
-    // Remove once we drop support for Safari 14.
-    // stylelint-disable-next-line property-disallowed-list
-    border-bottom-right-radius: $userbar-radius;
     border-end-end-radius: $userbar-radius;
     border-end-end-radius: $userbar-radius;
-    // Remove once we drop support for Safari 14.
-    // stylelint-disable-next-line property-disallowed-list
-    border-bottom-left-radius: $userbar-radius;
     border-end-start-radius: $userbar-radius;
     border-end-start-radius: $userbar-radius;
   }
   }
 
 

+ 0 - 6
client/src/components/CommentApp/main.scss

@@ -71,13 +71,7 @@ $box-padding: 20px;
 
 
   & > &__notice-placeholder:last-child &__notice,
   & > &__notice-placeholder:last-child &__notice,
   &__replies:last-child > :last-child &__notice {
   &__replies:last-child > :last-child &__notice {
-    // Remove once we drop support for Safari 14.
-    // stylelint-disable-next-line property-disallowed-list
-    border-bottom-left-radius: $box-border-radius;
     border-end-start-radius: $box-border-radius;
     border-end-start-radius: $box-border-radius;
-    // Remove once we drop support for Safari 14.
-    // stylelint-disable-next-line property-disallowed-list
-    border-bottom-right-radius: $box-border-radius;
     border-end-end-radius: $box-border-radius;
     border-end-end-radius: $box-border-radius;
   }
   }
 }
 }

+ 0 - 6
client/src/components/Draftail/Draftail.scss

@@ -96,13 +96,7 @@ $draftail-editor-font-family: $font-sans;
 
 
 .Draftail-Toolbar {
 .Draftail-Toolbar {
   border-width: 0;
   border-width: 0;
-  // Remove once we drop support for Safari 14.
-  // stylelint-disable-next-line property-disallowed-list
-  border-bottom-left-radius: 0;
   border-end-start-radius: 0;
   border-end-start-radius: 0;
-  // Remove once we drop support for Safari 14.
-  // stylelint-disable-next-line property-disallowed-list
-  border-bottom-right-radius: 0;
   border-end-end-radius: 0;
   border-end-end-radius: 0;
   background-color: $draftail-editor-background;
   background-color: $draftail-editor-background;
   color: $draftail-placeholder-text;
   color: $draftail-placeholder-text;

+ 68 - 58
client/src/components/Sidebar/Sidebar.stories.tsx

@@ -8,6 +8,7 @@ import { LinkMenuItemDefinition } from './menu/LinkMenuItem';
 import { SubMenuItemDefinition } from './menu/SubMenuItem';
 import { SubMenuItemDefinition } from './menu/SubMenuItem';
 import { WagtailBrandingModuleDefinition } from './modules/WagtailBranding';
 import { WagtailBrandingModuleDefinition } from './modules/WagtailBranding';
 import { range } from '../../utils/range';
 import { range } from '../../utils/range';
+import { MenuItemDefinition } from './menu/MenuItem';
 
 
 export default {
 export default {
   title: 'Sidebar/Sidebar',
   title: 'Sidebar/Sidebar',
@@ -27,7 +28,7 @@ function bogStandardMenuModule(): MainMenuModuleDefinition {
           label: 'Pages',
           label: 'Pages',
           url: '/admin/pages',
           url: '/admin/pages',
           icon_name: 'folder-open-inverse',
           icon_name: 'folder-open-inverse',
-          classnames: '',
+          classname: '',
         },
         },
         1,
         1,
       ),
       ),
@@ -36,35 +37,35 @@ function bogStandardMenuModule(): MainMenuModuleDefinition {
         label: 'Images',
         label: 'Images',
         url: '/admin/images/',
         url: '/admin/images/',
         icon_name: 'image',
         icon_name: 'image',
-        classnames: '',
+        classname: '',
       }),
       }),
       new LinkMenuItemDefinition({
       new LinkMenuItemDefinition({
         name: 'documents',
         name: 'documents',
         label: 'Documents',
         label: 'Documents',
         url: '/admin/documents/',
         url: '/admin/documents/',
         icon_name: 'doc-full-inverse',
         icon_name: 'doc-full-inverse',
-        classnames: '',
+        classname: '',
       }),
       }),
       new LinkMenuItemDefinition({
       new LinkMenuItemDefinition({
         name: 'snippets',
         name: 'snippets',
         label: 'Snippets',
         label: 'Snippets',
         url: '/admin/snippets/',
         url: '/admin/snippets/',
         icon_name: 'snippet',
         icon_name: 'snippet',
-        classnames: '',
+        classname: '',
       }),
       }),
       new LinkMenuItemDefinition({
       new LinkMenuItemDefinition({
         name: 'forms',
         name: 'forms',
         label: 'Forms',
         label: 'Forms',
         url: '/admin/forms/',
         url: '/admin/forms/',
         icon_name: 'form',
         icon_name: 'form',
-        classnames: '',
+        classname: '',
       }),
       }),
       new SubMenuItemDefinition(
       new SubMenuItemDefinition(
         {
         {
           name: 'reports',
           name: 'reports',
           label: 'Reports',
           label: 'Reports',
           icon_name: 'site',
           icon_name: 'site',
-          classnames: '',
+          classname: '',
         },
         },
         [
         [
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
@@ -72,28 +73,28 @@ function bogStandardMenuModule(): MainMenuModuleDefinition {
             label: 'Locked pages',
             label: 'Locked pages',
             url: '/admin/reports/locked/',
             url: '/admin/reports/locked/',
             icon_name: 'lock',
             icon_name: 'lock',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'workflows',
             name: 'workflows',
             label: 'Workflows',
             label: 'Workflows',
             url: '/admin/reports/workflow/',
             url: '/admin/reports/workflow/',
             icon_name: 'tasks',
             icon_name: 'tasks',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'workflow-tasks',
             name: 'workflow-tasks',
             label: 'Workflow tasks',
             label: 'Workflow tasks',
             url: '/admin/reports/workflow_tasks/',
             url: '/admin/reports/workflow_tasks/',
             icon_name: 'thumbtack',
             icon_name: 'thumbtack',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'site-history',
             name: 'site-history',
             label: 'Site history',
             label: 'Site history',
             url: '/admin/reports/site-history/',
             url: '/admin/reports/site-history/',
             icon_name: 'history',
             icon_name: 'history',
-            classnames: '',
+            classname: '',
           }),
           }),
         ],
         ],
       ),
       ),
@@ -102,7 +103,7 @@ function bogStandardMenuModule(): MainMenuModuleDefinition {
           name: 'settings',
           name: 'settings',
           label: 'Settings',
           label: 'Settings',
           icon_name: 'cogs',
           icon_name: 'cogs',
-          classnames: '',
+          classname: '',
           footer_text: 'Wagtail Version',
           footer_text: 'Wagtail Version',
         },
         },
         [
         [
@@ -111,49 +112,49 @@ function bogStandardMenuModule(): MainMenuModuleDefinition {
             label: 'Workflows',
             label: 'Workflows',
             url: '/admin/workflows/list/',
             url: '/admin/workflows/list/',
             icon_name: 'tasks',
             icon_name: 'tasks',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'workflow-tasks',
             name: 'workflow-tasks',
             label: 'Workflow tasks',
             label: 'Workflow tasks',
             url: '/admin/workflows/tasks/index/',
             url: '/admin/workflows/tasks/index/',
             icon_name: 'thumbtack',
             icon_name: 'thumbtack',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'users',
             name: 'users',
             label: 'Users',
             label: 'Users',
             url: '/admin/users/',
             url: '/admin/users/',
             icon_name: 'user',
             icon_name: 'user',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'groups',
             name: 'groups',
             label: 'Groups',
             label: 'Groups',
             url: '/admin/groups/',
             url: '/admin/groups/',
             icon_name: 'group',
             icon_name: 'group',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'sites',
             name: 'sites',
             label: 'Sites',
             label: 'Sites',
             url: '/admin/sites/',
             url: '/admin/sites/',
             icon_name: 'site',
             icon_name: 'site',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'collections',
             name: 'collections',
             label: 'Collections',
             label: 'Collections',
             url: '/admin/collections/',
             url: '/admin/collections/',
             icon_name: 'folder-open-1',
             icon_name: 'folder-open-1',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'redirects',
             name: 'redirects',
             label: 'Redirects',
             label: 'Redirects',
             url: '/admin/redirects/',
             url: '/admin/redirects/',
             icon_name: 'redirect',
             icon_name: 'redirect',
-            classnames: '',
+            classname: '',
           }),
           }),
         ],
         ],
       ),
       ),
@@ -164,14 +165,14 @@ function bogStandardMenuModule(): MainMenuModuleDefinition {
         label: 'Account',
         label: 'Account',
         url: '/admin/account/',
         url: '/admin/account/',
         icon_name: 'user',
         icon_name: 'user',
-        classnames: '',
+        classname: '',
       }),
       }),
       new LinkMenuItemDefinition({
       new LinkMenuItemDefinition({
         name: 'logout',
         name: 'logout',
         label: 'Log out',
         label: 'Log out',
         url: '/admin/logout/',
         url: '/admin/logout/',
         icon_name: 'logout',
         icon_name: 'logout',
-        classnames: '',
+        classname: '',
       }),
       }),
     ],
     ],
     {
     {
@@ -218,6 +219,13 @@ function renderSidebarStory(
     document.documentElement.setAttribute('dir', 'ltr');
     document.documentElement.setAttribute('dir', 'ltr');
   }
   }
 
 
+  React.useEffect(
+    () => () => {
+      document.documentElement.removeAttribute('dir');
+    },
+    [],
+  );
+
   return (
   return (
     <div className="wrapper">
     <div className="wrapper">
       <Sidebar
       <Sidebar
@@ -249,7 +257,7 @@ export function withNestedSubmenu() {
         name: 'nested-menu',
         name: 'nested-menu',
         label: 'Nested menu',
         label: 'Nested menu',
         icon_name: 'cogs',
         icon_name: 'cogs',
-        classnames: '',
+        classname: '',
       },
       },
       [
       [
         new LinkMenuItemDefinition({
         new LinkMenuItemDefinition({
@@ -257,14 +265,14 @@ export function withNestedSubmenu() {
           label: 'Item',
           label: 'Item',
           url: '/admin/item/',
           url: '/admin/item/',
           icon_name: 'user',
           icon_name: 'user',
-          classnames: '',
+          classname: '',
         }),
         }),
         new SubMenuItemDefinition(
         new SubMenuItemDefinition(
           {
           {
             name: 'nested-menu',
             name: 'nested-menu',
             label: 'Nested menu',
             label: 'Nested menu',
             icon_name: 'folder-open-1',
             icon_name: 'folder-open-1',
-            classnames: '',
+            classname: '',
           },
           },
           [
           [
             new LinkMenuItemDefinition({
             new LinkMenuItemDefinition({
@@ -272,14 +280,14 @@ export function withNestedSubmenu() {
               label: 'Item',
               label: 'Item',
               url: '/admin/item/item/',
               url: '/admin/item/item/',
               icon_name: 'user',
               icon_name: 'user',
-              classnames: '',
+              classname: '',
             }),
             }),
             new SubMenuItemDefinition(
             new SubMenuItemDefinition(
               {
               {
                 name: 'deeply-nested-menu',
                 name: 'deeply-nested-menu',
                 label: 'Deeply nested menu',
                 label: 'Deeply nested menu',
                 icon_name: 'side',
                 icon_name: 'side',
-                classnames: '',
+                classname: '',
               },
               },
               [
               [
                 new LinkMenuItemDefinition({
                 new LinkMenuItemDefinition({
@@ -287,7 +295,7 @@ export function withNestedSubmenu() {
                   label: 'Item',
                   label: 'Item',
                   url: '/admin/item/item/item/',
                   url: '/admin/item/item/item/',
                   icon_name: 'user',
                   icon_name: 'user',
-                  classnames: '',
+                  classname: '',
                 }),
                 }),
               ],
               ],
             ),
             ),
@@ -296,7 +304,7 @@ export function withNestedSubmenu() {
                 name: 'another-deeply-nested-menu',
                 name: 'another-deeply-nested-menu',
                 label: 'Another deeply nested menu',
                 label: 'Another deeply nested menu',
                 icon_name: 'user',
                 icon_name: 'user',
-                classnames: '',
+                classname: '',
               },
               },
               [
               [
                 new LinkMenuItemDefinition({
                 new LinkMenuItemDefinition({
@@ -304,7 +312,7 @@ export function withNestedSubmenu() {
                   label: 'Item',
                   label: 'Item',
                   url: '/admin/item/item/item2/',
                   url: '/admin/item/item/item2/',
                   icon_name: 'user',
                   icon_name: 'user',
-                  classnames: '',
+                  classname: '',
                 }),
                 }),
               ],
               ],
             ),
             ),
@@ -320,7 +328,7 @@ export function withNestedSubmenu() {
 export function withLargeSubmenu() {
 export function withLargeSubmenu() {
   const menuModule = bogStandardMenuModule();
   const menuModule = bogStandardMenuModule();
 
 
-  const menuItems = [];
+  const menuItems: MenuItemDefinition[] = [];
   range(0, 100).forEach((i) => {
   range(0, 100).forEach((i) => {
     menuItems.push(
     menuItems.push(
       new LinkMenuItemDefinition({
       new LinkMenuItemDefinition({
@@ -328,7 +336,7 @@ export function withLargeSubmenu() {
         label: `Item ${i}`,
         label: `Item ${i}`,
         url: `/admin/item-${i}/`,
         url: `/admin/item-${i}/`,
         icon_name: 'snippet',
         icon_name: 'snippet',
-        classnames: '',
+        classname: '',
       }),
       }),
     );
     );
   });
   });
@@ -339,7 +347,7 @@ export function withLargeSubmenu() {
         name: 'large-menu',
         name: 'large-menu',
         label: 'Large menu',
         label: 'Large menu',
         icon_name: 'cogs',
         icon_name: 'cogs',
-        classnames: '',
+        classname: '',
         footer_text: 'Footer text',
         footer_text: 'Footer text',
       },
       },
       menuItems,
       menuItems,
@@ -356,48 +364,50 @@ export function withoutSearch() {
 function arabicMenuModule(): MainMenuModuleDefinition {
 function arabicMenuModule(): MainMenuModuleDefinition {
   return new MainMenuModuleDefinition(
   return new MainMenuModuleDefinition(
     [
     [
-      new PageExplorerMenuItemDefinition({
-        name: 'explorer',
-        label: 'صفحات',
-        url: '/admin/pages',
-        start_page_id: 1,
-        icon_name: 'folder-open-inverse',
-        classnames: '',
-      }),
+      new PageExplorerMenuItemDefinition(
+        {
+          name: 'explorer',
+          label: 'صفحات',
+          url: '/admin/pages',
+          icon_name: 'folder-open-inverse',
+          classname: '',
+        },
+        1,
+      ),
       new LinkMenuItemDefinition({
       new LinkMenuItemDefinition({
         name: 'images',
         name: 'images',
         label: 'صور',
         label: 'صور',
         url: '/admin/images/',
         url: '/admin/images/',
         icon_name: 'image',
         icon_name: 'image',
-        classnames: '',
+        classname: '',
       }),
       }),
       new LinkMenuItemDefinition({
       new LinkMenuItemDefinition({
         name: 'documents',
         name: 'documents',
         label: 'وثائق',
         label: 'وثائق',
         url: '/admin/documents/',
         url: '/admin/documents/',
         icon_name: 'doc-full-inverse',
         icon_name: 'doc-full-inverse',
-        classnames: '',
+        classname: '',
       }),
       }),
       new LinkMenuItemDefinition({
       new LinkMenuItemDefinition({
         name: 'snippets',
         name: 'snippets',
         label: 'قصاصات',
         label: 'قصاصات',
         url: '/admin/snippets/',
         url: '/admin/snippets/',
         icon_name: 'snippet',
         icon_name: 'snippet',
-        classnames: '',
+        classname: '',
       }),
       }),
       new LinkMenuItemDefinition({
       new LinkMenuItemDefinition({
         name: 'forms',
         name: 'forms',
         label: 'نماذج',
         label: 'نماذج',
         url: '/admin/forms/',
         url: '/admin/forms/',
         icon_name: 'form',
         icon_name: 'form',
-        classnames: '',
+        classname: '',
       }),
       }),
       new SubMenuItemDefinition(
       new SubMenuItemDefinition(
         {
         {
           name: 'reports',
           name: 'reports',
           label: 'التقارير',
           label: 'التقارير',
           icon_name: 'site',
           icon_name: 'site',
-          classnames: '',
+          classname: '',
         },
         },
         [
         [
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
@@ -405,28 +415,28 @@ function arabicMenuModule(): MainMenuModuleDefinition {
             label: 'Locked pages',
             label: 'Locked pages',
             url: '/admin/reports/locked/',
             url: '/admin/reports/locked/',
             icon_name: 'lock',
             icon_name: 'lock',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'workflows',
             name: 'workflows',
             label: 'Workflows',
             label: 'Workflows',
             url: '/admin/reports/workflow/',
             url: '/admin/reports/workflow/',
             icon_name: 'tasks',
             icon_name: 'tasks',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'workflow-tasks',
             name: 'workflow-tasks',
             label: 'Workflow tasks',
             label: 'Workflow tasks',
             url: '/admin/reports/workflow_tasks/',
             url: '/admin/reports/workflow_tasks/',
             icon_name: 'thumbtack',
             icon_name: 'thumbtack',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'site-history',
             name: 'site-history',
             label: 'Site history',
             label: 'Site history',
             url: '/admin/reports/site-history/',
             url: '/admin/reports/site-history/',
             icon_name: 'history',
             icon_name: 'history',
-            classnames: '',
+            classname: '',
           }),
           }),
         ],
         ],
       ),
       ),
@@ -435,7 +445,7 @@ function arabicMenuModule(): MainMenuModuleDefinition {
           name: 'settings',
           name: 'settings',
           label: 'إعدادات',
           label: 'إعدادات',
           icon_name: 'cogs',
           icon_name: 'cogs',
-          classnames: '',
+          classname: '',
         },
         },
         [
         [
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
@@ -443,49 +453,49 @@ function arabicMenuModule(): MainMenuModuleDefinition {
             label: 'Workflows',
             label: 'Workflows',
             url: '/admin/workflows/list/',
             url: '/admin/workflows/list/',
             icon_name: 'tasks',
             icon_name: 'tasks',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'workflow-tasks',
             name: 'workflow-tasks',
             label: 'Workflow tasks',
             label: 'Workflow tasks',
             url: '/admin/workflows/tasks/index/',
             url: '/admin/workflows/tasks/index/',
             icon_name: 'thumbtack',
             icon_name: 'thumbtack',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'users',
             name: 'users',
             label: 'مستخدمين',
             label: 'مستخدمين',
             url: '/admin/users/',
             url: '/admin/users/',
             icon_name: 'user',
             icon_name: 'user',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'groups',
             name: 'groups',
             label: 'مجموعات',
             label: 'مجموعات',
             url: '/admin/groups/',
             url: '/admin/groups/',
             icon_name: 'group',
             icon_name: 'group',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'sites',
             name: 'sites',
             label: 'مواقع',
             label: 'مواقع',
             url: '/admin/sites/',
             url: '/admin/sites/',
             icon_name: 'site',
             icon_name: 'site',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'collections',
             name: 'collections',
             label: 'مجموعات',
             label: 'مجموعات',
             url: '/admin/collections/',
             url: '/admin/collections/',
             icon_name: 'folder-open-1',
             icon_name: 'folder-open-1',
-            classnames: '',
+            classname: '',
           }),
           }),
           new LinkMenuItemDefinition({
           new LinkMenuItemDefinition({
             name: 'redirects',
             name: 'redirects',
             label: 'اعادة التوجيهات',
             label: 'اعادة التوجيهات',
             url: '/admin/redirects/',
             url: '/admin/redirects/',
             icon_name: 'redirect',
             icon_name: 'redirect',
-            classnames: '',
+            classname: '',
           }),
           }),
         ],
         ],
       ),
       ),
@@ -496,14 +506,14 @@ function arabicMenuModule(): MainMenuModuleDefinition {
         label: 'حساب',
         label: 'حساب',
         url: '/admin/account/',
         url: '/admin/account/',
         icon_name: 'user',
         icon_name: 'user',
-        classnames: '',
+        classname: '',
       }),
       }),
       new LinkMenuItemDefinition({
       new LinkMenuItemDefinition({
         name: 'logout',
         name: 'logout',
         label: 'تسجيل الخروج',
         label: 'تسجيل الخروج',
         url: '/admin/logout/',
         url: '/admin/logout/',
         icon_name: 'logout',
         icon_name: 'logout',
-        classnames: '',
+        classname: '',
       }),
       }),
     ],
     ],
     {
     {

+ 1 - 1
client/src/components/Sidebar/menu/ActionMenuItem.tsx

@@ -81,7 +81,7 @@ export class ActionMenuItemDefinition implements MenuItemDefinition {
     name,
     name,
     label,
     label,
     action,
     action,
-    attrs,
+    attrs = {},
     icon_name: iconName = null,
     icon_name: iconName = null,
     classname = undefined,
     classname = undefined,
     method = 'POST',
     method = 'POST',

+ 3 - 3
client/src/components/Sidebar/menu/LinkMenuItem.tsx

@@ -96,9 +96,9 @@ export class LinkMenuItemDefinition implements MenuItemDefinition {
     name,
     name,
     label,
     label,
     url,
     url,
-    attrs,
-    icon_name: iconName = null,
-    classname = undefined,
+    attrs = {},
+    icon_name: iconName = null as string | null,
+    classname = undefined as string | undefined,
   }) {
   }) {
     this.name = name;
     this.name = name;
     this.label = label;
     this.label = label;

+ 3 - 3
client/src/components/Sidebar/menu/PageExplorerMenuItem.tsx

@@ -120,9 +120,9 @@ export class PageExplorerMenuItemDefinition extends LinkMenuItemDefinition {
       name,
       name,
       label,
       label,
       url,
       url,
-      attrs,
-      icon_name: iconName = null,
-      classname = undefined,
+      attrs = {},
+      icon_name: iconName = null as string | null,
+      classname = undefined as string | undefined,
     },
     },
     startPageId: number,
     startPageId: number,
   ) {
   ) {

+ 1 - 1
client/src/components/Sidebar/menu/SubMenuItem.tsx

@@ -168,7 +168,7 @@ export class SubMenuItemDefinition implements MenuItemDefinition {
     {
     {
       name,
       name,
       label,
       label,
-      attrs,
+      attrs = {},
       icon_name: iconName = null,
       icon_name: iconName = null,
       classname = undefined,
       classname = undefined,
       footer_text: footerText = '',
       footer_text: footerText = '',

+ 11 - 8
client/storybook/main.js

@@ -2,18 +2,16 @@ module.exports = {
   stories: [
   stories: [
     '../../client/**/*.stories.mdx',
     '../../client/**/*.stories.mdx',
     '../../client/**/*.stories.@(js|tsx)',
     '../../client/**/*.stories.@(js|tsx)',
-    {
-      directory: '../../wagtail/admin/templates/wagtailadmin/shared/',
-      titlePrefix: 'Shared',
-      files: '**/*.stories.*',
-    },
     '../../wagtail/**/*.stories.*',
     '../../wagtail/**/*.stories.*',
   ],
   ],
+
   addons: ['@storybook/addon-docs', '@storybook/addon-controls'],
   addons: ['@storybook/addon-docs', '@storybook/addon-controls'],
-  framework: '@storybook/react',
-  core: {
-    builder: 'webpack5',
+
+  framework: {
+    name: '@storybook/react-webpack5',
+    options: {},
   },
   },
+
   // Redefine Babel config to allow TypeScript class fields `declare`.
   // Redefine Babel config to allow TypeScript class fields `declare`.
   // See https://github.com/storybookjs/storybook/issues/12479.
   // See https://github.com/storybookjs/storybook/issues/12479.
   // The resulting configuration is closer to Wagtail’s Webpack + TypeScript setup,
   // The resulting configuration is closer to Wagtail’s Webpack + TypeScript setup,
@@ -26,6 +24,7 @@ module.exports = {
       ['@babel/preset-react', { runtime: 'automatic' }],
       ['@babel/preset-react', { runtime: 'automatic' }],
     ],
     ],
   }),
   }),
+
   webpackFinal: (config) => {
   webpackFinal: (config) => {
     /* eslint-disable no-param-reassign */
     /* eslint-disable no-param-reassign */
 
 
@@ -67,4 +66,8 @@ module.exports = {
 
 
     return config;
     return config;
   },
   },
+
+  docs: {
+    autodocs: true,
+  },
 };
 };

+ 1 - 8
docs/contributing/developing.md

@@ -216,14 +216,7 @@ Wagtail is meant to be used on a wide variety of devices and browsers. Supported
 | Firefox ESR   | Desktop    | Latest     |
 | Firefox ESR   | Desktop    | Latest     |
 | Safari        | macOS      | Last 3     |
 | Safari        | macOS      | Last 3     |
 
 
-We aim for Wagtail to work in those environments, there are known support gaps for Safari 13 introduced in Wagtail 4.0 to provide better support for RTL languages. Our development standards ensure that the site is usable on other browsers **and will work on future browsers**.
-
-IE 11 support has been officially dropped in 2.15 as it is gradually falling out of use. Features already known not to work include:
-
--   Rich text copy-paste in the rich text editor.
--   Sticky toolbar in the rich text editor.
--   Focus outline styles in the main menu & explorer menu.
--   Keyboard access to the actions in page listing tables.
+We aim for Wagtail to work in those environments. Our development standards ensure that the site is usable on other browsers **and will work on future browsers**.
 
 
 **Unsupported browsers / devices include:**
 **Unsupported browsers / devices include:**
 
 

文件差异内容过多而无法显示
+ 369 - 274
package-lock.json


+ 14 - 9
package.json

@@ -14,7 +14,8 @@
     "last 1 Firefox version",
     "last 1 Firefox version",
     "last 2 iOS versions",
     "last 2 iOS versions",
     "last 3 Safari versions",
     "last 3 Safari versions",
-    "not safari 13",
+    "iOS >= 16",
+    "Safari 15",
     "not ie 11"
     "not ie 11"
   ],
   ],
   "jest": {
   "jest": {
@@ -56,11 +57,13 @@
   },
   },
   "devDependencies": {
   "devDependencies": {
     "@babel/core": "^7.16.7",
     "@babel/core": "^7.16.7",
-    "@storybook/addon-controls": "^6.4.19",
-    "@storybook/addon-docs": "^6.4.19",
-    "@storybook/builder-webpack5": "^6.4.19",
-    "@storybook/manager-webpack5": "^6.4.19",
-    "@storybook/react": "^6.4.19",
+    "@babel/preset-env": "^7.23.3",
+    "@babel/preset-react": "^7.23.3",
+    "@babel/preset-typescript": "^7.23.3",
+    "@storybook/addon-controls": "^7.5.3",
+    "@storybook/addon-docs": "^7.5.3",
+    "@storybook/react": "^7.5.3",
+    "@storybook/react-webpack5": "^7.5.3",
     "@types/autosize": "^4.0.1",
     "@types/autosize": "^4.0.1",
     "@types/draft-js": "^0.10.45",
     "@types/draft-js": "^0.10.45",
     "@types/jest": "^29.5.3",
     "@types/jest": "^29.5.3",
@@ -81,6 +84,7 @@
     "enzyme-adapter-react-16": "^1.15.7",
     "enzyme-adapter-react-16": "^1.15.7",
     "enzyme-to-json": "^3.6.2",
     "enzyme-to-json": "^3.6.2",
     "eslint": "^8.46.0",
     "eslint": "^8.46.0",
+    "eslint-plugin-storybook": "^0.6.15",
     "expose-loader": "^3.1.0",
     "expose-loader": "^3.1.0",
     "gettext-extractor": "^3.5.3",
     "gettext-extractor": "^3.5.3",
     "jest": "^29.6.2",
     "jest": "^29.6.2",
@@ -93,13 +97,14 @@
     "redux-mock-store": "^1.3.0",
     "redux-mock-store": "^1.3.0",
     "sass": "^1.45.1",
     "sass": "^1.45.1",
     "sass-loader": "^12.4.0",
     "sass-loader": "^12.4.0",
+    "storybook": "^7.5.3",
     "storybook-django": "^0.5.1",
     "storybook-django": "^0.5.1",
     "stylelint": "^15.10.0",
     "stylelint": "^15.10.0",
     "tailwindcss": "^3.1.5",
     "tailwindcss": "^3.1.5",
     "tailwindcss-vanilla-rtl": "^0.2.0",
     "tailwindcss-vanilla-rtl": "^0.2.0",
     "ts-jest": "^29.1.0",
     "ts-jest": "^29.1.0",
     "ts-loader": "^9.2.6",
     "ts-loader": "^9.2.6",
-    "typescript": "^4.5.4",
+    "typescript": "^5.2.2",
     "webpack": "^5.76.0",
     "webpack": "^5.76.0",
     "webpack-cli": "^4.9.1"
     "webpack-cli": "^4.9.1"
   },
   },
@@ -145,7 +150,7 @@
     "test:unit:watch": "jest --watch",
     "test:unit:watch": "jest --watch",
     "test:unit:coverage": "jest --coverage",
     "test:unit:coverage": "jest --coverage",
     "test:integration": "./client/tests/integration/node_modules/.bin/jest --config ./client/tests/integration/jest.config.js",
     "test:integration": "./client/tests/integration/node_modules/.bin/jest --config ./client/tests/integration/jest.config.js",
-    "storybook": "start-storybook -c client/storybook -p 6006 --no-open --no-version-updates --no-release-notes --quiet --modern",
-    "build-storybook": "build-storybook -c client/storybook --modern"
+    "storybook": "storybook dev -c client/storybook -p 6006 --no-open --no-version-updates",
+    "build-storybook": "storybook build -c client/storybook"
   }
   }
 }
 }

+ 2 - 2
tsconfig.json

@@ -5,14 +5,14 @@
     "esModuleInterop": true,
     "esModuleInterop": true,
     "forceConsistentCasingInFileNames": true,
     "forceConsistentCasingInFileNames": true,
     "jsx": "react",
     "jsx": "react",
-    "lib": ["ES2021", "DOM", "DOM.iterable"],
+    "lib": ["ES2022", "DOM", "DOM.iterable"],
     "moduleResolution": "node",
     "moduleResolution": "node",
     "noImplicitAny": false, // TODO: Enable once all existing code is typed
     "noImplicitAny": false, // TODO: Enable once all existing code is typed
     "noUnusedLocals": true,
     "noUnusedLocals": true,
     "noUnusedParameters": true,
     "noUnusedParameters": true,
     "strictNullChecks": true,
     "strictNullChecks": true,
     "strictPropertyInitialization": true,
     "strictPropertyInitialization": true,
-    "target": "ES2021" // Since lowest browser support is for Safari 14
+    "target": "ES2022"
   },
   },
   "files": [
   "files": [
     "client/src/index.ts",
     "client/src/index.ts",

+ 1 - 0
wagtail/admin/templates/wagtailadmin/shared/avatar.stories.tsx

@@ -6,6 +6,7 @@ import template from './avatar.html';
 const { docs, argTypes } = generateDocs(template);
 const { docs, argTypes } = generateDocs(template);
 
 
 export default {
 export default {
+  title: 'Shared / Avatar',
   parameters: {
   parameters: {
     docs,
     docs,
   },
   },

+ 1 - 0
wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.stories.tsx

@@ -9,6 +9,7 @@ import template from './breadcrumbs.html';
 const { docs, argTypes } = generateDocs(template);
 const { docs, argTypes } = generateDocs(template);
 
 
 export default {
 export default {
+  title: 'Shared / Breadcrumbs',
   parameters: { docs },
   parameters: { docs },
   argTypes: { ...argTypes },
   argTypes: { ...argTypes },
 };
 };

+ 1 - 0
wagtail/admin/templates/wagtailadmin/shared/dropdown/dropdown.stories.tsx

@@ -9,6 +9,7 @@ import template from './dropdown.html';
 const { docs, argTypes } = generateDocs(template);
 const { docs, argTypes } = generateDocs(template);
 
 
 export default {
 export default {
+  title: 'Shared / Dropdown',
   parameters: {
   parameters: {
     docs,
     docs,
   },
   },

+ 1 - 0
wagtail/admin/templates/wagtailadmin/shared/header.stories.tsx

@@ -6,6 +6,7 @@ import template from './header.html';
 const { docs, argTypes } = generateDocs(template);
 const { docs, argTypes } = generateDocs(template);
 
 
 export default {
 export default {
+  title: 'Shared / Header',
   parameters: {
   parameters: {
     docs,
     docs,
   },
   },

+ 1 - 0
wagtail/admin/templates/wagtailadmin/shared/help_block.stories.tsx

@@ -6,6 +6,7 @@ import template from './help_block.html';
 const { docs, argTypes } = generateDocs(template);
 const { docs, argTypes } = generateDocs(template);
 
 
 export default {
 export default {
+  title: 'Shared / Help Block',
   parameters: { docs },
   parameters: { docs },
   argTypes: { ...argTypes },
   argTypes: { ...argTypes },
 };
 };

+ 1 - 0
wagtail/admin/templates/wagtailadmin/shared/page_breadcrumbs.stories.tsx

@@ -9,6 +9,7 @@ import template from './page_breadcrumbs.html';
 const { docs, argTypes } = generateDocs(template);
 const { docs, argTypes } = generateDocs(template);
 
 
 export default {
 export default {
+  title: 'Shared / Page Breadcrumbs',
   parameters: { docs },
   parameters: { docs },
   argTypes: { ...argTypes },
   argTypes: { ...argTypes },
 };
 };

+ 1 - 0
wagtail/admin/templates/wagtailadmin/shared/status_tag.stories.tsx

@@ -6,6 +6,7 @@ import template from './status_tag.html';
 const { docs, argTypes } = generateDocs(template);
 const { docs, argTypes } = generateDocs(template);
 
 
 export default {
 export default {
+  title: 'Shared / Status Tag',
   parameters: { docs },
   parameters: { docs },
   argTypes: {
   argTypes: {
     ...argTypes,
     ...argTypes,

部分文件因为文件数量过多而无法显示