Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

664 Zeilen
22 KiB

  1. <template>
  2. <view class="u-calendar-month-wrapper" ref="u-calendar-month-wrapper">
  3. <view v-for="(item, index) in months" :key="index" :class="[`u-calendar-month-${index}`]"
  4. :ref="`u-calendar-month-${index}`" :id="`month-${index}`">
  5. <text v-if="index !== 0" class="u-calendar-month__title">{{ monthTitle(item) }}</text>
  6. <view class="u-calendar-month__days">
  7. <view v-if="showMark" class="u-calendar-month__days__month-mark-wrapper">
  8. <text class="u-calendar-month__days__month-mark-wrapper__text">{{ item.month }}</text>
  9. </view>
  10. <view class="u-calendar-month__days__day" v-for="(item1, index1) in item.date" :key="index1"
  11. :style="[dayStyle(index, index1, item1)]" @tap="clickHandler(index, index1, item1)"
  12. :class="[item1.selected && 'u-calendar-month__days__day__select--selected']">
  13. <view class="u-calendar-month__days__day__select" :style="[daySelectStyle(index, index1, item1)]">
  14. <text class="u-calendar-month__days__day__select__info"
  15. :class="[(item1.disabled || isForbid(item1) ) ? 'u-calendar-month__days__day__select__info--disabled' : '']"
  16. :style="[textStyle(item1)]">{{ item1.day }}</text>
  17. <text v-if="getBottomInfo(index, index1, item1)"
  18. class="u-calendar-month__days__day__select__buttom-info"
  19. :class="[(item1.disabled || isForbid(item1) ) ? 'u-calendar-month__days__day__select__buttom-info--disabled' : '']"
  20. :style="[textStyle(item1)]">{{ getBottomInfo(index, index1, item1) }}</text>
  21. <text v-if="item1.dot" class="u-calendar-month__days__day__select__dot"></text>
  22. </view>
  23. </view>
  24. </view>
  25. </view>
  26. </view>
  27. </template>
  28. <script>
  29. // #ifdef APP-NVUE
  30. // 由于nvue不支持百分比单位,需要查询宽度来计算每个日期的宽度
  31. const dom = uni.requireNativePlugin('dom')
  32. // #endif
  33. import { mpMixin } from '../../libs/mixin/mpMixin';
  34. import { mixin } from '../../libs/mixin/mixin';
  35. import { addUnit, deepClone, toast, sleep, getWindowInfo } from '../../libs/function/index';
  36. import { colorGradient } from '../../libs/function/colorGradient';
  37. import test from '../../libs/function/test';
  38. import defProps from '../../libs/config/props';
  39. import dayjs from '../u-datetime-picker/dayjs.esm.min.js';
  40. import { t } from '../../libs/i18n'
  41. export default {
  42. name: 'u-calendar-month',
  43. mixins: [mpMixin, mixin],
  44. props: {
  45. // 是否显示月份背景色
  46. showMark: {
  47. type: Boolean,
  48. default: true
  49. },
  50. // 主题色,对底部按钮和选中日期有效
  51. color: {
  52. type: String,
  53. default: '#3c9cff'
  54. },
  55. // 月份数据
  56. months: {
  57. type: Array,
  58. default: () => []
  59. },
  60. // 日期选择类型
  61. mode: {
  62. type: String,
  63. default: 'single'
  64. },
  65. // 日期行高
  66. rowHeight: {
  67. type: [String, Number],
  68. default: 58
  69. },
  70. // mode=multiple时,最多可选多少个日期
  71. maxCount: {
  72. type: [String, Number],
  73. default: Infinity
  74. },
  75. // mode=range时,第一个日期底部的提示文字
  76. startText: {
  77. type: String,
  78. default: '开始'
  79. },
  80. // mode=range时,最后一个日期底部的提示文字
  81. endText: {
  82. type: String,
  83. default: '结束'
  84. },
  85. // 默认选中的日期,mode为multiple或range是必须为数组格式
  86. defaultDate: {
  87. type: [Array, String, Date],
  88. default: null
  89. },
  90. // 最小的可选日期
  91. minDate: {
  92. type: [String, Number],
  93. default: 0
  94. },
  95. // 最大可选日期
  96. maxDate: {
  97. type: [String, Number],
  98. default: 0
  99. },
  100. // 如果没有设置maxDate,则往后推多少个月
  101. maxMonth: {
  102. type: [String, Number],
  103. default: 2
  104. },
  105. // 是否为只读状态,只读状态下禁止选择日期
  106. readonly: {
  107. type: Boolean,
  108. default: () => defProps.calendar.readonly
  109. },
  110. // 日期区间最多可选天数,默认无限制,mode = range时有效
  111. maxRange: {
  112. type: [Number, String],
  113. default: Infinity
  114. },
  115. // 范围选择超过最多可选天数时的提示文案,mode = range时有效
  116. rangePrompt: {
  117. type: String,
  118. default: ''
  119. },
  120. // 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效
  121. showRangePrompt: {
  122. type: Boolean,
  123. default: true
  124. },
  125. // 是否允许日期范围的起止时间为同一天,mode = range时有效
  126. allowSameDay: {
  127. type: Boolean,
  128. default: false
  129. },
  130. forbidDays: {
  131. type: Array,
  132. default: () => []
  133. },
  134. forbidDaysToast: {
  135. type: String,
  136. default: ''
  137. },
  138. // 今天日期,用于独立高亮
  139. todayDate: {
  140. type: String,
  141. default: ''
  142. },
  143. // 今天日期的独立高亮颜色
  144. todayColor: {
  145. type: String,
  146. default: ''
  147. }
  148. },
  149. data() {
  150. return {
  151. // 每个日期的宽度
  152. width: 0,
  153. // 当前选中的日期item
  154. item: {},
  155. selected: []
  156. }
  157. },
  158. watch: {
  159. selectedChange: {
  160. immediate: true,
  161. handler(n) {
  162. this.setDefaultDate()
  163. }
  164. }
  165. },
  166. computed: {
  167. // 多个条件的变化,会引起选中日期的变化,这里统一管理监听
  168. selectedChange() {
  169. return [this.minDate, this.maxDate, this.defaultDate]
  170. },
  171. dayStyle(index1, index2, item) {
  172. return (index1, index2, item) => {
  173. const style = {}
  174. let week = item.week
  175. // 隐藏挂载场景下节点宽度可能拿到0,兜底使用窗口宽度避免首日偏移归零
  176. const wrapperWidth = this.width > 0 ? this.width : (getWindowInfo().windowWidth || 0)
  177. // 不进行四舍五入的形式保留2位小数
  178. const dayWidth = Number(parseFloat(wrapperWidth / 7).toFixed(3).slice(0, -1))
  179. // 得出每个日期的宽度
  180. // #ifdef APP-NVUE
  181. style.width = addUnit(dayWidth, 'px')
  182. // #endif
  183. style.height = addUnit(this.rowHeight, 'px')
  184. if (index2 === 0) {
  185. // 获取当前为星期几,如果为0,则为星期天,减一为每月第一天时,需要向左偏移的item个数
  186. week = (week === 0 ? 7 : week) - 1
  187. // #ifdef APP-NVUE
  188. style.marginLeft = addUnit(week * dayWidth, 'px')
  189. // #endif
  190. // #ifndef APP-NVUE
  191. style.marginLeft = `${(week / 7) * 100}%`
  192. // #endif
  193. }
  194. if (this.mode === 'range') {
  195. // 之所以需要这么写,是因为DCloud公司的iOS客户端导致的bug
  196. style.paddingLeft = 0
  197. style.paddingRight = 0
  198. style.paddingBottom = 0
  199. style.paddingTop = 0
  200. }
  201. return style
  202. }
  203. },
  204. daySelectStyle() {
  205. return (index1, index2, item) => {
  206. let date = dayjs(item.date).format("YYYY-MM-DD"),
  207. style = {}
  208. // 判断date是否在selected数组中,因为月份可能会需要补0,所以使用dateSame判断,而不用数组的includes判断
  209. if (this.selected.some(item => this.dateSame(item, date))) {
  210. style.backgroundColor = this.color
  211. }
  212. if (this.todayDate && this.dateSame(date, this.todayDate)) {
  213. style.border = `1px solid ${this.resolvedTodayColor}`
  214. style.boxSizing = 'border-box'
  215. }
  216. if (this.mode === 'single') {
  217. if (date === this.selected[0]) {
  218. // 因为需要对nvue的兼容,只能这么写,无法缩写,也无法通过类名控制等等
  219. style.borderTopLeftRadius = '3px'
  220. style.borderBottomLeftRadius = '3px'
  221. style.borderTopRightRadius = '3px'
  222. style.borderBottomRightRadius = '3px'
  223. }
  224. } else if (this.mode === 'range') {
  225. if (this.selected.length >= 2) {
  226. const len = this.selected.length - 1
  227. // 第一个日期设置左上角和左下角的圆角
  228. if (this.dateSame(date, this.selected[0])) {
  229. style.borderTopLeftRadius = '3px'
  230. style.borderBottomLeftRadius = '3px'
  231. }
  232. // 最后一个日期设置右上角和右下角的圆角
  233. if (this.dateSame(date, this.selected[len])) {
  234. style.borderTopRightRadius = '3px'
  235. style.borderBottomRightRadius = '3px'
  236. }
  237. // 处于第一和最后一个之间的日期,背景色设置为浅色,通过将对应颜色进行等分,再取其尾部的颜色值
  238. if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
  239. .selected[len]))) {
  240. const rangeEndColor = this.upThemeVar('--up-card-bg-color', this.upThemeIsDark ? '#1c1c1e' : '#ffffff')
  241. style.backgroundColor = colorGradient(this.color, rangeEndColor, 100)[90]
  242. // 增加一个透明度,让范围区间的背景色也能看到底部的mark水印字符
  243. style.opacity = this.upThemeIsDark ? 0.85 : 0.7
  244. }
  245. } else if (this.selected.length === 1) {
  246. // 之所以需要这么写,是因为uni-app的iOS客户端的bug
  247. // 进行还原操作,否则在nvue的iOS,uni-app有bug,会导致诡异的表现
  248. style.borderTopLeftRadius = '3px'
  249. style.borderBottomLeftRadius = '3px'
  250. }
  251. } else {
  252. if (this.selected.some(item => this.dateSame(item, date))) {
  253. style.borderTopLeftRadius = '3px'
  254. style.borderBottomLeftRadius = '3px'
  255. style.borderTopRightRadius = '3px'
  256. style.borderBottomRightRadius = '3px'
  257. }
  258. }
  259. return style
  260. }
  261. },
  262. resolvedTodayColor() {
  263. return this.todayColor || this.color
  264. },
  265. // 某个日期是否被选中
  266. textStyle() {
  267. return (item) => {
  268. const date = dayjs(item.date).format("YYYY-MM-DD"),
  269. style = {}
  270. // 选中的日期,提示文字设置白色
  271. if (this.selected.some(item => this.dateSame(item, date))) {
  272. style.color = '#ffffff'
  273. }
  274. if (this.mode === 'range') {
  275. const len = this.selected.length - 1
  276. // 如果是范围选择模式,第一个和最后一个之间的日期,文字颜色设置为高亮的主题色
  277. if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
  278. .selected[len]))) {
  279. style.color = this.color
  280. }
  281. }
  282. if (this.todayDate && this.dateSame(date, this.todayDate) && !this.isSelectedDate(date)) {
  283. style.color = this.resolvedTodayColor
  284. }
  285. return style
  286. }
  287. },
  288. // 获取底部的提示文字
  289. getBottomInfo() {
  290. return (index1, index2, item) => {
  291. const date = dayjs(item.date).format("YYYY-MM-DD")
  292. const bottomInfo = item.bottomInfo
  293. // 当为日期范围模式时,且选择的日期个数大于0时
  294. if (this.mode === 'range' && this.selected.length > 0) {
  295. if (this.selected.length === 1) {
  296. // 选择了一个日期时,如果当前日期为数组中的第一个日期,则显示底部文字为“开始”
  297. if (this.dateSame(date, this.selected[0])) return this.startText
  298. else return bottomInfo
  299. } else {
  300. const len = this.selected.length - 1
  301. // 如果数组中的日期大于2个时,第一个和最后一个显示为开始和结束日期
  302. if (this.dateSame(date, this.selected[0]) && this.dateSame(date, this.selected[1]) &&
  303. len === 1) {
  304. // 如果长度为2,且第一个等于第二个日期,则提示语放在同一个item中
  305. return `${this.startText}/${this.endText}`
  306. } else if (this.dateSame(date, this.selected[0])) {
  307. return this.startText
  308. } else if (this.dateSame(date, this.selected[len])) {
  309. return this.endText
  310. } else {
  311. return bottomInfo
  312. }
  313. }
  314. } else {
  315. return bottomInfo
  316. }
  317. }
  318. }
  319. },
  320. mounted() {
  321. this.init()
  322. },
  323. emits: ['monthSelected', 'updateMonthTop'],
  324. methods: {
  325. init() {
  326. // 初始化默认选中
  327. this.$emit('monthSelected', this.selected)
  328. this.$nextTick(() => {
  329. // 这里需要另一个延时,因为获取宽度后,会进行月份数据渲染,只有渲染完成之后,才有真正的高度
  330. // 因为nvue下,$nextTick并不是100%可靠的
  331. sleep(10).then(() => {
  332. this.getWrapperWidth()
  333. this.getMonthRect()
  334. })
  335. })
  336. },
  337. monthTitle(item) {
  338. if (uni.getLocale() == 'zh-Hans' || uni.getLocale() == 'zh-Hant') {
  339. return item.year + '年' + (item.month < 10 ? '0' + item.month : item.month) + '月'
  340. } else {
  341. return (item.month < 10 ? '0' + item.month : item.month) + '/' + item.year
  342. }
  343. },
  344. isForbid(item) {
  345. let date = dayjs(item.date).format("YYYY-MM-DD")
  346. if (this.mode !== 'range' && this.forbidDays.includes(date)) {
  347. return true
  348. }
  349. return false
  350. },
  351. // 判断两个日期是否相等
  352. dateSame(date1, date2) {
  353. return dayjs(date1).isSame(dayjs(date2))
  354. },
  355. isSelectedDate(date) {
  356. return this.selected.some(item => this.dateSame(item, date))
  357. },
  358. // 获取月份数据区域的宽度,因为nvue不支持百分比,所以无法通过css设置每个日期item的宽度
  359. getWrapperWidth() {
  360. // #ifdef APP-NVUE
  361. dom.getComponentRect(this.$refs['u-calendar-month-wrapper'], res => {
  362. const width = res && res.size ? Number(res.size.width) : 0
  363. this.width = width > 0 ? width : (getWindowInfo().windowWidth || 0)
  364. })
  365. // #endif
  366. // #ifndef APP-NVUE
  367. this.$uGetRect('.u-calendar-month-wrapper').then(size => {
  368. const width = size ? Number(size.width) : 0
  369. this.width = width > 0 ? width : (getWindowInfo().windowWidth || 0)
  370. })
  371. // #endif
  372. },
  373. getMonthRect() {
  374. // 获取每个月份数据的尺寸,用于父组件在scroll-view滚动事件中,监听当前滚动到了第几个月份
  375. const promiseAllArr = this.months.map((item, index) => this.getMonthRectByPromise(
  376. `u-calendar-month-${index}`))
  377. // 一次性返回
  378. Promise.all(promiseAllArr).then(
  379. sizes => {
  380. let height = 1
  381. const topArr = []
  382. for (let i = 0; i < this.months.length; i++) {
  383. // 添加到months数组中,供scroll-view滚动事件中,判断当前滚动到哪个月份
  384. topArr[i] = height
  385. height += sizes[i].height
  386. }
  387. // 由于微信下,无法通过this.months[i].top的形式(引用类型)去修改父组件的month的top值,所以使用事件形式对外发出
  388. this.$emit('updateMonthTop', topArr)
  389. })
  390. },
  391. // 获取每个月份区域的尺寸
  392. getMonthRectByPromise(el) {
  393. // #ifndef APP-NVUE
  394. // $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://uview-plus.jiangruyi.com/js/getRect.html
  395. // 组件内部一般用this.$uGetRect,对外的为uni.$u.getRect,二者功能一致,名称不同
  396. return new Promise(resolve => {
  397. this.$uGetRect(`.${el}`).then(size => {
  398. resolve(size)
  399. })
  400. })
  401. // #endif
  402. // #ifdef APP-NVUE
  403. // nvue下,使用dom模块查询元素高度
  404. // 返回一个promise,让调用此方法的主体能使用then回调
  405. return new Promise(resolve => {
  406. dom.getComponentRect(this.$refs[el][0], res => {
  407. resolve(res.size)
  408. })
  409. })
  410. // #endif
  411. },
  412. // 点击某一个日期
  413. clickHandler(index1, index2, item) {
  414. if (this.readonly) {
  415. return;
  416. }
  417. this.item = item
  418. const date = dayjs(item.date).format("YYYY-MM-DD")
  419. if (item.disabled) return
  420. if (this.isForbid(item)) {
  421. uni.showToast({
  422. title: this.forbidDaysToast
  423. })
  424. return
  425. }
  426. // 对上一次选择的日期数组进行深度克隆
  427. let selected = deepClone(this.selected)
  428. if (this.mode === 'single') {
  429. // 单选情况下,让数组中的元素为当前点击的日期
  430. selected = [date]
  431. } else if (this.mode === 'multiple') {
  432. if (selected.some(item => this.dateSame(item, date))) {
  433. // 如果点击的日期已在数组中,则进行移除操作,也就是达到反选的效果
  434. const itemIndex = selected.findIndex(item => item === date)
  435. selected.splice(itemIndex, 1)
  436. } else {
  437. // 如果点击的日期不在数组中,且已有的长度小于总可选长度时,则添加到数组中去
  438. if (selected.length < this.maxCount) selected.push(date)
  439. }
  440. } else {
  441. // 选择区间形式
  442. if (selected.length === 0 || selected.length >= 2) {
  443. // 如果原来就为0或者大于2的长度,则当前点击的日期,就是开始日期
  444. selected = [date]
  445. } else if (selected.length === 1) {
  446. // 如果已经选择了开始日期
  447. const existsDate = selected[0]
  448. // 如果当前选择的日期小于上一次选择的日期,则当前的日期定为开始日期
  449. if (dayjs(date).isBefore(existsDate)) {
  450. selected = [date]
  451. } else if (dayjs(date).isAfter(existsDate)) {
  452. // 当前日期减去最大可选的日期天数,如果大于起始时间,则进行提示
  453. if(dayjs(dayjs(date).subtract(this.maxRange, 'day')).isAfter(dayjs(selected[0])) && this.showRangePrompt) {
  454. if(this.rangePrompt) {
  455. toast(this.rangePrompt)
  456. } else {
  457. toast(t("up.calendar.daysExceed", { days: this.maxRange }))
  458. }
  459. return
  460. }
  461. // 如果当前日期大于已有日期,将当前的添加到数组尾部
  462. selected.push(date)
  463. const startDate = selected[0]
  464. const endDate = selected[1]
  465. const arr = []
  466. let i = 0
  467. do {
  468. // 将开始和结束日期之间的日期添加到数组中
  469. arr.push(dayjs(startDate).add(i, 'day').format("YYYY-MM-DD"))
  470. i++
  471. // 累加的日期小于结束日期时,继续下一次的循环
  472. } while (dayjs(startDate).add(i, 'day').isBefore(dayjs(endDate)))
  473. // 为了一次性修改数组,避免computed中多次触发,这里才用arr变量一次性赋值的方式,同时将最后一个日期添加近来
  474. arr.push(endDate)
  475. selected = arr
  476. } else {
  477. // 选择区间时,只有一个日期的情况下,且不允许选择起止为同一天的话,不允许选择自己
  478. if (selected[0] === date && !this.allowSameDay) return
  479. selected.push(date)
  480. }
  481. }
  482. }
  483. this.setSelected(selected)
  484. },
  485. // 设置默认日期
  486. setDefaultDate() {
  487. if (!this.defaultDate) {
  488. // 如果没有设置默认日期,则将当天日期设置为默认选中的日期
  489. const selected = [dayjs().format("YYYY-MM-DD")]
  490. return this.setSelected(selected, false)
  491. }
  492. let defaultDate = []
  493. const minDate = this.minDate || dayjs().format("YYYY-MM-DD")
  494. const maxDate = this.maxDate || dayjs(minDate).add(this.maxMonth - 1, 'month').format("YYYY-MM-DD")
  495. if (this.mode === 'single') {
  496. // 单选模式,可以是字符串或数组,Date对象等
  497. if (!test.array(this.defaultDate)) {
  498. defaultDate = [dayjs(this.defaultDate).format("YYYY-MM-DD")]
  499. } else {
  500. defaultDate = [this.defaultDate[0]]
  501. }
  502. } else {
  503. // 如果为非数组,则不执行
  504. if (!test.array(this.defaultDate)) return
  505. defaultDate = this.defaultDate
  506. }
  507. // 过滤用户传递的默认数组,取出只在可允许最大值与最小值之间的元素
  508. defaultDate = defaultDate.filter(item => {
  509. return dayjs(item).isAfter(dayjs(minDate).subtract(1, 'day')) && dayjs(item).isBefore(dayjs(
  510. maxDate).add(1, 'day'))
  511. })
  512. this.setSelected(defaultDate, false)
  513. },
  514. setSelected(selected, event = true) {
  515. this.selected = selected
  516. event && this.$emit('monthSelected', this.selected,'tap')
  517. },
  518. selectDate(date) {
  519. const targetDate = dayjs(date).format("YYYY-MM-DD")
  520. for (let monthIndex = 0; monthIndex < this.months.length; monthIndex++) {
  521. const dayIndex = this.months[monthIndex].date.findIndex(item => {
  522. return this.dateSame(item.date, targetDate)
  523. })
  524. if (dayIndex !== -1) {
  525. this.clickHandler(monthIndex, dayIndex, this.months[monthIndex].date[dayIndex])
  526. return
  527. }
  528. }
  529. }
  530. }
  531. }
  532. </script>
  533. <style lang="scss" scoped>
  534. .u-calendar-month-wrapper {
  535. margin-top: 4px;
  536. }
  537. .u-calendar-month {
  538. &__title {
  539. display: flex;
  540. flex-direction: column;
  541. font-size: 14px;
  542. line-height: 42px;
  543. height: 42px;
  544. color: var(--up-main-color, $u-main-color);
  545. text-align: center;
  546. font-weight: bold;
  547. }
  548. &__days {
  549. position: relative;
  550. @include flex;
  551. flex-wrap: wrap;
  552. &__month-mark-wrapper {
  553. position: absolute;
  554. top: 0;
  555. bottom: 0;
  556. left: 0;
  557. right: 0;
  558. @include flex;
  559. justify-content: center;
  560. align-items: center;
  561. &__text {
  562. font-size: 155px;
  563. color: var(--up-calendar-month-mark-color, rgba(231, 232, 234, 0.83));
  564. }
  565. }
  566. &__day {
  567. @include flex;
  568. padding: 2px;
  569. /* #ifndef APP-NVUE */
  570. // vue下使用css进行宽度计算,因为某些安卓机会无法进行js获取父元素宽度进行计算得出,会有偏移
  571. width: calc(100% / 7);
  572. box-sizing: border-box;
  573. /* #endif */
  574. &__select {
  575. flex: 1;
  576. @include flex;
  577. align-items: center;
  578. justify-content: center;
  579. position: relative;
  580. &__dot {
  581. width: 7px;
  582. height: 7px;
  583. border-radius: 100px;
  584. background-color: $u-error;
  585. position: absolute;
  586. top: 12px;
  587. right: 7px;
  588. }
  589. &__buttom-info {
  590. color: var(--up-content-color, $u-content-color);
  591. text-align: center;
  592. position: absolute;
  593. bottom: 5px;
  594. font-size: 10px;
  595. text-align: center;
  596. left: 0;
  597. right: 0;
  598. &--selected {
  599. color: #ffffff;
  600. }
  601. &--disabled {
  602. color: var(--up-disabled-color, #cacbcd);
  603. }
  604. }
  605. &__info {
  606. text-align: center;
  607. font-size: 16px;
  608. color: var(--up-main-color, $u-main-color);
  609. &--selected {
  610. color: #ffffff;
  611. }
  612. &--disabled {
  613. color: var(--up-disabled-color, #cacbcd);
  614. }
  615. }
  616. &--selected {
  617. background-color: $u-primary;
  618. @include flex;
  619. justify-content: center;
  620. align-items: center;
  621. flex: 1;
  622. border-radius: 3px;
  623. }
  624. &--range-selected {
  625. opacity: 0.3;
  626. border-radius: 0;
  627. }
  628. &--range-start-selected {
  629. border-top-right-radius: 0;
  630. border-bottom-right-radius: 0;
  631. }
  632. &--range-end-selected {
  633. border-top-left-radius: 0;
  634. border-bottom-left-radius: 0;
  635. }
  636. }
  637. }
  638. }
  639. }
  640. </style>