You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
4.0 KiB

2 years ago
  1. <template>
  2. <div class="group tw-mb-[20px]">
  3. <div class="tw-flex tw-justify-between tw-items-center tw-mb-[20px]">
  4. <h3 class="t14 tw-font-bold tw-mb-0 md:t16">{{ $t(label) }}</h3>
  5. <button class="'seeMore tw-transition tw-btn-md tw-body-4 tw-text-secondary-default tw-px-[16px] tw-py-[9px]"
  6. @click="clearAll()">
  7. {{ $t("Clear all") }}
  8. </button>
  9. </div>
  10. <div>
  11. <div class="optionGroup tw-border tw-rounded-[10px] tw-bg-white tw-p-[15px]">
  12. <selectOption v-for="(item, index) in packages" :key="index" :index="index" :item="item" :hasValue="hasValue"
  13. :seeMore="seeMore" @disabled="disabled($event)" @selected="total($event)">
  14. </selectOption>
  15. </div>
  16. <button v-show="length !== undefined && length > 3" :class="[
  17. 'seeMore tw-transition tw-btn-md tw-text-primary-1 tw-border tw-border-solid tw-border-primary-1 tw-px-[30px] tw-py-[8.5px] tw-mt-[20px] tw-w-full tw-rounded-xl hover:tw-bg-primary-3 xl:hover:tw-bg-transparent xl:tw-border-none',
  18. seeMore ? 'open' : '',
  19. ]" @click="seeMore = !seeMore">
  20. {{ $t(seeMoreText) }}
  21. </button>
  22. </div>
  23. </div>
  24. </template>
  25. <script>
  26. import selectOption from "./selectOption.vue";
  27. export default {
  28. components: {
  29. selectOption,
  30. },
  31. props: {
  32. label: {
  33. type: String,
  34. },
  35. packages: {
  36. type: Array,
  37. },
  38. choices: {
  39. type: Array
  40. },
  41. },
  42. data() {
  43. return {
  44. hasValue: null,
  45. totalPrice: [],
  46. seeMore: false,
  47. };
  48. },
  49. computed: {
  50. seeMoreText() {
  51. if (this.seeMore == false) {
  52. return "See more";
  53. } else {
  54. return "See less";
  55. }
  56. },
  57. length() {
  58. if (this.packages) {
  59. return this.packages.length;
  60. } else {
  61. return 0;
  62. }
  63. },
  64. },
  65. watch: {
  66. },
  67. methods: {
  68. disabled(i) {
  69. this.hasValue = i;
  70. },
  71. total(obj) {
  72. let hasObj = this.totalPrice.some(
  73. (item) => item.spec_id == obj.spec_id
  74. );
  75. if (!hasObj) {
  76. this.totalPrice.push(obj);
  77. } else {
  78. let oldObj = this.totalPrice.find((f) => f.spec_id == obj.spec_id);
  79. if (oldObj) {
  80. oldObj.spec_name = obj.spec_name;
  81. oldObj.number = obj.number;
  82. oldObj.total = obj.total;
  83. }
  84. }
  85. this.$emit("totalPrice", this.totalPrice);
  86. },
  87. clearAll() {
  88. this.hasValue = null;
  89. this.totalPrice = [];
  90. this.$emit("totalPrice", []);
  91. },
  92. },
  93. };
  94. </script>
  95. <style lang="scss" scoped>
  96. .custom-button {
  97. background-position: center;
  98. background-repeat: no-repeat;
  99. background-size: 12px;
  100. }
  101. .button {
  102. &-reduce {
  103. background-image: url("~/assets/svg/reduce.svg");
  104. background-color: #e5e5e5;
  105. }
  106. &-add {
  107. background-image: url("~/assets/svg/add.svg");
  108. background-color: #f48800;
  109. }
  110. }
  111. :deep() {
  112. .optionGroup {
  113. .optionItem:last-child {
  114. border: none !important;
  115. margin: 0 !important;
  116. padding: 0 !important;
  117. }
  118. }
  119. }
  120. .seeMore {
  121. &-hide {
  122. position: relative;
  123. max-height: 295px;
  124. overflow: hidden;
  125. &::after {
  126. content: "";
  127. display: block;
  128. position: absolute;
  129. background: url("~/assets/img/gradient_white.png") repeat-x left bottom;
  130. width: 100%;
  131. height: 130px;
  132. left: 0;
  133. bottom: 0;
  134. z-index: 1;
  135. transition: bottom 0.5s;
  136. }
  137. }
  138. &-show {
  139. position: relative;
  140. max-height: 100%;
  141. overflow: initial;
  142. &::after {
  143. display: none;
  144. }
  145. }
  146. @media screen and (min-width: 1366px) {
  147. position: relative;
  148. display: flex;
  149. align-items: center;
  150. justify-content: center;
  151. &::after {
  152. content: "";
  153. display: inline-block;
  154. position: relative;
  155. background-image: url("~/assets/svg/arrow-down-primary.svg");
  156. background-position: center center;
  157. background-repeat: no-repeat;
  158. background-size: 100%;
  159. width: 9px;
  160. height: 6px;
  161. margin-left: 16px;
  162. transition: all 0.2s linear;
  163. }
  164. &.open {
  165. &::after {
  166. transform: rotate(180deg);
  167. }
  168. }
  169. }
  170. }
  171. </style>