Просмотр исходного кода

Merge pull request #8524 from weseek/feat/139307-140753-replacement-simple-line-icon-all

feat: Replace simple line icon with Material Symbols Outlined
Yuki Takei 2 лет назад
Родитель
Сommit
07f9524bd0
39 измененных файлов с 72 добавлено и 65 удалено
  1. 1 1
      apps/app/public/static/locales/en_US/admin.json
  2. 1 1
      apps/app/public/static/locales/ja_JP/admin.json
  3. 1 1
      apps/app/public/static/locales/zh_CN/admin.json
  4. 5 1
      apps/app/src/components/Admin/Security/SamlSecuritySettingContents.jsx
  5. 1 1
      apps/app/src/components/Admin/Security/SecurityManagementContents.jsx
  6. 2 2
      apps/app/src/components/Admin/Security/SecuritySetting.jsx
  7. 9 3
      apps/app/src/components/Admin/SlackIntegration/Bridge.jsx
  8. 1 1
      apps/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxySettingsAccordion.jsx
  9. 1 1
      apps/app/src/components/Admin/SlackIntegration/WithProxyAccordions.jsx
  10. 1 1
      apps/app/src/components/Admin/UserGroup/UserGroupTable.tsx
  11. 1 1
      apps/app/src/components/Admin/UserGroupDetail/UpdateParentConfirmModal.tsx
  12. 1 1
      apps/app/src/components/Admin/UserGroupDetail/UserGroupUserTable.tsx
  13. 1 1
      apps/app/src/components/Admin/UserManagement.module.scss
  14. 4 3
      apps/app/src/components/Admin/UserManagement.tsx
  15. 1 1
      apps/app/src/components/Admin/Users/ExternalAccountTable.tsx
  16. 2 1
      apps/app/src/components/Admin/Users/UserMenu.tsx
  17. 1 1
      apps/app/src/components/Bookmarks/BookmarkFolderItemControl.tsx
  18. 0 4
      apps/app/src/components/Bookmarks/BookmarkFolderTree.module.scss
  19. 1 1
      apps/app/src/components/Bookmarks/BookmarkItem.tsx
  20. 3 2
      apps/app/src/components/Common/PagePathHierarchicalLink/PagePathHierarchicalLink.tsx
  21. 4 2
      apps/app/src/components/ExpandOrContractButton.tsx
  22. 0 5
      apps/app/src/components/ItemsTree/ItemsTree.module.scss
  23. 1 1
      apps/app/src/components/Me/ExternalAccountLinkedMe.jsx
  24. 2 2
      apps/app/src/components/PageAttachment/DeleteAttachmentModal.tsx
  25. 3 3
      apps/app/src/components/PageComment/CommentEditor.tsx
  26. 2 2
      apps/app/src/components/PageComment/ReplyComments.tsx
  27. 1 1
      apps/app/src/components/PageControls/PageControls.tsx
  28. 1 1
      apps/app/src/components/PageEditor/Editor.tsx
  29. 2 1
      apps/app/src/components/PagePresentationModal.tsx
  30. 5 5
      apps/app/src/components/SavePageControls/GrantSelector/GrantSelector.tsx
  31. 3 2
      apps/app/src/components/Sidebar/PageTree/PrivateLegacyPagesLink.tsx
  32. 1 1
      apps/app/src/components/Sidebar/PageTreeItem/Ellipsis.tsx
  33. 1 1
      apps/app/src/components/Sidebar/SidebarHeaderReloadButton.tsx
  34. 1 1
      apps/app/src/components/TreeItem/NewPageInput/NewPageCreateButton.tsx
  35. 1 2
      apps/app/src/components/User/UserInfo.tsx
  36. 1 1
      apps/app/src/features/growi-plugin/client/components/Admin/PluginsExtensionPageContents/PluginsExtensionPageContents.tsx
  37. 1 1
      apps/app/src/pages/installer.page.tsx
  38. 2 2
      packages/ui/src/components/Attachment.tsx
  39. 2 2
      packages/ui/src/components/PagePath/PageListMeta.tsx

+ 1 - 1
apps/app/public/static/locales/en_US/admin.json

@@ -746,7 +746,7 @@
       "description1":"Temporarily issue new users by email addresses.",
       "description2":"A temporary password will be generated for the first login.",
       "invite_thru_email": "Send invitation email",
-      "mail_setting_link":"<i class='icon-settings me-2'></i><a href='/admin/app'>Email settings</a>",
+      "mail_setting_link":"<span className='material-symbols-outlined me-2'>settings</span><a href='/admin/app'>Email settings</a>",
       "valid_email": "Valid email address is required",
       "temporary_password": "The created user has a temporary password",
       "send_new_password": "Please send the new password to the user.",

+ 1 - 1
apps/app/public/static/locales/ja_JP/admin.json

@@ -756,7 +756,7 @@
       "description1": "メールアドレスを使用して新規ユーザーを仮発行します。",
       "description2": "初回のログイン時に使用する仮パスワードが生成されます。",
       "invite_thru_email": "招待メールを送信する",
-      "mail_setting_link": "<i class='icon-settings me-2'></i><a href='/admin/app'>メールの設定</a>",
+      "mail_setting_link": "<span className='material-symbols-outlined me-2'>settings</span><a href='/admin/app'>メールの設定</a>",
       "valid_email": "メールアドレスを入力してください。",
       "temporary_password": "作成したユーザーは仮パスワードが設定されています。",
       "send_new_password": "新規発行したパスワードを、対象ユーザーへ連絡してください。",

+ 1 - 1
apps/app/public/static/locales/zh_CN/admin.json

@@ -754,7 +754,7 @@
       "emails": "电子邮件",
       "description1": "通过电子邮件地址临时发布新用户。",
       "description2": "将为首次登录生成一个临时密码。",
-      "mail_setting_link": "<i class='icon-settings me-2'></i><a href='/admin/app'>Email settings</a>",
+      "mail_setting_link": "<span className='material-symbols-outlined me-2'>settings</span><a href='/admin/app'>Email settings</a>",
       "valid_email": "需要有效的电子邮件地址",
       "invite_thru_email": "发送邀请电子邮件",
       "temporary_password": "创建的用户具有临时密码",

+ 5 - 1
apps/app/src/components/Admin/Security/SamlSecuritySettingContents.jsx

@@ -484,7 +484,11 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                               aria-expanded="true"
                               aria-controls="ablchelp"
                             >
-                              <i className={`icon-fw ${this.state.isHelpOpened ? 'icon-arrow-down' : 'icon-arrow-right'} small`}></i> Show more...
+                              <span
+                                className="material-symbols-outlined me-1"
+                                small
+                              >{this.state.isHelpOpened ? 'expand_more' : 'chevron_right'}
+                              </span> Show more...
                             </button>
                           </h2>
                           <Collapse isOpen={this.state.isHelpOpened}>

+ 1 - 1
apps/app/src/components/Admin/Security/SecurityManagementContents.jsx

@@ -81,7 +81,7 @@ const SecurityManagementContents = () => {
             href="/admin/markdown/#preventXSS"
             style={{ fontSize: 'large' }}
           >
-            <i className="fa-fw icon-login"></i> {t('security_settings.xss_prevent_setting_link')}
+            <span className="material-symbols-outlined me-1">login</span> {t('security_settings.xss_prevent_setting_link')}
           </Link>
         </div>
       </div>

+ 2 - 2
apps/app/src/components/Admin/Security/SecuritySetting.jsx

@@ -303,7 +303,7 @@ class SecuritySetting extends React.Component {
                     <div className="pb-4">
                       <p className="card custom-card">
                         <span className="text-warning">
-                          <i className="icon-info"></i>
+                          <span className="material-symbols-outlined">info</span>
                           {/* eslint-disable-next-line react/no-danger */}
                           <span dangerouslySetInnerHTML={{ __html: t('security_settings.page_delete_rights_caution') }} />
                         </span>
@@ -526,7 +526,7 @@ class SecuritySetting extends React.Component {
             <p className="form-text text-muted" dangerouslySetInnerHTML={{ __html: t('security_settings.max_age_desc') }} />
             <p className="card custom-card">
               <span className="text-warning">
-                <i className="icon-info"></i> {t('security_settings.max_age_caution')}
+                <span className="material-symbols-outlined">info</span> {t('security_settings.max_age_caution')}
               </span>
             </p>
           </div>

+ 9 - 3
apps/app/src/components/Admin/SlackIntegration/Bridge.jsx

@@ -15,14 +15,14 @@ const ProxyCircle = () => (
 
 const BridgeCore = (props) => {
   const {
-    description, iconClass, hrClass, withProxy,
+    description, iconClass, iconName, hrClass, withProxy,
   } = props;
 
   return (
     <>
       <div id="grw-bridge-container" className={`grw-bridge-container ${withProxy ? 'with-proxy' : ''}`}>
         <p className={`${withProxy ? 'mt-0' : 'mt-2'}`}>
-          <i className={iconClass} />
+          <span className={iconClass}>{iconName}</span>
           <small
             className="ms-2 d-none d-lg-inline"
             // eslint-disable-next-line react/no-danger
@@ -47,6 +47,7 @@ const BridgeCore = (props) => {
 BridgeCore.propTypes = {
   description: PropTypes.string.isRequired,
   iconClass: PropTypes.string.isRequired,
+  iconName: PropTypes.string.isRequired,
   hrClass: PropTypes.string.isRequired,
   withProxy: PropTypes.bool,
 };
@@ -58,24 +59,28 @@ const Bridge = (props) => {
 
   let description;
   let iconClass;
+  let iconName;
   let hrClass;
 
   // empty or all failed
   if (totalCount === 0 || errorCount === totalCount) {
     description = t('admin:slack_integration.integration_sentence.integration_is_not_complete');
-    iconClass = 'icon-info text-danger';
+    iconClass = 'material-symbols-outlined text-danger';
+    iconName = 'info';
     hrClass = 'border-danger admin-border-failed';
   }
   // all green
   else if (errorCount === 0) {
     description = t('admin:slack_integration.integration_sentence.integration_successful');
     iconClass = 'fa fa-check text-success';
+    iconName = '';
     hrClass = 'border-success admin-border-success';
   }
   // some of them failed
   else {
     description = t('admin:slack_integration.integration_sentence.integration_some_ws_is_not_complete');
     iconClass = 'fa fa-check text-warning';
+    iconName = '';
     hrClass = 'border-warning admin-border-failed';
   }
 
@@ -83,6 +88,7 @@ const Bridge = (props) => {
     <BridgeCore
       description={description}
       iconClass={iconClass}
+      iconName={iconName}
       hrClass={hrClass}
       withProxy={withProxy}
     />

+ 1 - 1
apps/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxySettingsAccordion.jsx

@@ -142,7 +142,7 @@ const CustomBotWithoutProxySettingsAccordion = (props) => {
       >
         <p className="text-center m-4">{t('admin:slack_integration.accordion.test_connection_by_pressing_button')}</p>
         <p className="text-center text-warning">
-          <i className="icon-info">{t('admin:slack_integration.accordion.test_connection_only_public_channel')}</i>
+          <span className="material-symbols-outlined">info</span>{t('admin:slack_integration.accordion.test_connection_only_public_channel')}
         </p>
         <div className="d-flex justify-content-center">
           <form className="align-items-center" onSubmit={e => submitForm(e)}>

+ 1 - 1
apps/app/src/components/Admin/SlackIntegration/WithProxyAccordions.jsx

@@ -240,7 +240,7 @@ const TestProcess = ({
     <>
       <p className="text-center m-4">{t('admin:slack_integration.accordion.test_connection_by_pressing_button')}</p>
       <p className="text-center text-warning">
-        <i className="icon-info">{t('admin:slack_integration.accordion.test_connection_only_public_channel')}</i>
+        <span className="material-symbols-outlined me-1">info</span>{t('admin:slack_integration.accordion.test_connection_only_public_channel')}
       </p>
       <div className="d-flex justify-content-center">
         <form className="justify-content-center" onSubmit={e => submitForm(e)}>

+ 1 - 1
apps/app/src/components/Admin/UserGroup/UserGroupTable.tsx

@@ -205,7 +205,7 @@ export const UserGroupTable: FC<Props> = ({
                           className="btn btn-outline-secondary btn-sm dropdown-toggle"
                           data-bs-toggle="dropdown"
                         >
-                          <i className="icon-settings"></i>
+                          <span className="material-symbols-outlined fs-5">settings</span>
                         </button>
                         <div className="dropdown-menu" role="menu" aria-labelledby={`admin-group-menu-button-${group._id}`}>
                           <button className="dropdown-item" type="button" role="button" onClick={onClickEdit} data-user-group-id={group._id}>

+ 1 - 1
apps/app/src/components/Admin/UserGroupDetail/UpdateParentConfirmModal.tsx

@@ -28,7 +28,7 @@ export const UpdateParentConfirmModal: FC = () => {
   return (
     <Modal className="modal-md" isOpen={isOpened} toggle={closeModal}>
       <ModalHeader tag="h4" toggle={closeModal} className="bg-warning text-light">
-        <i className="icon icon-warning"></i> {t('admin:user_group_management.update_parent_confirm_modal.header')}
+        <span className="material-symbols-outlined">warning</span> {t('admin:user_group_management.update_parent_confirm_modal.header')}
       </ModalHeader>
       {
         targetGroup != null && updateData != null ? (

+ 1 - 1
apps/app/src/components/Admin/UserGroupDetail/UserGroupUserTable.tsx

@@ -54,7 +54,7 @@ export const UserGroupUserTable = (props: Props): JSX.Element => {
                       className="btn btn-outline-secondary btn-sm dropdown-toggle"
                       data-bs-toggle="dropdown"
                     >
-                      <i className="icon-settings"></i>
+                      <span className="material-symbols-outlined fs-5">settings</span>
                     </button>
                     <div className="dropdown-menu" role="menu" aria-labelledby={`admin-group-menu-button-${relatedUser._id}`}>
                       <button

+ 1 - 1
apps/app/src/components/Admin/UserManagement.module.scss

@@ -12,7 +12,7 @@
   }
   .search-clear {
     position: absolute;
-    top: 12px;
+    top: 15px;
     right: 1px;
     z-index: 3;
     width: 24px;

+ 4 - 3
apps/app/src/components/Admin/UserManagement.tsx

@@ -149,15 +149,16 @@ const UserManagement = (props: UserManagementProps) => {
               {
                 adminUsersContainer.state.searchText.length > 0
                   ? (
-                    <i
-                      className="icon-close search-clear"
+                    <span
+                      className="material-symbols-outlined me-1 search-clear"
                       onClick={async() => {
                         await adminUsersContainer.clearSearchText();
                         if (inputRef.current != null) {
                           inputRef.current.value = '';
                         }
                       }}
-                    />
+                    >cancel
+                    </span>
                   )
                   : ''
               }

+ 1 - 1
apps/app/src/components/Admin/Users/ExternalAccountTable.tsx

@@ -92,7 +92,7 @@ const ExternalAccountTable = (props: ExternalAccountTableProps): JSX.Element =>
                 <td>
                   <div className="btn-group admin-user-menu">
                     <button type="button" className="btn btn-outline-secondary btn-sm dropdown-toggle" data-bs-toggle="dropdown">
-                      <i className="icon-settings"></i> <span className="caret"></span>
+                      <span className="material-symbols-outlined">settings</span> <span className="caret"></span>
                     </button>
                     <ul className="dropdown-menu" role="menu">
                       <li className="dropdown-header">{t('user_management.user_table.edit_menu')}</li>

+ 2 - 1
apps/app/src/components/Admin/Users/UserMenu.tsx

@@ -95,7 +95,8 @@ const UserMenu = (props: UserMenuProps) => {
   return (
     <UncontrolledDropdown id="userMenu" size="sm">
       <DropdownToggle caret color="secondary" outline>
-        <i className="icon-settings" />
+        {/* TODO:fontsize: 20px */}
+        <span className="material-symbols-outlined fs-5">settings</span>
         {(user.status === USER_STATUS.INVITED && !isInvitationEmailSended)
         && <i className={`fa fa-circle text-danger grw-usermenu-notification-icon ${styles['grw-usermenu-notification-icon']}`} />}
       </DropdownToggle>

+ 1 - 1
apps/app/src/components/Bookmarks/BookmarkFolderItemControl.tsx

@@ -23,7 +23,7 @@ export const BookmarkFolderItemControl: React.FC<{
     <Dropdown isOpen={isOpen} toggle={() => setIsOpen(!isOpen)}>
       { children ?? (
         <DropdownToggle color="transparent" className="border-0 rounded btn-page-item-control d-flex align-items-center justify-content-center">
-          <i className="icon-options"></i>
+          <span className="material-symbols-outlined">more_horiz</span>
         </DropdownToggle>
       ) }
       <DropdownMenu

+ 0 - 4
apps/app/src/components/Bookmarks/BookmarkFolderTree.module.scss

@@ -24,10 +24,6 @@ $grw-bookmark-item-padding-left: 35px;
 
 .grw-foldertree :global {
 
-  .btn-page-item-control .icon-plus::before {
-    font-size: 18px;
-  }
-
   .list-group-item {
     .grw-visible-on-hover {
       display: none;

+ 1 - 1
apps/app/src/components/Bookmarks/BookmarkItem.tsx

@@ -181,7 +181,7 @@ export const BookmarkItem = (props: Props): JSX.Element => {
               : undefined}
           >
             <DropdownToggle color="transparent" className="border-0 rounded btn-page-item-control p-0 grw-visible-on-hover me-1">
-              <i className="icon-options fa fa-rotate-90 p-1"></i>
+              <span className="material-symbols-outlined p-1">more_vert</span>
             </DropdownToggle>
           </PageItemControl>
         </div>

+ 3 - 2
apps/app/src/components/Common/PagePathHierarchicalLink/PagePathHierarchicalLink.tsx

@@ -3,7 +3,7 @@ import React, { memo, useCallback } from 'react';
 import Link from 'next/link';
 import urljoin from 'url-join';
 
-import LinkedPagePath from '../../../models/linked-page-path';
+import type LinkedPagePath from '../../../models/linked-page-path';
 
 import styles from './PagePathHierarchicalLink.module.scss';
 
@@ -51,7 +51,8 @@ export const PagePathHierarchicalLink = memo((props: PagePathHierarchicalLinkPro
         <RootElm>
           <span className="path-segment">
             <Link href="/" prefetch={false}>
-              <i className="icon-home"></i>
+              {/* TODO: Size adjust */}
+              <span className="material-symbols-outlined">home</span>
               <span className={`separator ${styles.separator}`}>/</span>
             </Link>
           </span>

+ 4 - 2
apps/app/src/components/ExpandOrContractButton.tsx

@@ -1,4 +1,5 @@
-import React, { FC } from 'react';
+import type { FC } from 'react';
+import React from 'react';
 
 type Props = {
   isWindowExpanded: boolean,
@@ -24,9 +25,10 @@ const ExpandOrContractButton: FC<Props> = (props: Props) => {
   return (
     <button
       type="button"
-      className={`btn ${isWindowExpanded ? 'icon-size-actual' : 'icon-size-fullscreen'}`}
+      className="btn material-symbols-outlined"
       onClick={isWindowExpanded ? clickContractButtonHandler : clickExpandButtonHandler}
     >
+      {isWindowExpanded ? 'close_fullscreen' : 'open_in_full'}
     </button>
   );
 };

+ 0 - 5
apps/app/src/components/ItemsTree/ItemsTree.module.scss

@@ -17,11 +17,6 @@ $grw-pagetree-item-container-height: 40px;
   }
 
   :global {
-    .btn-page-item-control {
-      .icon-plus::before {
-        font-size: 18px;
-      }
-    }
 
     .list-group-item {
       .grw-visible-on-hover {

+ 1 - 1
apps/app/src/components/Me/ExternalAccountLinkedMe.jsx

@@ -64,7 +64,7 @@ class ExternalAccountLinkedMe extends React.Component {
             className="btn btn-outline-secondary btn-sm pull-right"
             onClick={this.openAssociateModal}
           >
-            <i className="icon-plus" aria-hidden="true" />
+            <span className="material-symbols-outlined" aria-hidden="true">add_circle</span>
             Add
           </button>
           { t('admin:user_management.external_accounts') }

+ 2 - 2
apps/app/src/components/PageAttachment/DeleteAttachmentModal.tsx

@@ -20,7 +20,7 @@ import styles from './DeleteAttachmentModal.module.scss';
 const logger = loggerFactory('growi:attachmentDelete');
 
 const iconByFormat = (format: string): string => {
-  return format.match(/image\/.+/i) ? 'icon-picture' : 'icon-doc';
+  return format.match(/image\/.+/i) ? 'image' : 'description';
 };
 
 export const DeleteAttachmentModal: React.FC = () => {
@@ -73,7 +73,7 @@ export const DeleteAttachmentModal: React.FC = () => {
     return (
       <div className="attachment-delete-image">
         <p>
-          <i className={iconByFormat(attachment.fileFormat)}></i> {attachment.originalName}
+          <span className="material-symbols-outlined">{iconByFormat(attachment.fileFormat)}</span> {attachment.originalName}
         </p>
         <p>
           uploaded by <UserPicture user={attachment.creator} size="sm"></UserPicture> <Username user={attachment.creator as IUser}></Username>

+ 3 - 3
apps/app/src/components/PageComment/CommentEditor.tsx

@@ -44,11 +44,11 @@ const SlackNotification = dynamic(() => import('../SlackNotification').then(mod
 
 const navTabMapping = {
   comment_editor: {
-    Icon: () => <i className="icon-settings" />,
+    Icon: () => <span className="material-symbols-outlined">edit_square</span>,
     i18n: 'Write',
   },
   comment_preview: {
-    Icon: () => <i className="icon-settings" />,
+    Icon: () => <span className="material-symbols-outlined">play_arrow</span>,
     i18n: 'Preview',
   },
 };
@@ -263,7 +263,7 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => {
               onClick={() => setIsReadyToUse(true)}
               data-testid="open-comment-editor-button"
             >
-              <i className="icon-bubble"></i> Add Comment
+              <span className="material-symbols-outlined">comment</span> Add Comment
             </button>
           </NotAvailableForReadOnlyUser>
         </NotAvailableForGuest>

+ 2 - 2
apps/app/src/components/PageComment/ReplyComments.tsx

@@ -68,8 +68,8 @@ export const ReplyComments = (props: ReplycommentsProps): JSX.Element => {
   }
 
   const areThereHiddenReplies = (replyList.length > 2);
-  const toggleButtonIconName = isOlderRepliesShown ? 'icon-arrow-up' : 'icon-options-vertical';
-  const toggleButtonIcon = <i className={`icon-fw ${toggleButtonIconName}`}></i>;
+  const toggleButtonIconName = isOlderRepliesShown ? 'expand_less' : 'more_vert';
+  const toggleButtonIcon = <span className="material-icons-outlined me-1">{toggleButtonIconName}</span>;
   const toggleButtonLabel = isOlderRepliesShown ? '' : 'more';
   const shownReplies = replyList.slice(replyList.length - 2, replyList.length);
   const hiddenReplies = replyList.slice(0, replyList.length - 2);

+ 1 - 1
apps/app/src/components/PageControls/PageControls.tsx

@@ -52,7 +52,7 @@ const Tags = (props: TagsProps): JSX.Element => {
         className="btn btn-link btn-edit-tags text-muted border border-secondary p-1 d-flex align-items-center"
         onClick={onClickEditTagsButton}
       >
-        <i className="icon-tag me-2" />
+        <span className="material-symbols-outlined me-2">local_offer</span>
         Tags
       </button>
     </div>

+ 1 - 1
apps/app/src/components/PageEditor/Editor.tsx

@@ -343,7 +343,7 @@ const Editor: ForwardRefRenderFunction<IEditorMethods, EditorPropsType> = (props
               className="btn btn-outline-secondary btn-open-dropzone"
               onClick={addAttachmentHandler}
             >
-              <i className="icon-paper-clip" aria-hidden="true"></i>&nbsp;
+              <span className="material-symbols-outlined" aria-hidden="true">attachment</span>&nbsp;
               Attach files
               <span className="d-none d-sm-inline">
               &nbsp;by dragging &amp; dropping,&nbsp;

+ 2 - 1
apps/app/src/components/PagePresentationModal.tsx

@@ -71,11 +71,12 @@ const PagePresentationModal = (): JSX.Element => {
     >
       <div className="grw-presentation-controls d-flex">
         <button
-          className={`btn ${fullscreen.active ? 'icon-size-actual' : 'icon-size-fullscreen'}`}
+          className="btn material-symbols-outlined"
           type="button"
           aria-label="fullscreen"
           onClick={toggleFullscreenHandler}
         >
+          {fullscreen.active ? 'close_fullscreen' : 'open_in_full'}
         </button>
         <button className="btn-close" type="button" aria-label="Close" onClick={closeHandler}></button>
       </div>

+ 5 - 5
apps/app/src/components/SavePageControls/GrantSelector/GrantSelector.tsx

@@ -18,18 +18,18 @@ import { useMyUserGroups } from './use-my-user-groups';
 
 const AVAILABLE_GRANTS = [
   {
-    grant: PageGrant.GRANT_PUBLIC, iconClass: 'icon-people', btnStyleClass: 'outline-info', label: 'Public',
+    grant: PageGrant.GRANT_PUBLIC, iconName: 'group', btnStyleClass: 'outline-info', label: 'Public',
   },
   {
-    grant: PageGrant.GRANT_RESTRICTED, iconClass: 'icon-link', btnStyleClass: 'outline-teal', label: 'Anyone with the link',
+    grant: PageGrant.GRANT_RESTRICTED, iconName: 'link', btnStyleClass: 'outline-teal', label: 'Anyone with the link',
   },
   // { grant: 3, iconClass: '', label: 'Specified users only' },
   {
-    grant: PageGrant.GRANT_OWNER, iconClass: 'icon-lock', btnStyleClass: 'outline-danger', label: 'Only me',
+    grant: PageGrant.GRANT_OWNER, iconName: 'lock', btnStyleClass: 'outline-danger', label: 'Only me',
   },
   {
     grant: PageGrant.GRANT_USER_GROUP,
-    iconClass: 'icon-options',
+    iconName: 'more_horiz',
     btnStyleClass: 'outline-purple',
     label: 'Only inside the group',
     reselectLabel: 'Reselect the group',
@@ -119,7 +119,7 @@ export const GrantSelector = (props: Props): JSX.Element => {
 
       const labelElm = (
         <span>
-          <i className={`icon icon-fw ${opt.iconClass}`}></i>
+          <span className="material-symbols-outlined me-2">{opt.iconName}</span>
           <span className="label">{t(label)}</span>
         </span>
       );

+ 3 - 2
apps/app/src/components/Sidebar/PageTree/PrivateLegacyPagesLink.tsx

@@ -1,4 +1,5 @@
-import React, { FC, memo } from 'react';
+import type { FC } from 'react';
+import React, { memo } from 'react';
 
 import { useTranslation } from 'next-i18next';
 import Link from 'next/link';
@@ -13,7 +14,7 @@ export const PrivateLegacyPagesLink: FC = memo(() => {
       className="h5 grw-private-legacy-pages-anchor text-decoration-none"
       prefetch={false}
     >
-      <i className="icon-drawer me-2"></i> {t('private_legacy_pages.title')}
+      <span className="material-symbols-outlined me-2">bottom_drawer</span> {t('private_legacy_pages.title')}
     </Link>
   );
 });

+ 1 - 1
apps/app/src/components/Sidebar/PageTreeItem/Ellipsis.tsx

@@ -162,7 +162,7 @@ export const Ellipsis: FC<TreeItemToolProps> = (props) => {
           >
             {/* pass the color property to reactstrap dropdownToggle props. https://6-4-0--reactstrap.netlify.app/components/dropdowns/  */}
             <DropdownToggle color="transparent" className="border-0 rounded btn-page-item-control p-0 grw-visible-on-hover mr-1">
-              <i id="option-button-in-page-tree" className="icon-options fa fa-rotate-90 p-1"></i>
+              <span id="option-button-in-page-tree" className="material-symbols-outlined p-1">more_vert</span>
             </DropdownToggle>
           </PageItemControl>
         </div>

+ 1 - 1
apps/app/src/components/Sidebar/SidebarHeaderReloadButton.tsx

@@ -8,7 +8,7 @@ export const SidebarHeaderReloadButton = ({ onClick }: Props) => {
 
   return (
     <button type="button" className="btn btn-sm ms-auto py-0 grw-btn-reload" onClick={onClick}>
-      <i className="icon icon-reload"></i>
+      <span className="material-symbols-outlined">refresh</span>
     </button>
   );
 };

+ 1 - 1
apps/app/src/components/TreeItem/NewPageInput/NewPageCreateButton.tsx

@@ -27,7 +27,7 @@ export const NewPageCreateButton: FC<NewPageCreateButtonProps> = (props) => {
               className="border-0 rounded btn btn-page-item-control p-0 grw-visible-on-hover"
               onClick={onClick}
             >
-              <i className="icon-plus d-block p-0" />
+              <span className="material-symbols-outlined d-block p-0">add_circle</span>
             </button>
           </NotAvailableForReadOnlyUser>
         </NotAvailableForGuest>

+ 1 - 2
apps/app/src/components/User/UserInfo.tsx

@@ -27,8 +27,7 @@ export const UserInfo = (props: UserInfoProps): JSX.Element => {
         </h1>
         <div className="user-page-meta mt-3 mb-0">
           <span className="user-page-username me-4">
-            {/* TODO:Replace with Material Symbols Outlined */}
-            <span className="user-page-username me-4"><i className="icon-user me-1"></i>{author.username}</span>
+            <span className="user-page-username me-4"><span className="material-symbols-outlined">person</span>{author.username}</span>
           </span>
           <span className="user-page-email me-2">
             <span className="material-symbols-outlined me-1">mail</span>

+ 1 - 1
apps/app/src/features/growi-plugin/client/components/Admin/PluginsExtensionPageContents/PluginsExtensionPageContents.tsx

@@ -38,7 +38,7 @@ export const PluginsExtensionPageContents = (): JSX.Element => {
           <h2 className="admin-setting-header">
             {t('plugins.plugin_card')}
             <button type="button" className="btn btn-sm ms-auto grw-btn-reload" onClick={() => mutate()}>
-              <i className="icon icon-reload"></i>
+              <span className="material-symbols-outlined">refresh</span>
             </button>
           </h2>
           {data?.plugins == null

+ 1 - 1
apps/app/src/pages/installer.page.tsx

@@ -42,7 +42,7 @@ const InstallerPage: NextPage<Props> = (props: Props) => {
   const navTabMapping = useMemo(() => {
     return {
       user_infomation: {
-        Icon: () => <i className="icon-fw icon-user"></i>,
+        Icon: () => <span className="material-symbols-outlined me-1">person</span>,
         Content: InstallerForm,
         i18n: t('installer.tab'),
       },

+ 2 - 2
packages/ui/src/components/Attachment.tsx

@@ -22,7 +22,7 @@ export const Attachment = (props: AttachmentProps): JSX.Element => {
     }
   };
 
-  const formatIcon = (attachment.fileFormat.match(/image\/.+/i)) ? 'icon-picture' : 'icon-doc';
+  const formatIcon = (attachment.fileFormat.match(/image\/.+/i)) ? 'image' : 'description';
   const btnDownload = (isUserLoggedIn)
     ? (
       <a className="attachment-download" href={attachment.downloadPathProxied}>
@@ -49,7 +49,7 @@ export const Attachment = (props: AttachmentProps): JSX.Element => {
         <UserPicture user={attachment.creator} size="sm"></UserPicture>
       </span>
       <a className="me-2" href={attachment.filePathProxied} target="_blank" rel="noopener noreferrer">
-        <i className={formatIcon}></i> {attachment.originalName}
+        <span className="material-symbols-outlined ms-1">{formatIcon}</span> {attachment.originalName}
       </a>
       <span className="me-2">{fileType}</span>
       <span className="me-2">{createdAt}</span>

+ 2 - 2
packages/ui/src/components/PagePath/PageListMeta.tsx

@@ -81,7 +81,7 @@ export const PageListMeta: FC<PageListMetaProps> = (props: PageListMetaProps) =>
 
   let commentCount;
   if (page.commentCount > 0) {
-    commentCount = <span className={`${shouldSpaceOutIcon ? 'me-2' : ''}`}><i className="icon-bubble" />{page.commentCount}</span>;
+    commentCount = <span className={`${shouldSpaceOutIcon ? 'me-2' : ''}`}><span className="material-symbols-outlined">comment</span>{page.commentCount}</span>;
   }
 
   let likerCount;
@@ -91,7 +91,7 @@ export const PageListMeta: FC<PageListMetaProps> = (props: PageListMetaProps) =>
 
   let locked;
   if (page.grant !== 1) {
-    locked = <span className={`${shouldSpaceOutIcon ? 'me-2' : ''}`}><i className="icon-lock" /></span>;
+    locked = <span className={`${shouldSpaceOutIcon ? 'me-2' : ''}`}><span className="material-symbols-outlined">lock</span></span>;
   }
 
   let bookmarkCount;