소스 검색

add NodeBook layout component to handle text display

axolotle 3 년 전
부모
커밋
ddff9313cb
2개의 변경된 파일221개의 추가작업 그리고 0개의 파일을 삭제
  1. 220 0
      src/components/layouts/NodeBook.vue
  2. 1 0
      src/components/layouts/index.js

+ 220 - 0
src/components/layouts/NodeBook.vue

@@ -0,0 +1,220 @@
+<template>
+  <div
+    class="node-book"
+  >
+    <section
+      class="node-book-stack no-events-container"
+      :style="`--count: ${nodes.length - 1}; --h: ${stackHeight}px;`"
+    >
+      <div
+        v-for="({ parent, children }, i) in nodes" :key="parent.id"
+        class="node-book-stack-item node-book-stack-item-parent splitted"
+        :class="{ active: i === nodes.length - 1 }"
+        :style="`--nth: ${i}`"
+      >
+        <node-view-child-list :children="parent.children" :parent-id="parent.id" smartphone />
+
+        <node-view
+          :node="parent"
+          type="ref"
+          mode="view"
+          @open-node="$emit('open-node', $event)"
+          @open-child="$emit('open-node', parent.id, $event)"
+          @close-node="$emit('close-node', $event)"
+        />
+
+        <section
+          class="node-book-stack no-events-container"
+          :style="`--count: ${children.length }; --h: ${getChildrenStackHeight(children.length)}px;`"
+        >
+          <div
+            v-for="(child, j) in children" :key="child.id + '-cont'"
+            class="node-book-stack-item"
+            :class="{ active: j === children.length - 1 }"
+            :style="`--nth: ${j}`"
+          >
+            <node-view
+              :key="child.id"
+              :node="child"
+              mode="view"
+              type="prod"
+              @open-node="$emit('open-node', $event)"
+              @close-node="$emit('close-node', parent.id, $event)"
+            />
+          </div>
+        </section>
+      </div>
+    </section>
+  </div>
+</template>
+
+<script>
+import { NodeViewChildList, NodeView } from '@/components/nodes'
+
+
+export default {
+  name: 'NodeBook',
+
+  components: {
+    NodeViewChildList,
+    NodeView
+  },
+
+  props: {
+    nodes: { type: Array, required: true }
+  },
+
+  data () {
+    return {
+      height: undefined
+    }
+  },
+
+  computed: {
+    stackHeight () {
+      return Math.min(150 / (this.nodes.length - 1), 75)
+    }
+  },
+
+  methods: {
+    updateSize () {
+      this.height = this.$el.getBoundingClientRect().height
+    },
+
+    getChildrenStackHeight (childrenLen) {
+      return this.stackHeight / childrenLen || this.stackHeight
+    }
+  },
+
+  mounted () {
+    window.addEventListener('resize', () => this.updateSize())
+    this.updateSize()
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.node-book {
+  min-height: 100%;
+  // top: -100%;
+
+  @include media-breakpoint-up($layout-bp) {
+    height: 100%;
+
+    // ╭─╴╶┬╴╭─┐╭─╴╷ ╭
+    // ╰─╮ │ ├─┤│  ├┴╮
+    // ╶─╯ ╵ ╵ ╵╰─╴╵ ╵
+
+    &-stack {
+      position: relative;
+      height: 100%;
+      width: 100%;
+      display: flex;
+      flex-direction: column;
+
+      &-item {
+        width: 100%;
+        height: 100%;
+        position: absolute;
+        top: calc(var(--h) * var(--nth));
+        height: calc(100% - (var(--h) * var(--nth)));
+
+        &-parent > .node-view {
+          border-right: $line;
+        }
+
+        &-parent > .node-view {
+          border-top: $line;
+        }
+
+        &:not(.node-book-stack-item-parent):first-child {
+          border-top: $line;
+        }
+
+
+        // BLURS
+        &-parent:not(.active) {
+          &::before,
+          &::after {
+            content: '';
+            pointer-events: none;
+            position: absolute;
+            z-index: 1;
+            display: block;
+            top: $border-width;
+            height: calc(var(--h) - #{$border-width});
+            background-color: rgba($white, .5);
+          }
+          &::before {
+            width: calc(50% - #{$border-width});
+            left: 0;
+          }
+          &::after {
+            width: 50%;
+            left: 50%;
+          }
+        }
+
+        &-parent.active {
+          background-color: rgba($white, .5);
+        }
+
+        &:not(.active) {
+          ::v-deep {
+            .node-view {
+              overflow-y: hidden;
+
+              &-header {
+                z-index: 0;
+              }
+            }
+
+            .node-view-child-list {
+              display: none;
+            }
+          }
+          // ::v-deep .node-view:not(:hover) {
+          //     .node-view-header {
+          //       padding-top: $node-view-spacer-sm-y;
+          //       padding-bottom: $node-view-spacer-sm-y;
+          //     }
+          //
+          //     h4 {
+          //       font-size: 2rem;
+          //       > * {
+          //         display: inline !important;
+          //       }
+          //       .edition {
+          //         display: none !important;
+          //       }
+          //       display: block;
+          //       display: -webkit-box;
+          //       -webkit-line-clamp: 1;
+          //       -webkit-box-orient: vertical;
+          //       text-overflow: ellipsis;
+          //       overflow: hidden;
+          //       max-height: 1.5em;
+          //     }
+          //
+          //     .node-view-header-prod h4 {
+          //       font-size: 1rem;
+          //     }
+          // }
+          //
+          // &:hover {
+          //   ::v-deep .node-view:hover .node-view-header {
+          //     z-index: calc(var(--count) + 10);
+          //     border-bottom: $line;
+          //   }
+          // }
+        }
+
+        &.splitted {
+          display: flex;
+          flex-basis: 50%;
+        }
+      }
+    }
+  }
+}
+</style>

+ 1 - 0
src/components/layouts/index.js

@@ -1 +1,2 @@
 export { default as MapZoom } from './MapZoom'
+export { default as NodeBook } from './NodeBook'