undergroundwires/privacy.sexy

View on GitHub
src/presentation/components/Scripts/View/Tree/TreeView/Node/NodeCheckbox.vue

Summary

Maintainability
Test Coverage
<template>
  <div
    class="checkbox"
    :class="{
      checked,
      indeterminate,
    }"
  />
</template>

<script lang="ts">
import { defineComponent, computed, toRef } from 'vue';
import { useCurrentTreeNodes } from '../UseCurrentTreeNodes';
import { useNodeState } from './UseNodeState';
import { TreeNodeCheckState } from './State/CheckState';
import type { TreeRoot } from '../TreeRoot/TreeRoot';
import type { TreeNode, TreeNodeId } from './TreeNode';
import type { PropType } from 'vue';

export default defineComponent({
  props: {
    nodeId: {
      type: String as PropType<TreeNodeId>,
      required: true,
    },
    treeRoot: {
      type: Object as PropType<TreeRoot>,
      required: true,
    },
  },
  setup(props) {
    const { nodes } = useCurrentTreeNodes(toRef(props, 'treeRoot'));
    const currentNode = computed<TreeNode>(
      () => nodes.value.getNodeById(props.nodeId),
    );
    const { state } = useNodeState(currentNode);

    const checked = computed<boolean>(() => state.value.checkState === TreeNodeCheckState.Checked);
    const indeterminate = computed<boolean>(
      () => state.value.checkState === TreeNodeCheckState.Indeterminate,
    );

    return {
      indeterminate,
      checked,
      currentNode,
    };
  },
});
</script>

<style scoped lang="scss">
@use "@/presentation/assets/styles/main" as *;
@use "./../tree-colors" as *;

$side-size-in-px: $font-size-absolute-x-large;

.checkbox {
  position: relative;

  width: $side-size-in-px;
  height: $side-size-in-px;

  box-sizing: border-box;
  border: 1px solid $color-node-checkbox-border-unchecked;
  border-radius: 2px;
  transition: border-color .25s, background-color .25s;
  background: $color-node-checkbox-bg-unchecked;

  &:after {
    position: absolute;
    display: block;
    content: "";
  }

  &.indeterminate {
    border-color: $color-node-checkbox-border-unchecked;

    &:after { // Draw line (─)
      background-color: $color-node-checkbox-border-indeterminate;
      top: 50%;
      left: 20%;
      right: 20%;
      height: 1.5px;
    }
  }

  &.checked {
    background: $color-node-checkbox-bg-checked;
    border-color: $color-node-checkbox-border-checked;

    &:after { // Draw checkmark tick (✔️)

      box-sizing: content-box;
      border: 1.5px solid $color-node-checkbox-tick-checked;
      border-left: 0;
      border-top: 0;

      left: $side-size-in-px * 0.33;
      top: $side-size-in-px * 0.11;
      height: $side-size-in-px * 0.50;
      width: $side-size-in-px * 0.25;

      transform: rotate(45deg) scaleY(1);
      transition: transform .25s;
      transform-origin: center;
    }
  }
}
</style>