<div class="alert alert-warning">

# DEPRECATED

master ブランチは Atlaskit を使わず自前実装に切り替え済み。

</div>

# 元の材料

- [@atlaskit/navigation-next](https://atlaskit.atlassian.com/packages/core/navigation-next) を Sidebar コンポーネントでラップしている
- 開閉(collapse)できる
- サイズの固定・解除ができる
    - サイズ固定状態では、collapse が解除される

## Drawer Mode

- `navigationUIController.disableResize()` を行い、サイズ固定、Sidebar としては常に collapse 解除(open 状態)にする
- 上記をスタイル変更で画面外に隠す
    - `@mixin drawer()`
- Drawer の開閉は、Sidebar コンポーネントごと css で左右に移動させる
    - `AppContainer.state.isDrawerOpened`
- モーダルバックドロップは自作している
    - `.grw-sidebar-backdrop.modal-backdrop`

## Dock Mode

- `navigationUIController.enableResize()` を行い、サイズ可変にする

## Hack

- navigation-next は unstated container を利用しているが、一部のコードでバグがある
    - `UIController.storeState` で、更新完了していない state を参照してしまっている(await していない)
    - そのため、1世代前の state 情報を localStorege に保存してしまう
- 上記を回避するため、以下のようなコードで storeState メソッドを上書きしている

```javascript:Sidebar.jsx
  /**
   * hack and override UIController.storeState
   *
   * Since UIController is an unstated container, setState() in storeState method should be awaited before writing to cache.
   */
  hackUIController() {
    const { navigationUIController } = this.props;

    // see: @atlaskit/navigation-next/dist/esm/ui-controller/UIController.js
    const orgStoreState = navigationUIController.storeState;
    navigationUIController.storeState = async(state) => {
      await navigationUIController.setState(state);
      orgStoreState(state);
    };
  }
```

# モード変更条件

- デバイスサイズ sm 以下では Drawer Mode
- デバイスサイズ md 以上では、閲覧/編集 モード x ユーザーpreference のマトリックスにより、4種類の状態を遷移する
    - 閲覧モード x `localStorage.preferDrawerModeByUser: true` -> Drawer Mode
    - 閲覧モード x `localStorage.preferDrawerModeByUser: false` -> Dock Mode
    - 編集モード x `localStorage.preferDrawerModeOnEditByUser: true` -> Drawer Mode
    - 編集モード x `localStorage.preferDrawerModeOnEditByUser: false` -> Dock Mode
- 上記は `AppContainer.updateDrawerMode()` で判定
    - unstated の state を正しく更新・参照するために await を乱発するとパフォーマンスが落ちるため、呼び出し側で新しい状態オブジェクトである `newState` を作成して引数に入れている
    - 更新のトリガーは以下
        - 閲覧・編集モードタブ切り替え
        - デバイスサイズ変更を検知する media query イベントハンドラ

# モード変更時のトランジション抑制
- 状態に応じて以下を抑制しないと気持ち悪い動きになる
    1. Sidebar の実態である navigationUIController の開閉 transition
    1. `@mixin drawer()` で左右に動かしている部分の transition
- ロジック
    - Dock Mode での navigationUIController の開閉状態を記憶、判定の材料に使う
    - Dock -> Drawer
        - 元々 collapse していた場合、1を抑制してはいけない
            - 抑制してしまうと瞬時に open 状態になり、スムーズに画面外に掃けなくなる
        - 元々 collapse していた場合、2を抑制する
            - 抑制することで navigationUIController が open 状態に遷移するとしても、Sidebar 全体は画面外へ速やかに移動する
    - Drawer -> Dock
        - 元々 collapse していた場合、1を抑制する
            - navigationUIController を瞬時に open -> collapse に戻すことができる
- 抑制手段
    - 少し気持ち悪いが一旦クリアして setTimeout で元に戻す
        ```javascript
          clearNavigationTransitionTemporary(elem) {
            const transitionCache = elem.style.transition;

            // clear
            elem.style.transition = undefined;

            // restore after 300ms
            setTimeout(() => {
              elem.style.transition = transitionCache;
            }, 300);
          }
        ```

# ページロード時の初期状態

- sm 以下の場合は、CSS により `.grw-sidebar-drawer` クラスの有無に関わらず `@mixin drawer()` が適用される
    - media query の判定はページロード完了後になるため、 `AppContainer.state.isDeviceSmallerThanMd` を初期状態セットアップに利用することができない
    - Sidebar の実態である navigationUIController は、画面外で `AppContainer.state.isDrawerMode` の初期化を待って Drawer Mode へ遷移する
- md 以上の場合は、AppContainer の初期化完了時に既に localStorage から値を読み込んだ `AppContainer.state.preferDrawerMode*` が利用可能であるため、その値を利用して初期状態への遷移を行う
    - Sidebar の実態である navigationUIController は、`SidebarWithNavigation` で `NavigationProvider` の `initialUIController` が設定される
        - preferDrawerModeByUser が true なら初期値をセット、false なら何もセットせず、キャッシュ(`localStorage.ATLASKIT_NAVIGATION_UI_STATE`)を利用する

`growi-sidebar-drawer` クラスの有無で `@mixin drawer()` が適用されるかどうかが決まる

---

## Page Navigation

- Canonical URL: https://dev.growi.org/資料/内部仕様/Sidebar
- Permalink: https://dev.growi.org/5edacd0e3512890048ddc19f
- Parent: [内部仕様](/5cc1c93a973c65003eeca8c9.md)
- Children: 0 total
- Total descendants: 0
- Siblings: 48 total
  - [AWS・メーラー周りの改善](/5d02003202145d003e1babf6.md)
  - [Audit Log Bulk Export](/68b96f7fcde220ddd8dad822.md)
  - [ConfigManager](/5cc9975f30890b003fe90935.md)
  - [ElasticSearchのインデックスリビルド](/5e3ff13564387500480619a1.md)
  - [Elasticsearchから取得できるPagesに関するデータ](/614aad9c0043a10051e15701.md)
  - [EmojiPicker](/6333fb298e520dbb752dc0cd.md)
  - [EventEmitterの利用](/61391728d5f8360051fd4942.md)
  - [G2G Transfer](/6346a2e0e4791185c5e88285.md)
  - [GROWI Bot](/62a71cdfb1519362cc276234.md)
  - [HackMD連携](/5d27efd443f7f50048a78e0a.md)
  - [Handsontable統合メモ](/5cc99eac30890b003fe9093b.md)
  - [InAppNotificationにニュースを配信する](/69ab8eb7659066cd59ddb618.md)
  - [LDAPグループ同期](/646d5f73d184d74b40517c3e.md)
  - [Packagesのエラーハンドリングアーキテクチャ](/60e6727cf04bf00049b9d514.md)
  - [Page Bulk Export](/655834752aa37f82842a2034.md)
  - [PageOperation](/62010f2f16bc406c1b5e291b.md)
  - [SAML RoleとGrowiの権限の連携](/5d25e82feeb1f9003ee9b64c.md)
  - [SMTP設定に関する仕様](/5f4ef239cff9700048251c9a.md)
  - [SWR Utilities](/63735c96c29dff4657eb78ca.md)
  - [Slack Command Handling](/60ee432f4a58890049d183cd.md)
  - [WebpackAssetsのHTMLへの注入](/5e3ee633ccdb6f0048e8c124.md)
  - [apiv3仕様](/5cf494d4aa8c91003eb0b481.md)
  - [audit-log](/62a1639c028badd4ac23f533.md)
  - [growi-database-plugin](/634784794b3568aa883bfca6.md)
  - [skipSSR](/64bf8e68a1e72e1b846d02fd.md)
  - [socket.io room 機能を使った通知設計](/6137540af2060f00510d56bb.md)
  - [v5.0.0～v7.0.15 でのRevisionデータマイグレーションバグ](/69301054963f68dfcf2b7111.md)
  - [お知らせ機能](/650d5e741647c0285cbb8a33.md)
  - [アンケート機能](/6385911e1632aa30f4dae6a4.md)
  - [インストールプロセス](/6009091dd3b38b00486b4ba5.md)
  - [インラインコメント機能](/650154e4a3498dcb94e91b36.md)
  - [ショートカットキー](/5cc1cb12973c65003eeca8cc.md)
  - [スケルトン表示ガイドライン](/62d7ca7fb18c4bec89d81a12.md)
  - [タグに関する仕様](/6171077c700078147672e3e0.md)
  - [ビルトインエディタでの同時多人数編集](/6524a63e46f2d6a2691e430a.md)
  - [ファイルアップロードのシーケンス図](/5fd8424f2271ae00481ed2e8.md)
  - [ファイルアップロード設定](/5f55a6af28951e0048d61398.md)
  - [プレゼンテーション](/63ea366fdc96eb0ef7657f53.md)
  - [ページ&ユーザーグループv5](/61b2cdd6aa330ce7d8152a4e.md)
  - [ページの子孫数](/62ac00a1c395c23b7a8c86dc.md)
  - [ページの移動・リネーム](/62149d019311629d4ecd91cf.md)
  - [ページ同時編集時のコンフリクト解消に関する仕様](/615d4a77c0ac5081f05d9d57.md)
  - [ログイン時の挙動](/63eee058c9d7133b414ba205.md)
  - [ワークフロー機能](/64e6b3d5e28cb1aa7ee4197f.md)
  - [検索v5](/61975a974027a1fa01947059.md)
  - [検索結果ページのコメント表示](/621caadad9a9f09266ad21c3.md)
  - [権限修正が可能なページのアラート](/626a263645af0b779a282145.md)
  - [空ページ](/62b2f5b3f442e6078d890a8b.md)
- Last updated: 2022-03-03T12:54:23.176Z by yuki
- Full page listing (all children regardless of count): https://dev.growi.org/_api/v3/page-listing/children?id=5edacd0e3512890048ddc19f
