feat(SW-350): Implemented tooltip and booking widget tablet design
This commit is contained in:
77
components/Forms/BookingWidget/FormContent/Voucher/index.tsx
Normal file
77
components/Forms/BookingWidget/FormContent/Voucher/index.tsx
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
"use client"
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import inputStyles from "@/components/Forms/BookingWidget/FormContent/Search/search.module.css"
|
||||||
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
|
import { Tooltip } from "@/components/TempDesignSystem/Tooltip"
|
||||||
|
|
||||||
|
import styles from "./voucher.module.css"
|
||||||
|
|
||||||
|
export default function Voucher() {
|
||||||
|
const intl = useIntl()
|
||||||
|
|
||||||
|
const vouchers = intl.formatMessage({ id: "Code / Voucher" })
|
||||||
|
const useVouchers = intl.formatMessage({ id: "Use code/voucher" })
|
||||||
|
const addVouchers = intl.formatMessage({ id: "Add code" })
|
||||||
|
const bonus = intl.formatMessage({ id: "Use bonus cheque" })
|
||||||
|
const reward = intl.formatMessage({ id: "Book reward night" })
|
||||||
|
const disabledBookingOptionsHeader = intl.formatMessage({
|
||||||
|
id: "Disabled booking options header",
|
||||||
|
})
|
||||||
|
const disabledBookingOptionsText = intl.formatMessage({
|
||||||
|
id: "Disabled booking options text",
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.optionsContainer}>
|
||||||
|
<Tooltip
|
||||||
|
heading={disabledBookingOptionsHeader}
|
||||||
|
text={disabledBookingOptionsText}
|
||||||
|
position="bottom"
|
||||||
|
arrow="left"
|
||||||
|
>
|
||||||
|
<div className={styles.vouchers}>
|
||||||
|
<div className={styles.vouchersHeader}>
|
||||||
|
<Caption color="disabled" textTransform="bold">
|
||||||
|
{vouchers}
|
||||||
|
</Caption>
|
||||||
|
{/* <InfoCircleIcon color="white" className={styles.infoIcon} /> Out of scope for this release */}
|
||||||
|
</div>
|
||||||
|
<Body asChild>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder={addVouchers}
|
||||||
|
className={inputStyles.input}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</Body>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip
|
||||||
|
heading={disabledBookingOptionsHeader}
|
||||||
|
text={disabledBookingOptionsText}
|
||||||
|
position="bottom"
|
||||||
|
arrow="left"
|
||||||
|
>
|
||||||
|
<div className={styles.options}>
|
||||||
|
<label className={`${styles.option} ${styles.checkboxVoucher}`}>
|
||||||
|
<input type="checkbox" disabled className={styles.checkbox} />
|
||||||
|
<Caption color="disabled">{useVouchers}</Caption>
|
||||||
|
{/* <InfoCircleIcon color="white" className={styles.infoIcon} /> Out of scope for this release */}
|
||||||
|
</label>
|
||||||
|
<label className={styles.option}>
|
||||||
|
<input type="checkbox" disabled className={styles.checkbox} />
|
||||||
|
<Caption color="disabled">{bonus}</Caption>
|
||||||
|
{/* <InfoCircleIcon color="white" className={styles.infoIcon} /> Out of scope for this release */}
|
||||||
|
</label>
|
||||||
|
<label className={styles.option}>
|
||||||
|
<input type="checkbox" disabled className={styles.checkbox} />
|
||||||
|
<Caption color="disabled">{reward}</Caption>
|
||||||
|
{/* <InfoCircleIcon color="white" className={styles.infoIcon} /> Out of scope for this release */}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
.vouchers {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.options {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--Spacing-x2);
|
||||||
|
margin-top: var(--Spacing-x2);
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.vouchers {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
padding: var(--Spacing-x1) var(--Spacing-x-one-and-half);
|
||||||
|
border-radius: var(--Corner-radius-Small);
|
||||||
|
}
|
||||||
|
|
||||||
|
.optionsContainer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
width: var(--Spacing-x3);
|
||||||
|
height: var(--Spacing-x3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkboxVoucher {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
.vouchers {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.options {
|
||||||
|
flex-direction: row;
|
||||||
|
gap: var(--Spacing-x4);
|
||||||
|
}
|
||||||
|
.option {
|
||||||
|
margin-top: 0;
|
||||||
|
gap: var(--Spacing-x-one-and-half);
|
||||||
|
}
|
||||||
|
.checkboxVoucher {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1366px) {
|
||||||
|
.vouchers {
|
||||||
|
background-color: var(--Base-Background-Primary-Normal);
|
||||||
|
border-radius: var(--Corner-radius-Medium);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 1367px) {
|
||||||
|
.vouchers {
|
||||||
|
display: block;
|
||||||
|
max-width: 200px;
|
||||||
|
}
|
||||||
|
.options {
|
||||||
|
flex-direction: column;
|
||||||
|
max-width: 190px;
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
.vouchers:hover,
|
||||||
|
.option:hover {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
.optionsContainer {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
.checkboxVoucher {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +1,7 @@
|
|||||||
.options {
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option {
|
|
||||||
display: flex;
|
|
||||||
gap: var(--Spacing-x-one-and-half);
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.infoIcon {
|
.infoIcon {
|
||||||
stroke: var(--Base-Text-Disabled);
|
stroke: var(--Base-Text-Disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vouchers,
|
|
||||||
.options {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vouchersHeader {
|
.vouchersHeader {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--Spacing-x-one-and-half);
|
gap: var(--Spacing-x-one-and-half);
|
||||||
@@ -28,9 +11,19 @@
|
|||||||
width: var(--Spacing-x3);
|
width: var(--Spacing-x3);
|
||||||
height: var(--Spacing-x3);
|
height: var(--Spacing-x3);
|
||||||
}
|
}
|
||||||
|
.icon,
|
||||||
|
.voucherRow {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 767px) {
|
@media screen and (max-width: 767px) {
|
||||||
.input {
|
.voucherContainer {
|
||||||
|
padding: var(--Spacing-x2) 0 var(--Spacing-x4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1367px) {
|
||||||
|
.inputContainer {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--Spacing-x2);
|
gap: var(--Spacing-x2);
|
||||||
}
|
}
|
||||||
@@ -49,36 +42,39 @@
|
|||||||
padding: var(--Spacing-x1) var(--Spacing-x-one-and-half);
|
padding: var(--Spacing-x1) var(--Spacing-x-one-and-half);
|
||||||
}
|
}
|
||||||
|
|
||||||
.options {
|
.button {
|
||||||
gap: var(--Spacing-x2);
|
align-self: flex-end;
|
||||||
margin-top: var(--Spacing-x2);
|
justify-content: center;
|
||||||
}
|
width: 100%;
|
||||||
|
|
||||||
.option {
|
|
||||||
gap: var(--Spacing-x2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 768px) {
|
@media screen and (min-width: 768px) {
|
||||||
.input {
|
.input {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.inputContainer {
|
||||||
|
display: flex;
|
||||||
|
flex: 2;
|
||||||
gap: var(--Spacing-x2);
|
gap: var(--Spacing-x2);
|
||||||
}
|
}
|
||||||
|
.voucherContainer {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.rooms,
|
.rooms,
|
||||||
.vouchers,
|
|
||||||
.when,
|
.when,
|
||||||
.where {
|
.where {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input input[type="text"] {
|
.inputContainer input[type="text"] {
|
||||||
border: none;
|
border: none;
|
||||||
height: 24px;
|
height: var(--Spacing-x3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.rooms,
|
.rooms,
|
||||||
.vouchers,
|
|
||||||
.when {
|
.when {
|
||||||
max-width: 240px;
|
max-width: 240px;
|
||||||
padding: var(--Spacing-x1) var(--Spacing-x-one-and-half);
|
padding: var(--Spacing-x1) var(--Spacing-x-one-and-half);
|
||||||
@@ -90,30 +86,43 @@
|
|||||||
background-color: var(--Base-Surface-Primary-light-Hover-alt);
|
background-color: var(--Base-Surface-Primary-light-Hover-alt);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vouchers {
|
|
||||||
max-width: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.where {
|
.where {
|
||||||
max-width: 280px;
|
max-width: 280px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.options {
|
.button {
|
||||||
max-width: 190px;
|
justify-content: center;
|
||||||
|
width: 118px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 1367px) {
|
@media screen and (min-width: 768px) and (max-width: 1366px) {
|
||||||
.vouchers {
|
.inputContainer {
|
||||||
display: block;
|
padding: var(--Spacing-x2);
|
||||||
}
|
}
|
||||||
|
.buttonContainer {
|
||||||
.options {
|
padding-right: var(--Spacing-x2);
|
||||||
|
}
|
||||||
|
.input .buttonContainer .button {
|
||||||
|
padding: var(--Spacing-x1);
|
||||||
|
width: var(--Spacing-x6);
|
||||||
|
height: var(--Spacing-x6);
|
||||||
|
}
|
||||||
|
.buttonText {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
.vouchers:hover,
|
|
||||||
.option:hover {
|
.voucherRow {
|
||||||
cursor: not-allowed;
|
display: flex;
|
||||||
|
background: var(--Base-Surface-Primary-light-Hover);
|
||||||
|
border-bottom: 1px solid var(--Primary-Light-On-Surface-Divider-subtle);
|
||||||
|
padding: var(--Spacing-x2);
|
||||||
|
}
|
||||||
|
.voucherContainer {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,85 +1,93 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
import React from "react"
|
||||||
import { useWatch } from "react-hook-form"
|
import { useWatch } from "react-hook-form"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { dt } from "@/lib/dt"
|
import { dt } from "@/lib/dt"
|
||||||
|
|
||||||
import DatePicker from "@/components/DatePicker"
|
import DatePicker from "@/components/DatePicker"
|
||||||
import { InfoCircleIcon } from "@/components/Icons"
|
import { SearchIcon } from "@/components/Icons"
|
||||||
|
import Button from "@/components/TempDesignSystem/Button"
|
||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
|
|
||||||
import Search from "./Search"
|
import Search from "./Search"
|
||||||
|
import Voucher from "./Voucher"
|
||||||
|
|
||||||
import styles from "./formContent.module.css"
|
import styles from "./formContent.module.css"
|
||||||
import tempStyles from "./Search/search.module.css" // TODO: Remove this when Rooms and Voucher is implemented
|
import inputStyles from "./Search/search.module.css"
|
||||||
|
|
||||||
import type { BookingWidgetFormContentProps } from "@/types/components/form/bookingwidget"
|
import type { BookingWidgetFormContentProps } from "@/types/components/form/bookingwidget"
|
||||||
|
|
||||||
export default function FormContent({
|
export default function FormContent({
|
||||||
locations,
|
locations,
|
||||||
|
formId,
|
||||||
|
formState,
|
||||||
}: BookingWidgetFormContentProps) {
|
}: BookingWidgetFormContentProps) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const selectedDate = useWatch({ name: "date" })
|
const selectedDate = useWatch({ name: "date" })
|
||||||
|
|
||||||
const rooms = intl.formatMessage({ id: "Guests & Rooms" })
|
const rooms = intl.formatMessage({ id: "Guests & Rooms" })
|
||||||
const vouchers = intl.formatMessage({ id: "Code / Voucher" })
|
|
||||||
const addVouchers = intl.formatMessage({ id: "Add code" })
|
|
||||||
const bonus = intl.formatMessage({ id: "Use bonus cheque" })
|
|
||||||
const reward = intl.formatMessage({ id: "Book reward night" })
|
|
||||||
|
|
||||||
const nights = dt(selectedDate.to).diff(dt(selectedDate.from), "days")
|
const nights = dt(selectedDate.to).diff(dt(selectedDate.from), "days")
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.input}>
|
<>
|
||||||
<div className={styles.where}>
|
<div className={styles.input}>
|
||||||
<Search locations={locations} />
|
<div className={styles.inputContainer}>
|
||||||
</div>
|
<div className={styles.where}>
|
||||||
<div className={styles.when}>
|
<Search locations={locations} />
|
||||||
<Caption color="red" textTransform="bold">
|
</div>
|
||||||
{intl.formatMessage(
|
<div className={styles.when}>
|
||||||
{ id: "booking.nights" },
|
<Caption color="red" textTransform="bold">
|
||||||
{ totalNights: nights }
|
{intl.formatMessage(
|
||||||
)}
|
{ id: "booking.nights" },
|
||||||
</Caption>
|
{ totalNights: nights }
|
||||||
<DatePicker />
|
)}
|
||||||
</div>
|
</Caption>
|
||||||
<div className={styles.rooms}>
|
<DatePicker />
|
||||||
<Caption color="red" textTransform="bold">
|
</div>
|
||||||
{rooms}
|
<div className={styles.rooms}>
|
||||||
</Caption>
|
<Caption color="red" textTransform="bold">
|
||||||
<Body asChild>
|
{rooms}
|
||||||
<input type="text" placeholder={rooms} className={tempStyles.input} />
|
</Caption>
|
||||||
</Body>
|
<Body asChild>
|
||||||
</div>
|
<input
|
||||||
<div className={styles.vouchers}>
|
type="text"
|
||||||
<div className={styles.vouchersHeader}>
|
placeholder={rooms}
|
||||||
<Caption color="disabled" textTransform="bold">
|
className={inputStyles.input}
|
||||||
{vouchers}
|
/>
|
||||||
</Caption>
|
</Body>
|
||||||
<InfoCircleIcon color="white" className={styles.infoIcon} />
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.voucherContainer}>
|
||||||
|
<Voucher />
|
||||||
|
</div>
|
||||||
|
<div className={styles.buttonContainer}>
|
||||||
|
<Button
|
||||||
|
className={styles.button}
|
||||||
|
disabled={!formState.isValid}
|
||||||
|
form={formId}
|
||||||
|
intent="primary"
|
||||||
|
theme="base"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
<Caption
|
||||||
|
color="white"
|
||||||
|
textTransform="bold"
|
||||||
|
className={styles.buttonText}
|
||||||
|
>
|
||||||
|
{intl.formatMessage({ id: "Search" })}
|
||||||
|
</Caption>
|
||||||
|
<div className={styles.icon}>
|
||||||
|
<SearchIcon color="white" width={28} height={28} />
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Body asChild>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder={addVouchers}
|
|
||||||
className={tempStyles.input}
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
</Body>
|
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.options}>
|
<div className={styles.voucherRow}>
|
||||||
<label className={styles.option}>
|
<Voucher />
|
||||||
<input type="checkbox" disabled className={styles.checkbox} />
|
|
||||||
<Caption color="disabled">{bonus}</Caption>
|
|
||||||
<InfoCircleIcon color="white" className={styles.infoIcon} />
|
|
||||||
</label>
|
|
||||||
<label className={styles.option}>
|
|
||||||
<input type="checkbox" disabled className={styles.checkbox} />
|
|
||||||
<Caption color="disabled">{reward}</Caption>
|
|
||||||
<InfoCircleIcon color="white" className={styles.infoIcon} />
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
.form {
|
.form {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--Spacing-x2);
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,27 +15,23 @@
|
|||||||
.form {
|
.form {
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
|
||||||
align-self: flex-end;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 768px) {
|
@media screen and (min-width: 768px) {
|
||||||
.section {
|
.section {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: var(--Spacing-x1) var(--Spacing-x5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
justify-content: center;
|
|
||||||
width: 118px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.default {
|
.default {
|
||||||
border-radius: var(--Corner-radius-Medium);
|
border-radius: var(--Corner-radius-Medium);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 1367px) {
|
||||||
|
.section {
|
||||||
|
padding: var(--Spacing-x1) var(--Spacing-x5);
|
||||||
|
}
|
||||||
|
.default {
|
||||||
padding: var(--Spacing-x-one-and-half) var(--Spacing-x2)
|
padding: var(--Spacing-x-one-and-half) var(--Spacing-x2)
|
||||||
var(--Spacing-x-one-and-half) var(--Spacing-x1);
|
var(--Spacing-x-one-and-half) var(--Spacing-x1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import { useRouter } from "next/navigation"
|
import { useRouter } from "next/navigation"
|
||||||
import { useFormContext } from "react-hook-form"
|
import { useFormContext } from "react-hook-form"
|
||||||
import { useIntl } from "react-intl"
|
|
||||||
|
|
||||||
import Button from "@/components/TempDesignSystem/Button"
|
|
||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
|
||||||
|
|
||||||
import FormContent from "./FormContent"
|
import FormContent from "./FormContent"
|
||||||
import { bookingWidgetVariants } from "./variants"
|
import { bookingWidgetVariants } from "./variants"
|
||||||
@@ -17,7 +13,6 @@ import type { BookingWidgetFormProps } from "@/types/components/form/bookingwidg
|
|||||||
const formId = "booking-widget"
|
const formId = "booking-widget"
|
||||||
|
|
||||||
export default function Form({ locations, type }: BookingWidgetFormProps) {
|
export default function Form({ locations, type }: BookingWidgetFormProps) {
|
||||||
const intl = useIntl()
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const classNames = bookingWidgetVariants({
|
const classNames = bookingWidgetVariants({
|
||||||
@@ -43,20 +38,12 @@ export default function Form({ locations, type }: BookingWidgetFormProps) {
|
|||||||
id={formId}
|
id={formId}
|
||||||
>
|
>
|
||||||
<input {...register("location")} type="hidden" />
|
<input {...register("location")} type="hidden" />
|
||||||
<FormContent locations={locations} />
|
<FormContent
|
||||||
|
locations={locations}
|
||||||
|
formId={formId}
|
||||||
|
formState={formState}
|
||||||
|
/>
|
||||||
</form>
|
</form>
|
||||||
<Button
|
|
||||||
className={styles.button}
|
|
||||||
disabled={!formState.isValid}
|
|
||||||
form={formId}
|
|
||||||
intent="primary"
|
|
||||||
theme="base"
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
<Caption color="white" textTransform="bold">
|
|
||||||
{intl.formatMessage({ id: "Search" })}
|
|
||||||
</Caption>
|
|
||||||
</Button>
|
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
30
components/TempDesignSystem/Tooltip/index.tsx
Normal file
30
components/TempDesignSystem/Tooltip/index.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
|
|
||||||
|
import { tooltipVariants } from "./variants"
|
||||||
|
|
||||||
|
import styles from "./tooltip.module.css"
|
||||||
|
|
||||||
|
import { TooltipPosition, TooltipProps } from "@/types/components/tooltip"
|
||||||
|
|
||||||
|
export function Tooltip<P extends TooltipPosition>({
|
||||||
|
heading,
|
||||||
|
text,
|
||||||
|
position,
|
||||||
|
arrow,
|
||||||
|
children,
|
||||||
|
}: TooltipProps<P>) {
|
||||||
|
const className = tooltipVariants({ position, arrow })
|
||||||
|
return (
|
||||||
|
<div className={styles.tooltipContainer} role="tooltip" aria-label={text}>
|
||||||
|
<div className={className}>
|
||||||
|
{heading && (
|
||||||
|
<Caption textTransform="bold" color="white">
|
||||||
|
{heading}
|
||||||
|
</Caption>
|
||||||
|
)}
|
||||||
|
{text && <Caption color="white">{text}</Caption>}
|
||||||
|
</div>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
137
components/TempDesignSystem/Tooltip/tooltip.module.css
Normal file
137
components/TempDesignSystem/Tooltip/tooltip.module.css
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
.tooltipContainer {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
padding: var(--Spacing-x1);
|
||||||
|
background-color: var(--UI-Text-Active);
|
||||||
|
border: 0.5px solid var(--UI-Border-Active);
|
||||||
|
border-radius: var(--Corner-radius-Medium);
|
||||||
|
color: var(--Base-Text-Inverted);
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
z-index: 1000;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
max-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltipContainer:hover .tooltip {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
right: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
left: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top {
|
||||||
|
bottom: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom {
|
||||||
|
top: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
border-style: solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom.arrowLeft::before {
|
||||||
|
top: -8px;
|
||||||
|
left: 16px;
|
||||||
|
border-width: 0 7px 8px 7px;
|
||||||
|
border-color: transparent transparent var(--UI-Text-Active) transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom.arrowCenter::before {
|
||||||
|
top: -8px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
border-width: 0 7px 8px 7px;
|
||||||
|
border-color: transparent transparent var(--UI-Text-Active) transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom.arrowRight::before {
|
||||||
|
top: -8px;
|
||||||
|
right: 16px;
|
||||||
|
border-width: 0 7px 8px 7px;
|
||||||
|
border-color: transparent transparent var(--UI-Text-Active) transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top.arrowLeft::before {
|
||||||
|
bottom: -8px;
|
||||||
|
left: 16px;
|
||||||
|
border-width: 8px 7px 0 7px;
|
||||||
|
border-color: var(--UI-Text-Active) transparent transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top.arrowCenter::before {
|
||||||
|
bottom: -8px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
border-width: 8px 7px 0 7px;
|
||||||
|
border-color: var(--UI-Text-Active) transparent transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top.arrowRight::before {
|
||||||
|
bottom: -8px;
|
||||||
|
right: 16px;
|
||||||
|
border-width: 8px 7px 0 7px;
|
||||||
|
border-color: var(--UI-Text-Active) transparent transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left.arrowTop::before {
|
||||||
|
top: 16px;
|
||||||
|
right: -8px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border-width: 7px 0 7px 8px;
|
||||||
|
border-color: transparent transparent transparent var(--UI-Text-Active);
|
||||||
|
}
|
||||||
|
|
||||||
|
.left.arrowCenter::before {
|
||||||
|
top: 50%;
|
||||||
|
right: -8px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border-width: 7px 0 7px 8px;
|
||||||
|
border-color: transparent transparent transparent var(--UI-Text-Active);
|
||||||
|
}
|
||||||
|
|
||||||
|
.left.arrowBottom::before {
|
||||||
|
bottom: 16px;
|
||||||
|
right: -8px;
|
||||||
|
transform: translateY(50%);
|
||||||
|
border-width: 7px 0 7px 8px;
|
||||||
|
border-color: transparent transparent transparent var(--UI-Text-Active);
|
||||||
|
}
|
||||||
|
|
||||||
|
.right.arrowTop::before {
|
||||||
|
top: 16px;
|
||||||
|
left: -8px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border-width: 7px 8px 7px 0;
|
||||||
|
border-color: transparent var(--UI-Text-Active) transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right.arrowCenter::before {
|
||||||
|
top: 50%;
|
||||||
|
left: -8px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border-width: 7px 8px 7px 0;
|
||||||
|
border-color: transparent var(--UI-Text-Active) transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right.arrowBottom::before {
|
||||||
|
bottom: 16px;
|
||||||
|
left: -8px;
|
||||||
|
transform: translateY(50%);
|
||||||
|
border-width: 7px 8px 7px 0;
|
||||||
|
border-color: transparent var(--UI-Text-Active) transparent transparent;
|
||||||
|
}
|
||||||
21
components/TempDesignSystem/Tooltip/variants.ts
Normal file
21
components/TempDesignSystem/Tooltip/variants.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { cva } from "class-variance-authority"
|
||||||
|
|
||||||
|
import styles from "./tooltip.module.css"
|
||||||
|
|
||||||
|
export const tooltipVariants = cva(styles.tooltip, {
|
||||||
|
variants: {
|
||||||
|
position: {
|
||||||
|
left: styles.left,
|
||||||
|
right: styles.right,
|
||||||
|
top: styles.top,
|
||||||
|
bottom: styles.bottom,
|
||||||
|
},
|
||||||
|
arrow: {
|
||||||
|
left: styles.arrowLeft,
|
||||||
|
right: styles.arrowRight,
|
||||||
|
center: styles.arrowCenter,
|
||||||
|
top: styles.arrowTop,
|
||||||
|
bottom: styles.arrowBottom,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
"As our Close Friend": "Som vores nære ven",
|
"As our Close Friend": "Som vores nære ven",
|
||||||
"At latest": "Senest",
|
"At latest": "Senest",
|
||||||
"At the hotel": "På hotellet",
|
"At the hotel": "På hotellet",
|
||||||
"Attractions": "Attraktioner",
|
"Attraction": "Attraktion",
|
||||||
"Back to scandichotels.com": "Tilbage til scandichotels.com",
|
"Back to scandichotels.com": "Tilbage til scandichotels.com",
|
||||||
"Bed type": "Seng type",
|
"Bed type": "Seng type",
|
||||||
"Book": "Book",
|
"Book": "Book",
|
||||||
@@ -60,6 +60,8 @@
|
|||||||
"Day": "Dag",
|
"Day": "Dag",
|
||||||
"Description": "Beskrivelse",
|
"Description": "Beskrivelse",
|
||||||
"Destinations & hotels": "Destinationer & hoteller",
|
"Destinations & hotels": "Destinationer & hoteller",
|
||||||
|
"Disabled booking options header": "Vi beklager",
|
||||||
|
"Disabled booking options text": "Koder, checks og bonusnætter er endnu ikke tilgængelige på den nye hjemmeside.",
|
||||||
"Discard changes": "Kassér ændringer",
|
"Discard changes": "Kassér ændringer",
|
||||||
"Discard unsaved changes?": "Slette ændringer, der ikke er gemt?",
|
"Discard unsaved changes?": "Slette ændringer, der ikke er gemt?",
|
||||||
"Distance to city centre": "{number}km til centrum",
|
"Distance to city centre": "{number}km til centrum",
|
||||||
@@ -228,6 +230,7 @@
|
|||||||
"Type of bed": "Sengtype",
|
"Type of bed": "Sengtype",
|
||||||
"Type of room": "Værelsestype",
|
"Type of room": "Værelsestype",
|
||||||
"Use bonus cheque": "Brug Bonus Cheque",
|
"Use bonus cheque": "Brug Bonus Cheque",
|
||||||
|
"Use code/voucher": "Brug kode/voucher",
|
||||||
"User information": "Brugeroplysninger",
|
"User information": "Brugeroplysninger",
|
||||||
"View as list": "Vis som liste",
|
"View as list": "Vis som liste",
|
||||||
"View as map": "Vis som kort",
|
"View as map": "Vis som kort",
|
||||||
@@ -281,4 +284,4 @@
|
|||||||
"spendable points expiring by": "{points} Brugbare point udløber den {date}",
|
"spendable points expiring by": "{points} Brugbare point udløber den {date}",
|
||||||
"to": "til",
|
"to": "til",
|
||||||
"uppercase letter": "stort bogstav"
|
"uppercase letter": "stort bogstav"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
"As our Close Friend": "Als unser enger Freund",
|
"As our Close Friend": "Als unser enger Freund",
|
||||||
"At latest": "Spätestens",
|
"At latest": "Spätestens",
|
||||||
"At the hotel": "Im Hotel",
|
"At the hotel": "Im Hotel",
|
||||||
"Attractions": "Attraktionen",
|
"Attraction": "Attraktion",
|
||||||
"Back to scandichotels.com": "Zurück zu scandichotels.com",
|
"Back to scandichotels.com": "Zurück zu scandichotels.com",
|
||||||
"Bed type": "Bettentyp",
|
"Bed type": "Bettentyp",
|
||||||
"Book": "Buchen",
|
"Book": "Buchen",
|
||||||
@@ -60,6 +60,8 @@
|
|||||||
"Day": "Tag",
|
"Day": "Tag",
|
||||||
"Description": "Beschreibung",
|
"Description": "Beschreibung",
|
||||||
"Destinations & hotels": "Reiseziele & Hotels",
|
"Destinations & hotels": "Reiseziele & Hotels",
|
||||||
|
"Disabled booking options header": "Es tut uns leid",
|
||||||
|
"Disabled booking options text": "Codes, Schecks und Bonusnächte sind auf der neuen Website noch nicht verfügbar.",
|
||||||
"Discard changes": "Änderungen verwerfen",
|
"Discard changes": "Änderungen verwerfen",
|
||||||
"Discard unsaved changes?": "Nicht gespeicherte Änderungen verwerfen?",
|
"Discard unsaved changes?": "Nicht gespeicherte Änderungen verwerfen?",
|
||||||
"Distance to city centre": "{number}km zum Stadtzentrum",
|
"Distance to city centre": "{number}km zum Stadtzentrum",
|
||||||
@@ -227,6 +229,7 @@
|
|||||||
"Type of bed": "Bettentyp",
|
"Type of bed": "Bettentyp",
|
||||||
"Type of room": "Zimmerart",
|
"Type of room": "Zimmerart",
|
||||||
"Use bonus cheque": "Bonusscheck nutzen",
|
"Use bonus cheque": "Bonusscheck nutzen",
|
||||||
|
"Use code/voucher": "Code/Gutschein nutzen",
|
||||||
"User information": "Nutzerinformation",
|
"User information": "Nutzerinformation",
|
||||||
"View as list": "Als Liste anzeigen",
|
"View as list": "Als Liste anzeigen",
|
||||||
"View as map": "Als Karte anzeigen",
|
"View as map": "Als Karte anzeigen",
|
||||||
@@ -280,4 +283,4 @@
|
|||||||
"spendable points expiring by": "{points} Einlösbare punkte verfallen bis zum {date}",
|
"spendable points expiring by": "{points} Einlösbare punkte verfallen bis zum {date}",
|
||||||
"to": "zu",
|
"to": "zu",
|
||||||
"uppercase letter": "großbuchstabe"
|
"uppercase letter": "großbuchstabe"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,8 @@
|
|||||||
"Description": "Description",
|
"Description": "Description",
|
||||||
"Destinations & hotels": "Destinations & hotels",
|
"Destinations & hotels": "Destinations & hotels",
|
||||||
"Destination": "Destination",
|
"Destination": "Destination",
|
||||||
|
"Disabled booking options header": "We're sorry",
|
||||||
|
"Disabled booking options text": "Codes, cheques and reward nights aren't available on the new website yet.",
|
||||||
"Discard changes": "Discard changes",
|
"Discard changes": "Discard changes",
|
||||||
"Discard unsaved changes?": "Discard unsaved changes?",
|
"Discard unsaved changes?": "Discard unsaved changes?",
|
||||||
"Distance to city centre": "{number}km to city centre",
|
"Distance to city centre": "{number}km to city centre",
|
||||||
@@ -230,6 +232,7 @@
|
|||||||
"Type of bed": "Type of bed",
|
"Type of bed": "Type of bed",
|
||||||
"Type of room": "Type of room",
|
"Type of room": "Type of room",
|
||||||
"Use bonus cheque": "Use bonus cheque",
|
"Use bonus cheque": "Use bonus cheque",
|
||||||
|
"Use code/voucher": "Use code/voucher",
|
||||||
"User information": "User information",
|
"User information": "User information",
|
||||||
"View as list": "View as list",
|
"View as list": "View as list",
|
||||||
"View as map": "View as map",
|
"View as map": "View as map",
|
||||||
@@ -285,4 +288,4 @@
|
|||||||
"spendable points expiring by": "{points} spendable points expiring by {date}",
|
"spendable points expiring by": "{points} spendable points expiring by {date}",
|
||||||
"to": "to",
|
"to": "to",
|
||||||
"uppercase letter": "uppercase letter"
|
"uppercase letter": "uppercase letter"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,8 @@
|
|||||||
"Day": "Päivä",
|
"Day": "Päivä",
|
||||||
"Description": "Kuvaus",
|
"Description": "Kuvaus",
|
||||||
"Destinations & hotels": "Kohteet ja hotellit",
|
"Destinations & hotels": "Kohteet ja hotellit",
|
||||||
|
"Disabled booking options header": "Olemme pahoillamme",
|
||||||
|
"Disabled booking options text": "Koodit, sekit ja palkintoillat eivät ole vielä saatavilla uudella verkkosivustolla.",
|
||||||
"Discard changes": "Hylkää muutokset",
|
"Discard changes": "Hylkää muutokset",
|
||||||
"Discard unsaved changes?": "Hylkäätkö tallentamattomat muutokset?",
|
"Discard unsaved changes?": "Hylkäätkö tallentamattomat muutokset?",
|
||||||
"Distance to city centre": "{number}km Etäisyys kaupunkiin",
|
"Distance to city centre": "{number}km Etäisyys kaupunkiin",
|
||||||
@@ -228,6 +230,7 @@
|
|||||||
"Type of bed": "Vuodetyyppi",
|
"Type of bed": "Vuodetyyppi",
|
||||||
"Type of room": "Huonetyyppi",
|
"Type of room": "Huonetyyppi",
|
||||||
"Use bonus cheque": "Käytä bonussekkiä",
|
"Use bonus cheque": "Käytä bonussekkiä",
|
||||||
|
"Use code/voucher": "Käytä koodia/voucheria",
|
||||||
"User information": "Käyttäjän tiedot",
|
"User information": "Käyttäjän tiedot",
|
||||||
"View as list": "Näytä listana",
|
"View as list": "Näytä listana",
|
||||||
"View as map": "Näytä kartalla",
|
"View as map": "Näytä kartalla",
|
||||||
@@ -281,4 +284,4 @@
|
|||||||
"spendable points expiring by": "{points} pistettä vanhenee {date} mennessä",
|
"spendable points expiring by": "{points} pistettä vanhenee {date} mennessä",
|
||||||
"to": "to",
|
"to": "to",
|
||||||
"uppercase letter": "iso kirjain"
|
"uppercase letter": "iso kirjain"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,8 @@
|
|||||||
"Day": "Dag",
|
"Day": "Dag",
|
||||||
"Description": "Beskrivelse",
|
"Description": "Beskrivelse",
|
||||||
"Destinations & hotels": "Destinasjoner og hoteller",
|
"Destinations & hotels": "Destinasjoner og hoteller",
|
||||||
|
"Disabled booking options header": "Vi beklager",
|
||||||
|
"Disabled booking options text": "Koder, checks og belønningsnætter er enda ikke tilgjengelige på den nye nettsiden.",
|
||||||
"Discard changes": "Forkaste endringer",
|
"Discard changes": "Forkaste endringer",
|
||||||
"Discard unsaved changes?": "Forkaste endringer som ikke er lagret?",
|
"Discard unsaved changes?": "Forkaste endringer som ikke er lagret?",
|
||||||
"Distance to city centre": "{number}km til sentrum",
|
"Distance to city centre": "{number}km til sentrum",
|
||||||
@@ -228,6 +230,7 @@
|
|||||||
"Type of bed": "Sengtype",
|
"Type of bed": "Sengtype",
|
||||||
"Type of room": "Romtype",
|
"Type of room": "Romtype",
|
||||||
"Use bonus cheque": "Bruk bonussjekk",
|
"Use bonus cheque": "Bruk bonussjekk",
|
||||||
|
"Use code/voucher": "Bruk kode/voucher",
|
||||||
"User information": "Brukerinformasjon",
|
"User information": "Brukerinformasjon",
|
||||||
"View as list": "Vis som liste",
|
"View as list": "Vis som liste",
|
||||||
"View as map": "Vis som kart",
|
"View as map": "Vis som kart",
|
||||||
@@ -281,4 +284,4 @@
|
|||||||
"spendable points expiring by": "{points} Brukbare poeng utløper innen {date}",
|
"spendable points expiring by": "{points} Brukbare poeng utløper innen {date}",
|
||||||
"to": "til",
|
"to": "til",
|
||||||
"uppercase letter": "stor bokstav"
|
"uppercase letter": "stor bokstav"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,8 @@
|
|||||||
"Day": "Dag",
|
"Day": "Dag",
|
||||||
"Description": "Beskrivning",
|
"Description": "Beskrivning",
|
||||||
"Destinations & hotels": "Destinationer & hotell",
|
"Destinations & hotels": "Destinationer & hotell",
|
||||||
|
"Disabled booking options header": "Vi beklagar",
|
||||||
|
"Disabled booking options text": "Koder, bonuscheckar och belöningsnätter är inte tillgängliga på den nya webbplatsen än.",
|
||||||
"Discard changes": "Ignorera ändringar",
|
"Discard changes": "Ignorera ändringar",
|
||||||
"Discard unsaved changes?": "Vill du ignorera ändringar som inte har sparats?",
|
"Discard unsaved changes?": "Vill du ignorera ändringar som inte har sparats?",
|
||||||
"Distance to city centre": "{number}km till centrum",
|
"Distance to city centre": "{number}km till centrum",
|
||||||
@@ -227,7 +229,8 @@
|
|||||||
"Tripadvisor reviews": "{rating} ({count} recensioner på Tripadvisor)",
|
"Tripadvisor reviews": "{rating} ({count} recensioner på Tripadvisor)",
|
||||||
"Type of bed": "Sängtyp",
|
"Type of bed": "Sängtyp",
|
||||||
"Type of room": "Rumstyp",
|
"Type of room": "Rumstyp",
|
||||||
"Use bonus cheque": "Use bonus cheque",
|
"Use bonus cheque": "Använd bonuscheck",
|
||||||
|
"Use code/voucher": "Använd kod/voucher",
|
||||||
"User information": "Användarinformation",
|
"User information": "Användarinformation",
|
||||||
"View as list": "Visa som lista",
|
"View as list": "Visa som lista",
|
||||||
"View as map": "Visa som karta",
|
"View as map": "Visa som karta",
|
||||||
@@ -281,4 +284,4 @@
|
|||||||
"spendable points expiring by": "{points} poäng förfaller {date}",
|
"spendable points expiring by": "{points} poäng förfaller {date}",
|
||||||
"to": "till",
|
"to": "till",
|
||||||
"uppercase letter": "stor bokstav"
|
"uppercase letter": "stor bokstav"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
import type { BookingWidgetType } from "@/types/components/bookingWidget"
|
import { FormState, UseFormReturn } from "react-hook-form"
|
||||||
|
|
||||||
|
import type {
|
||||||
|
BookingWidgetSchema,
|
||||||
|
BookingWidgetType,
|
||||||
|
} from "@/types/components/bookingWidget"
|
||||||
import type { Location, Locations } from "@/types/trpc/routers/hotel/locations"
|
import type { Location, Locations } from "@/types/trpc/routers/hotel/locations"
|
||||||
|
|
||||||
export interface BookingWidgetFormProps {
|
export interface BookingWidgetFormProps {
|
||||||
@@ -8,6 +13,8 @@ export interface BookingWidgetFormProps {
|
|||||||
|
|
||||||
export interface BookingWidgetFormContentProps {
|
export interface BookingWidgetFormContentProps {
|
||||||
locations: Locations
|
locations: Locations
|
||||||
|
formId: string
|
||||||
|
formState: FormState<BookingWidgetSchema>
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ActionType {
|
export enum ActionType {
|
||||||
|
|||||||
22
types/components/tooltip.ts
Normal file
22
types/components/tooltip.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
export type TooltipPosition = "left" | "right" | "top" | "bottom"
|
||||||
|
type VerticalArrow = "top" | "bottom" | "center"
|
||||||
|
type HorizontalArrow = "left" | "right" | "center"
|
||||||
|
|
||||||
|
type ValidArrowMap = {
|
||||||
|
left: VerticalArrow
|
||||||
|
right: VerticalArrow
|
||||||
|
top: HorizontalArrow
|
||||||
|
bottom: HorizontalArrow
|
||||||
|
}
|
||||||
|
|
||||||
|
type ValidArrow<P extends TooltipPosition> = P extends keyof ValidArrowMap
|
||||||
|
? ValidArrowMap[P]
|
||||||
|
: never
|
||||||
|
|
||||||
|
export interface TooltipProps<P extends TooltipPosition = TooltipPosition> {
|
||||||
|
heading?: string
|
||||||
|
text?: string
|
||||||
|
position: P
|
||||||
|
arrow: ValidArrow<P>
|
||||||
|
children: React.ReactNode
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user