<script lang="ts">
export enum TabType {
  Year = 0,
  Month = 1,
  Day = 2,
  Hour = 3,
  Minute = 4,
}
</script>

<script setup lang="ts">
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import {
  MIN_YEAR,
  MAX_YEAR,
  MIN_DATETIME,
  MAX_DATETIME,
  MONTH_DAY_COUNT,
  dayOfWeek,
  isLeapYear,
} from '@/utils/datetime';
import { i18n, universalGetMonth } from '@/utils/i18n';

// region: Constants

const ALL_TABS: TabType[] = [TabType.Year, TabType.Month, TabType.Day, TabType.Hour, TabType.Minute];

const DIAL_PLATE_WIDTH = 200;
const DIAL_PLATE_RADIUS = DIAL_PLATE_WIDTH / 2;
const DIAL_PLATE_HOUR_INNER_PERCENT = 0.6;
const DIAL_PLATE_HOUR_OUTER_PERCENT = 0.8;
const DIAL_PLATE_HOUR_DISTINGUISH_PERCENT = 0.7;
const DIAL_PLATE_MINUTE_PERCENT = 0.8;
const DIAL_PLATE_HOUR_RESOLUTION = Math.PI * 2 / 12;
const DIAL_PLATE_MINUTE_RESOLUTION = Math.PI * 2 / 60;

// endregion

// region: State

const isVisible = ref<boolean>(false);
const mode = ref<TabType>(TabType.Day);
const currentTab = ref<TabType>(TabType.Day);

const internalDateTime = ref<Date>(new Date());
const displayCacheDateTime = ref<Date>(new Date());

const enableHourDrag = ref<boolean>(false);
const enableMinuteDrag = ref<boolean>(false);

const hourSvgEl = ref<SVGSVGElement | null>(null);
const minuteSvgEl = ref<SVGSVGElement | null>(null);
const pickerBodyEl = ref<HTMLElement | null>(null);
const svgFontEm = ref<number>(1);

// endregion

// region: Exposed API

const emit = defineEmits<{
  (e: 'confirm', date: Date): void
  (e: 'cancel'): void
}>();

/**
 * Open the picker seeded with `initialDate`, with the deepest selectable tab
 * set to `modeType`.
 *
 * NOTE: The DateTimePicker ALWAYS edits the passed Date via LOCAL accessors
 * (getFullYear / getMonth / getDate / getHours / getMinutes). It performs NO
 * timezone conversion. If the value represents a wall-clock in a non-browser
 * timezone, the CALLER must pre-construct a Date whose LOCAL components equal
 * that wall-clock, and recompute any timestamp from the components afterwards.
 */
const modal = (initialDate: Date, modeType: TabType) => {
  internalDateTime.value = new Date(initialDate.getTime());
  displayCacheDateTime.value = new Date(initialDate.getTime());
  mode.value = modeType;
  currentTab.value = modeType;
  isVisible.value = true;
}

const confirm = () => {
  isVisible.value = false;
  emit('confirm', new Date(internalDateTime.value.getTime()));
}

const cancel = () => {
  isVisible.value = false;
  emit('cancel');
}

defineExpose({ modal })

// endregion

// region: Helpers

const cloneDate = (d: Date): Date => new Date(d.getTime());

const clampDateTime = (d: Date): void => {
  if (d < MIN_DATETIME) d.setTime(MIN_DATETIME.getTime());
  if (d >= MAX_DATETIME) d.setTime(MAX_DATETIME.getTime());
}

const switchTab = (newTab: TabType): void => {
  displayCacheDateTime.value = new Date(internalDateTime.value.getTime());
  currentTab.value = newTab;
}

// endregion

// region: Header

const visibleTabs = computed<TabType[]>(() => ALL_TABS.filter(t => t <= mode.value));

const isYearTab = computed<boolean>(() => currentTab.value === TabType.Year);
const isMonthTab = computed<boolean>(() => currentTab.value === TabType.Month);
const isDayTab = computed<boolean>(() => currentTab.value === TabType.Day);
const isHourTab = computed<boolean>(() => currentTab.value === TabType.Hour);
const isMinuteTab = computed<boolean>(() => currentTab.value === TabType.Minute);

const tabLabel = (t: TabType): string => {
  if (t === TabType.Year) return i18n.global.t('universal-text-year');
  if (t === TabType.Month) return i18n.global.t('universal-text-month');
  if (t === TabType.Day) return i18n.global.t('universal-text-day');
  if (t === TabType.Hour) return i18n.global.t('universal-text-hour');
  return i18n.global.t('universal-text-minute');
}

const headerValue = (t: TabType): number => {
  if (t === TabType.Year) return internalDateTime.value.getFullYear();
  if (t === TabType.Month) return internalDateTime.value.getMonth() + 1;
  if (t === TabType.Day) return internalDateTime.value.getDate();
  if (t === TabType.Hour) return internalDateTime.value.getHours();
  return internalDateTime.value.getMinutes();
}

// endregion

// region: Year Panel

const yearPanelStartYear = computed<number>(() => {
  return Math.floor((displayCacheDateTime.value.getFullYear() - MIN_YEAR) / 12) * 12 + MIN_YEAR;
})

interface Cell {
  value: number | null;
  picked: boolean;
}

const yearCells = computed<Cell[]>(() => {
  const start = yearPanelStartYear.value;
  const pickedYear = internalDateTime.value.getFullYear();
  const cells: Cell[] = [];
  for (let i = 0; i < 12; i++) {
    const v = start + i;
    cells.push({ value: v < MAX_YEAR ? v : null, picked: v === pickedYear && v < MAX_YEAR });
  }
  return cells;
})

const yearRows = computed<Cell[][]>(() => {
  const cells = yearCells.value;
  return [cells.slice(0, 4), cells.slice(4, 8), cells.slice(8, 12)];
})

const yearPanelTitle = computed<string>(() => {
  const start = yearPanelStartYear.value;
  const end = start + 12 < MAX_YEAR ? start + 12 : MAX_YEAR;
  return `${start} - ${end}`;
})

const prevNextYear = (isPrev: boolean): void => {
  const d = cloneDate(displayCacheDateTime.value);
  d.setFullYear(d.getFullYear() + (isPrev ? -12 : 12));
  clampDateTime(d);
  displayCacheDateTime.value = d;
}

const clickYear = (cell: Cell): void => {
  if (cell.value === null) return;
  const d = cloneDate(internalDateTime.value);
  d.setFullYear(cell.value);
  clampDateTime(d);
  internalDateTime.value = d;
  if (mode.value !== TabType.Year) switchTab(TabType.Month);
}

// endregion

// region: Month Panel

interface MonthCell {
  idx: number;
  name: string;
  picked: boolean;
}

const monthCells = computed<MonthCell[]>(() => {
  const sameYear = displayCacheDateTime.value.getFullYear() === internalDateTime.value.getFullYear();
  const pickedMonth = internalDateTime.value.getMonth();
  return Array.from({ length: 12 }, (_, idx) => ({
    idx,
    name: universalGetMonth(idx),
    picked: sameYear && idx === pickedMonth,
  }));
})

const monthRows = computed<MonthCell[][]>(() => {
  const cells = monthCells.value;
  return [cells.slice(0, 4), cells.slice(4, 8), cells.slice(8, 12)];
})

const monthPanelTitle = computed<string>(() => `${displayCacheDateTime.value.getFullYear()}`);

const prevNextMonth = (isPrev: boolean): void => {
  const d = cloneDate(displayCacheDateTime.value);
  d.setFullYear(d.getFullYear() + (isPrev ? -1 : 1));
  clampDateTime(d);
  displayCacheDateTime.value = d;
}

const clickMonth = (cell: MonthCell): void => {
  const d = cloneDate(internalDateTime.value);
  d.setFullYear(displayCacheDateTime.value.getFullYear(), cell.idx);
  clampDateTime(d);
  internalDateTime.value = d;
  if (mode.value !== TabType.Month) switchTab(TabType.Day);
}

// endregion

// region: Day Panel

const dayCells = computed<Cell[]>(() => {
  const year = displayCacheDateTime.value.getFullYear();
  const month1 = displayCacheDateTime.value.getMonth() + 1;
  const offset = dayOfWeek(year, month1, 1);
  const days = MONTH_DAY_COUNT[month1 - 1]! + ((month1 === 2 && isLeapYear(year)) ? 1 : 0);
  const sameYearMonth = displayCacheDateTime.value.getFullYear() === internalDateTime.value.getFullYear()
    && displayCacheDateTime.value.getMonth() === internalDateTime.value.getMonth();
  const pickedDay = sameYearMonth ? internalDateTime.value.getDate() : -1;
  const cells: Cell[] = [];
  for (let i = 0; i < 42; i++) {
    const counter = i - offset;
    if (counter < 0 || counter >= days) {
      cells.push({ value: null, picked: false });
    } else {
      const day = counter + 1;
      cells.push({ value: day, picked: day === pickedDay });
    }
  }
  return cells;
})

const dayRows = computed<Cell[][]>(() => {
  const cells = dayCells.value;
  const rows: Cell[][] = [];
  for (let i = 0; i < 6; i++) rows.push(cells.slice(i * 7, i * 7 + 7));
  return rows;
})

const dayPanelTitle = computed<string>(() => {
  return `${displayCacheDateTime.value.getFullYear()} - ${universalGetMonth(displayCacheDateTime.value.getMonth())}`;
})

const prevNextDay = (isPrev: boolean): void => {
  const d = cloneDate(displayCacheDateTime.value);
  d.setMonth(d.getMonth() + (isPrev ? -1 : 1));
  clampDateTime(d);
  displayCacheDateTime.value = d;
}

const clickDay = (cell: Cell): void => {
  if (cell.value === null) return;
  const d = cloneDate(internalDateTime.value);
  d.setFullYear(
    displayCacheDateTime.value.getFullYear(),
    displayCacheDateTime.value.getMonth(),
    cell.value);
  clampDateTime(d);
  internalDateTime.value = d;
  if (mode.value !== TabType.Day) switchTab(TabType.Hour);
}

// endregion

// region: Hour / Minute Dial

const hourHand = computed<{ x: number; y: number }>(() => {
  const h = displayCacheDateTime.value.getHours();
  const angle = (3 - h) * DIAL_PLATE_HOUR_RESOLUTION;
  const radius = DIAL_PLATE_RADIUS * (h < 12 ? DIAL_PLATE_HOUR_OUTER_PERCENT : DIAL_PLATE_HOUR_INNER_PERCENT);
  return {
    x: Math.cos(angle) * radius + DIAL_PLATE_RADIUS,
    y: -Math.sin(angle) * radius + DIAL_PLATE_RADIUS,
  };
})

const minuteHand = computed<{ x: number; y: number }>(() => {
  const m = displayCacheDateTime.value.getMinutes();
  const angle = (15 - m) * DIAL_PLATE_MINUTE_RESOLUTION;
  const radius = DIAL_PLATE_RADIUS * DIAL_PLATE_MINUTE_PERCENT;
  return {
    x: Math.cos(angle) * radius + DIAL_PLATE_RADIUS,
    y: -Math.sin(angle) * radius + DIAL_PLATE_RADIUS,
  };
})

// static numeric labels around each dial (positions match the legacy template)
const hourOuterLabels = computed(() => Array.from({ length: 12 }, (_, h) => {
  const a = h * DIAL_PLATE_HOUR_RESOLUTION;
  return { label: String(h), x: 100 + 80 * Math.sin(a), y: 100 - 80 * Math.cos(a) };
}))
const hourInnerLabels = computed(() => Array.from({ length: 12 }, (_, h) => {
  const a = h * DIAL_PLATE_HOUR_RESOLUTION;
  return { label: String(h + 12), x: 100 + 60 * Math.sin(a), y: 100 - 60 * Math.cos(a) };
}))
const minuteLabels = computed(() => Array.from({ length: 12 }, (_, i) => {
  const m = i * 5;
  const a = m * DIAL_PLATE_MINUTE_RESOLUTION;
  return { label: String(m), x: 100 + 80 * Math.sin(a), y: 100 - 80 * Math.cos(a) };
}))

const getUniformedXY = (e: MouseEvent | TouchEvent, el: SVGSVGElement): { x: number; y: number } => {
  const rect = el.getBoundingClientRect();
  const halfWidth = rect.width / 2;
  const halfHeight = rect.height / 2;
  const halfSquare = Math.min(rect.width, rect.height) / 2;
  let realX = 0, realY = 0;
  if ('targetTouches' in e) {
    const te = e as TouchEvent;
    if (te.targetTouches.length >= 1) {
      realX = te.targetTouches[0]!.clientX;
      realY = te.targetTouches[0]!.clientY;
    }
  } else {
    const me = e as MouseEvent;
    realX = me.clientX;
    realY = me.clientY;
  }
  const x = (realX - rect.left - halfWidth) / halfSquare * DIAL_PLATE_RADIUS;
  const y = -((realY - rect.top - halfHeight) / halfSquare * DIAL_PLATE_RADIUS);
  return { x, y };
}

const startDragHour = (): void => { enableHourDrag.value = true; }

const draggingHour = (e: MouseEvent | TouchEvent): void => {
  if (!enableHourDrag.value || !hourSvgEl.value) return;

  const { x, y } = getUniformedXY(e, hourSvgEl.value);

  const distance = Math.sqrt(x * x + y * y);
  if (distance < 0.001) return;
  let angle = Math.acos(x / distance);
  if (y < 0) angle = Math.PI * 2 - angle; // correct negative y axis angle

  angle += DIAL_PLATE_HOUR_RESOLUTION / 2;
  if (angle > Math.PI * 2) angle -= Math.PI * 2;

  let number = Math.floor(angle / DIAL_PLATE_HOUR_RESOLUTION);
  if (number >= 12) number = 11; // prevent unexpected result at the edge.
  number = (15 - number) % 12;
  if (distance < DIAL_PLATE_RADIUS * DIAL_PLATE_HOUR_DISTINGUISH_PERCENT) number += 12;

  // judge
  if (displayCacheDateTime.value.getHours() !== number) {
    const d = cloneDate(displayCacheDateTime.value);
    d.setHours(number);
    displayCacheDateTime.value = d;
  }
  e.preventDefault();
}

const stopDragHour = (): void => {
  if (!enableHourDrag.value) return;
  enableHourDrag.value = false;
  const d = cloneDate(internalDateTime.value);
  d.setHours(displayCacheDateTime.value.getHours());
  clampDateTime(d);
  internalDateTime.value = d;
  if (mode.value !== TabType.Hour) switchTab(TabType.Minute);
}

const startDragMinute = (): void => { enableMinuteDrag.value = true; }

const draggingMinute = (e: MouseEvent | TouchEvent): void => {
  if (!enableMinuteDrag.value || !minuteSvgEl.value) return;

  const { x, y } = getUniformedXY(e, minuteSvgEl.value);

  const distance = Math.sqrt(x * x + y * y);
  if (distance < 0.001) return;
  let angle = Math.acos(x / distance);
  if (y < 0) angle = Math.PI * 2 - angle; // correct negative y axis angle

  angle += DIAL_PLATE_MINUTE_RESOLUTION / 2; // correct offset
  if (angle > Math.PI * 2) angle -= Math.PI * 2;

  let number = Math.floor(angle / DIAL_PLATE_MINUTE_RESOLUTION);
  if (number >= 60) number = 59; // prevent unexpected result at the edge.
  number = (75 - number) % 60;

  // judge
  if (displayCacheDateTime.value.getMinutes() !== number) {
    const d = cloneDate(displayCacheDateTime.value);
    d.setMinutes(number);
    displayCacheDateTime.value = d;
  }
  e.preventDefault();
}

const stopDragMinute = (): void => {
  if (!enableMinuteDrag.value) return;
  enableMinuteDrag.value = false;
  const d = cloneDate(internalDateTime.value);
  d.setMinutes(displayCacheDateTime.value.getMinutes());
  clampDateTime(d);
  internalDateTime.value = d;
  // Minute is the deepest tab; no further advance.
}

// endregion

// region: SVG font scaling

const recomputeSvgFont = (): void => {
  const el = currentTab.value === TabType.Hour ? hourSvgEl.value
    : currentTab.value === TabType.Minute ? minuteSvgEl.value
    : null;
  if (!el) return;
  const rect = el.getBoundingClientRect();
  const minSide = Math.min(rect.width, rect.height);
  if (minSide > 0) svgFontEm.value = DIAL_PLATE_WIDTH / minSide;
}

let resizeObserver: ResizeObserver | null = null;
const onWindowResize = (): void => recomputeSvgFont();

onMounted(() => {
  if (pickerBodyEl.value && typeof ResizeObserver !== 'undefined') {
    resizeObserver = new ResizeObserver(() => recomputeSvgFont());
    resizeObserver.observe(pickerBodyEl.value);
  }
  window.addEventListener('resize', onWindowResize);
})

onBeforeUnmount(() => {
  resizeObserver?.disconnect();
  resizeObserver = null;
  window.removeEventListener('resize', onWindowResize);
})

watch(currentTab, (t) => {
  if (t === TabType.Hour || t === TabType.Minute) {
    // immediately trigger once svg resize
    nextTick(() => recomputeSvgFont());
  }
})

// endregion
</script>

<template>
  <div class="modal" :class="{ 'is-active': isVisible }"
    style="float: left; position: fixed; top: 0; bottom: 0; left: 0; right: 0;">
    <div class="modal-background"></div>
    <div class="modal-card" style="height: 70%;">
      <header class="modal-card-head pickerHeader">
        <div v-for="t in visibleTabs" :key="t" @click="switchTab(t)">
          <small>{{ tabLabel(t) }}</small>
          <span>{{ headerValue(t) }}</span>
        </div>
      </header>

      <div ref="pickerBodyEl" class="modal-card-body pickerContainer">
        <div v-show="isYearTab">
          <nav class="level is-mobile">
            <div class="level-left">
              <div class="level-item control">
                <a class="button" @click="prevNextYear(true)">
                  <span class="icon is-small"><font-awesome-icon icon="fas fa-chevron-circle-left" /></span>
                </a>
              </div>
            </div>
            <div class="level-item">{{ yearPanelTitle }}</div>
            <div class="level-right">
              <div class="level-item control">
                <a class="button" @click="prevNextYear(false)">
                  <span class="icon is-small"><font-awesome-icon icon="fas fa-chevron-circle-right" /></span>
                </a>
              </div>
            </div>
          </nav>
          <div class="perfectTable">
            <div v-for="(row, ri) in yearRows" :key="ri">
              <div v-for="(cell, ci) in row" :key="ci" :class="{ picked: cell.picked }" @click="clickYear(cell)">
                <template v-if="cell.value !== null">{{ cell.value }}</template>
                <template v-else>&nbsp;</template>
              </div>
            </div>
          </div>
        </div>

        <div v-show="isMonthTab">
          <nav class="level is-mobile">
            <div class="level-left">
              <div class="level-item control">
                <a class="button" @click="prevNextMonth(true)">
                  <span class="icon is-small"><font-awesome-icon icon="fas fa-chevron-circle-left" /></span>
                </a>
              </div>
            </div>
            <div class="level-item">{{ monthPanelTitle }}</div>
            <div class="level-right">
              <div class="level-item control">
                <a class="button" @click="prevNextMonth(false)">
                  <span class="icon is-small"><font-awesome-icon icon="fas fa-chevron-circle-right" /></span>
                </a>
              </div>
            </div>
          </nav>
          <div class="perfectTable">
            <div v-for="(row, ri) in monthRows" :key="ri">
              <div v-for="cell in row" :key="cell.idx" :class="{ picked: cell.picked }" @click="clickMonth(cell)">
                {{ cell.name }}
              </div>
            </div>
          </div>
        </div>

        <div v-show="isDayTab">
          <nav class="level is-mobile">
            <div class="level-left">
              <div class="level-item control">
                <a class="button" @click="prevNextDay(true)">
                  <span class="icon is-small"><font-awesome-icon icon="fas fa-chevron-circle-left" /></span>
                </a>
              </div>
            </div>
            <div class="level-item">{{ dayPanelTitle }}</div>
            <div class="level-right">
              <div class="level-item control">
                <a class="button" @click="prevNextDay(false)">
                  <span class="icon is-small"><font-awesome-icon icon="fas fa-chevron-circle-right" /></span>
                </a>
              </div>
            </div>
          </nav>
          <div class="perfectTable">
            <div>
              <div v-for="i in 7" :key="i">{{ $t('universal-week-' + i) }}</div>
            </div>
            <div v-for="(row, ri) in dayRows" :key="ri">
              <div v-for="(cell, ci) in row" :key="ci" :class="{ picked: cell.picked }" @click="clickDay(cell)">
                <template v-if="cell.value !== null">{{ cell.value }}</template>
                <template v-else>&nbsp;</template>
              </div>
            </div>
          </div>
        </div>

        <svg v-show="isHourTab" ref="hourSvgEl" xmlns="http://www.w3.org/2000/svg"
          preserveAspectRatio="xMidYMid" viewBox="0 0 200 200" :style="{ fontSize: svgFontEm + 'em' }"
          @mousedown="startDragHour" @mousemove="draggingHour" @mouseup="stopDragHour"
          @mouseleave="stopDragHour" @touchstart="startDragHour" @touchmove="draggingHour"
          @touchend="stopDragHour">
          <circle cx="100" cy="100" r="100" type="background"></circle>
          <line x1="100" y1="100" :x2="hourHand.x" :y2="hourHand.y"></line>
          <circle :cx="hourHand.x" :cy="hourHand.y" r="1em" type="symbol"></circle>
          <text v-for="(lb, i) in hourOuterLabels" :key="'o' + i" :x="lb.x" :y="lb.y">{{ lb.label }}</text>
          <text v-for="(lb, i) in hourInnerLabels" :key="'i' + i" :x="lb.x" :y="lb.y">{{ lb.label }}</text>
        </svg>

        <svg v-show="isMinuteTab" ref="minuteSvgEl" xmlns="http://www.w3.org/2000/svg"
          preserveAspectRatio="xMidYMid" viewBox="0 0 200 200" :style="{ fontSize: svgFontEm + 'em' }"
          @mousedown="startDragMinute" @mousemove="draggingMinute" @mouseup="stopDragMinute"
          @mouseleave="stopDragMinute" @touchstart="startDragMinute" @touchmove="draggingMinute"
          @touchend="stopDragMinute">
          <circle cx="100" cy="100" r="100" type="background"></circle>
          <line x1="100" y1="100" :x2="minuteHand.x" :y2="minuteHand.y"></line>
          <circle :cx="minuteHand.x" :cy="minuteHand.y" r="1em" type="symbol"></circle>
          <text v-for="(lb, i) in minuteLabels" :key="i" :x="lb.x" :y="lb.y">{{ lb.label }}</text>
        </svg>
      </div>

      <footer class="modal-card-foot">
        <a class="button is-success" @click="confirm"><span>{{ $t('datetimepicker-confirm') }}</span></a>
        <a class="button" @click="cancel"><span>{{ $t('datetimepicker-cancel') }}</span></a>
      </footer>
    </div>
  </div>
</template>

<style scoped>
div.perfectTable {
  display: flex;
  flex-flow: column;
}

/* div.perfectTable > div > div:nth-child(1) {
  border-left: 1px solid black;
}

div.perfectTable > div:nth-child(1) > div {
  border-top: 1px solid black;
} */

div.perfectTable > div > div {
  /* border-top: 0 solid black;
  border-left: 0 solid black;
  border-right: 1px solid black;
  border-bottom: 1px solid black;

  padding: 0.75em; */

  flex-grow: 1;
  flex-basis: 0;
  flex-shrink: 0;

  overflow: hidden;

  display: flex;
  justify-content: center;

  padding-top: 1rem;
  padding-bottom: 1rem;
}

div.perfectTable > div {
  display: flex;
  flex-flow: row;
}

div.perfectTable > div > div.picked {
  background: hsl(171, 100%, 41%);
  color: #fff;
}


div.pickerContainer {
  display: flex;
  align-items: center;
  flex-flow: row;
  justify-content: center;
}

div.pickerContainer > div {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
}

div.pickerContainer > svg {
  width: 100%;
  height: 100%;
}

div.pickerContainer > svg > text {
  dominant-baseline: middle;
  text-anchor: middle;
  user-select: none;
  cursor: default;
}

div.pickerContainer > svg > circle[type=background] {
  stroke-width: 0;
  fill: #d0d0d0;
}

div.pickerContainer > svg > circle[type=symbol] {
  stroke-width: 0;
  fill: hsl(171, 100%, 41%); /* $primary */
}

div.pickerContainer > svg > line {
  stroke-width: 0.125em;
  stroke: hsl(171, 100%, 41%); /* $primary */
}


header.pickerHeader {
  display: flex;
  flex-flow: row;

  flex-grow: 0;
  flex-basis: 0;
  flex-shrink: 0;

  justify-content: space-between;
}

header.pickerHeader > div {
  display: flex;
  flex-flow: column;

  flex-grow: 1;
  flex-basis: 0;
  flex-shrink: 0;
}
</style>
