Explorar el Código

HUE-9485 [frontend] Add a Dropdown Vue component

Johan Ahlen hace 5 años
padre
commit
925054a0f2

+ 34 - 0
desktop/core/src/desktop/js/components/dropdown/Dropdown.test.ts

@@ -0,0 +1,34 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// 'License'); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { shallowMount } from '@vue/test-utils';
+import Dropdown from './Dropdown.vue';
+
+describe('Dropdown.vue', () => {
+  it('should render empty dropdown', () => {
+    const wrapper = shallowMount(Dropdown);
+    expect(wrapper.element).toMatchSnapshot();
+  });
+
+  it('should render dropdown with slots', () => {
+    const wrapper = shallowMount(Dropdown, {
+      scopedSlots: {
+        default: '<div>Some item</div>'
+      }
+    });
+    expect(wrapper.element).toMatchSnapshot();
+  });
+});

+ 138 - 0
desktop/core/src/desktop/js/components/dropdown/Dropdown.vue

@@ -0,0 +1,138 @@
+<!--
+  Licensed to Cloudera, Inc. under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  Cloudera, Inc. licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<template>
+  <div :class="{ 'dropdown-inline': inline }">
+    <a v-if="inline" href="javascript: void(0);" @click="toggleMenu">
+      {{ text }} <i class="fa fa-caret-down" />
+    </a>
+    <button v-else class="btn" type="button" @click="toggleMenu">
+      {{ text }} <i class="fa fa-caret-down" />
+    </button>
+    <div :class="{ open: menuOpen }" class="hue-dropdown-container" @click="toggleMenu">
+      <div class="hue-dropdown-menu">
+        <ul>
+          <slot />
+        </ul>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+  import Vue from 'vue';
+  import Component from 'vue-class-component';
+  import { Prop } from 'vue-property-decorator';
+
+  @Component
+  export default class Dropdown extends Vue {
+    @Prop({ required: false, default: '' })
+    text: string;
+    @Prop({ required: false, default: false })
+    inline: boolean;
+
+    menuOpen = false;
+
+    toggleMenu(): void {
+      this.menuOpen = !this.menuOpen;
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  @import '../styles/colors';
+  @import '../styles/mixins';
+
+  .dropdown-inline {
+    display: inline-block;
+  }
+
+  .hue-dropdown-container {
+    position: fixed;
+    z-index: 1061;
+
+    &.open {
+      position: absolute;
+      .hue-dropdown-menu {
+        display: block;
+      }
+    }
+
+    &.hue-dropdown-fixed {
+      position: fixed !important;
+    }
+
+    /deep/ .hue-dropdown-menu {
+      display: none;
+      z-index: 1000;
+      float: left;
+
+      position: absolute;
+      top: 100%;
+      left: 0;
+      margin: 2px 0 0;
+      padding: 0;
+      min-width: 160px;
+      max-width: 250px;
+      min-height: 34px;
+      max-height: 200px;
+
+      background-color: $cui-white;
+      overflow-x: hidden;
+      overflow-y: auto;
+      list-style: none;
+      border: 1px solid $cui-gray;
+      border-radius: $hue-panel-border-radius;
+
+      @include box-shadow(0, 5px, 10px, rgba(0, 0, 0, 0.2));
+
+      ul {
+        overflow-x: hidden;
+        margin: 0 !important;
+        padding: 0;
+        list-style: none;
+        font-size: 13px;
+
+        li {
+          color: $cui-gray-800;
+
+          button,
+          a {
+            display: block;
+            width: 100%;
+            padding: 6px 16px;
+            clear: both;
+            font-weight: 400;
+            text-align: inherit;
+            white-space: nowrap;
+            background-color: transparent;
+            border: 0;
+            position: relative;
+            outline: 0;
+
+            &:hover,
+            &.active,
+            &.focus {
+              background-color: $hue-primary-color-light;
+            }
+          }
+        }
+      }
+    }
+  }
+</style>

+ 29 - 0
desktop/core/src/desktop/js/components/dropdown/DropdownGroup.test.ts

@@ -0,0 +1,29 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// 'License'); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { shallowMount } from '@vue/test-utils';
+import DropdownGroup from './DropdownGroup.vue';
+
+describe('DropdownGroup.vue', () => {
+  it('should render', () => {
+    const wrapper = shallowMount(DropdownGroup, {
+      propsData: {
+        header: 'Some Header'
+      }
+    });
+    expect(wrapper.element).toMatchSnapshot();
+  });
+});

+ 48 - 0
desktop/core/src/desktop/js/components/dropdown/DropdownGroup.vue

@@ -0,0 +1,48 @@
+<!--
+  Licensed to Cloudera, Inc. under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  Cloudera, Inc. licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<template>
+  <li>
+    <header class="dropdown-group-header">{{ header }}</header>
+    <ul>
+      <slot />
+    </ul>
+  </li>
+</template>
+
+<script lang="ts">
+  import Vue from 'vue';
+  import Component from 'vue-class-component';
+  import { Prop } from 'vue-property-decorator';
+
+  @Component
+  export default class DropdownGroup extends Vue {
+    @Prop({ required: true })
+    header!: string;
+  }
+</script>
+
+<style lang="scss" scoped>
+  @import '../styles/colors';
+
+  .dropdown-group-header {
+    color: $cui-gray-800;
+    font-weight: 500;
+    padding: 6px 10px;
+  }
+</style>

+ 25 - 0
desktop/core/src/desktop/js/components/dropdown/DropdownItem.test.ts

@@ -0,0 +1,25 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// 'License'); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { shallowMount } from '@vue/test-utils';
+import DropdownItem from './DropdownItem.vue';
+
+describe('DropdownItem.vue', () => {
+  it('should render', () => {
+    const wrapper = shallowMount(DropdownItem);
+    expect(wrapper.element).toMatchSnapshot();
+  });
+});

+ 34 - 0
desktop/core/src/desktop/js/components/dropdown/DropdownItem.vue

@@ -0,0 +1,34 @@
+<!--
+  Licensed to Cloudera, Inc. under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  Cloudera, Inc. licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<template>
+  <li>
+    {{ text }}
+    <slot />
+  </li>
+</template>
+
+<script lang="ts">
+  import Vue from 'vue';
+  import Component from 'vue-class-component';
+
+  @Component
+  export default class DropdownItem extends Vue {}
+</script>
+
+<style lang="scss" scoped></style>

+ 25 - 0
desktop/core/src/desktop/js/components/dropdown/DropdownItemButton.test.ts

@@ -0,0 +1,25 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// 'License'); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { shallowMount } from '@vue/test-utils';
+import DropdownItemButton from './DropdownItemButton.vue';
+
+describe('DropdownItemButton.vue', () => {
+  it('should render', () => {
+    const wrapper = shallowMount(DropdownItemButton);
+    expect(wrapper.element).toMatchSnapshot();
+  });
+});

+ 33 - 0
desktop/core/src/desktop/js/components/dropdown/DropdownItemButton.vue

@@ -0,0 +1,33 @@
+<!--
+  Licensed to Cloudera, Inc. under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  Cloudera, Inc. licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<template>
+  <li>
+    <button @click="$emit('click')"><slot /></button>
+  </li>
+</template>
+
+<script lang="ts">
+  import Vue from 'vue';
+  import Component from 'vue-class-component';
+
+  @Component
+  export default class DropdownItemButton extends Vue {}
+</script>
+
+<style lang="scss" scoped></style>

+ 25 - 0
desktop/core/src/desktop/js/components/dropdown/DropdownItemText.test.ts

@@ -0,0 +1,25 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// 'License'); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an 'AS IS' BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { shallowMount } from '@vue/test-utils';
+import DropdownItemText from './DropdownItemText.vue';
+
+describe('DropdownItemText.vue', () => {
+  it('should render', () => {
+    const wrapper = shallowMount(DropdownItemText);
+    expect(wrapper.element).toMatchSnapshot();
+  });
+});

+ 45 - 0
desktop/core/src/desktop/js/components/dropdown/DropdownItemText.vue

@@ -0,0 +1,45 @@
+<!--
+  Licensed to Cloudera, Inc. under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  Cloudera, Inc. licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<template>
+  <li class="hue-dropdown-item-text">
+    {{ text }}
+    <slot />
+  </li>
+</template>
+
+<script lang="ts">
+  import Vue from 'vue';
+  import Component from 'vue-class-component';
+  import { Prop } from 'vue-property-decorator';
+
+  @Component
+  export default class DropdownItemText extends Vue {
+    @Prop({ required: false, default: '' })
+    text;
+  }
+</script>
+
+<style lang="scss" scoped>
+  @import '../styles/colors';
+
+  .hue-dropdown-item-text {
+    padding: 6px 16px;
+    color: $cui-gray-800;
+  }
+</style>

+ 59 - 0
desktop/core/src/desktop/js/components/dropdown/__snapshots__/Dropdown.test.ts.snap

@@ -0,0 +1,59 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Dropdown.vue should render dropdown with slots 1`] = `
+<div
+  class=""
+>
+  <button
+    class="btn"
+    type="button"
+  >
+    
+     
+    <i
+      class="fa fa-caret-down"
+    />
+  </button>
+   
+  <div
+    class="hue-dropdown-container"
+  >
+    <div
+      class="hue-dropdown-menu"
+    >
+      <ul>
+        <div>
+          Some item
+        </div>
+      </ul>
+    </div>
+  </div>
+</div>
+`;
+
+exports[`Dropdown.vue should render empty dropdown 1`] = `
+<div
+  class=""
+>
+  <button
+    class="btn"
+    type="button"
+  >
+    
+     
+    <i
+      class="fa fa-caret-down"
+    />
+  </button>
+   
+  <div
+    class="hue-dropdown-container"
+  >
+    <div
+      class="hue-dropdown-menu"
+    >
+      <ul />
+    </div>
+  </div>
+</div>
+`;

+ 13 - 0
desktop/core/src/desktop/js/components/dropdown/__snapshots__/DropdownGroup.test.ts.snap

@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`DropdownGroup.vue should render 1`] = `
+<li>
+  <header
+    class="dropdown-group-header"
+  >
+    Some Header
+  </header>
+   
+  <ul />
+</li>
+`;

+ 9 - 0
desktop/core/src/desktop/js/components/dropdown/__snapshots__/DropdownItem.test.ts.snap

@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`DropdownItem.vue should render 1`] = `
+<li>
+  
+  
+  
+</li>
+`;

+ 7 - 0
desktop/core/src/desktop/js/components/dropdown/__snapshots__/DropdownItemButton.test.ts.snap

@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`DropdownItemButton.vue should render 1`] = `
+<li>
+  <button />
+</li>
+`;

+ 11 - 0
desktop/core/src/desktop/js/components/dropdown/__snapshots__/DropdownItemText.test.ts.snap

@@ -0,0 +1,11 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`DropdownItemText.vue should render 1`] = `
+<li
+  class="hue-dropdown-item-text"
+>
+  
+  
+  
+</li>
+`;