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.

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