@schedule-x/date-picker
Advanced tools
Comparing version 1.37.0 to 1.38.0
@@ -93,16 +93,10 @@ 'use strict'; | ||
const [wrapperClasses, setWrapperClasses] = hooks.useState([]); | ||
const setInputDOMRect = () => { | ||
const setInputElement = () => { | ||
const inputWrapperEl = document.getElementById(inputWrapperId); | ||
if (inputWrapperEl === null) | ||
return; | ||
$app.datePickerState.inputRect.value = { | ||
x: inputWrapperEl.getBoundingClientRect().left + window.scrollX, | ||
y: inputWrapperEl.getBoundingClientRect().top + window.scrollY, | ||
height: inputWrapperEl.getBoundingClientRect().height, | ||
width: inputWrapperEl.getBoundingClientRect().width, | ||
}; | ||
$app.datePickerState.inputWrapperElement.value = | ||
inputWrapperEl instanceof HTMLDivElement ? inputWrapperEl : undefined; | ||
}; | ||
hooks.useEffect(() => { | ||
if ($app.config.teleportTo) | ||
setInputDOMRect(); | ||
setInputElement(); | ||
const newClasses = ['sx__date-input-wrapper']; | ||
@@ -400,2 +394,26 @@ if ($app.datePickerState.isOpen.value) | ||
const isScrollable = (el) => { | ||
if (el) { | ||
const hasScrollableContent = el.scrollHeight > el.clientHeight; | ||
const overflowYStyle = window.getComputedStyle(el).overflowY; | ||
const isOverflowHidden = overflowYStyle.indexOf('hidden') !== -1; | ||
return hasScrollableContent && !isOverflowHidden; | ||
} | ||
return true; | ||
}; | ||
const getScrollableParents = (el, acc = []) => { | ||
if (!el || | ||
el === document.body || | ||
el.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { | ||
acc.push(window); | ||
return acc; | ||
} | ||
if (isScrollable(el)) { | ||
acc.push(el); | ||
} | ||
return getScrollableParents((el.assignedSlot | ||
? el.assignedSlot.parentNode | ||
: el.parentNode), acc); | ||
}; | ||
const POPUP_CLASS_NAME = 'sx__date-picker-popup'; | ||
@@ -418,16 +436,28 @@ function AppPopup() { | ||
const popupWidth = 332; | ||
const fixedPositionStyle = { | ||
top: $app.config.placement.includes('bottom') | ||
? $app.datePickerState.inputRect.value.height + | ||
$app.datePickerState.inputRect.value.y + | ||
1 // 1px border | ||
: $app.datePickerState.inputRect.value.y - remSize - popupHeight, // subtract remsize to leave room for label text | ||
left: $app.config.placement.includes('start') | ||
? $app.datePickerState.inputRect.value.x | ||
: $app.datePickerState.inputRect.value.x + | ||
$app.datePickerState.inputRect.value.width - | ||
popupWidth, | ||
width: popupWidth, | ||
position: 'fixed', | ||
const getFixedPositionStyles = () => { | ||
const inputWrapperEl = $app.datePickerState.inputWrapperElement.value; | ||
const inputRect = inputWrapperEl === null || inputWrapperEl === void 0 ? void 0 : inputWrapperEl.getBoundingClientRect(); | ||
if (inputWrapperEl === undefined || !(inputRect instanceof DOMRect)) | ||
return undefined; | ||
return { | ||
top: $app.config.placement.includes('bottom') | ||
? inputRect.height + inputRect.y + 1 // 1px border | ||
: inputRect.y - remSize - popupHeight, // subtract remsize to leave room for label text | ||
left: $app.config.placement.includes('start') | ||
? inputRect.x | ||
: inputRect.x + inputRect.width - popupWidth, | ||
width: popupWidth, | ||
position: 'fixed', | ||
}; | ||
}; | ||
const [fixedPositionStyle, setFixedPositionStyle] = hooks.useState(getFixedPositionStyles()); | ||
hooks.useEffect(() => { | ||
const inputWrapper = $app.datePickerState.inputWrapperElement.value; | ||
if (inputWrapper === undefined) | ||
return; | ||
const scrollableParents = getScrollableParents(inputWrapper); | ||
const scrollListener = () => setFixedPositionStyle(getFixedPositionStyles()); | ||
scrollableParents.forEach((parent) => parent.addEventListener('scroll', scrollListener)); | ||
return () => scrollableParents.forEach((parent) => parent.removeEventListener('scroll', scrollListener)); | ||
}, []); | ||
return (u(preact.Fragment, { children: u("div", { style: $app.config.teleportTo ? fixedPositionStyle : undefined, "data-testid": "date-picker-popup", className: popupClasses.join(' '), children: datePickerView === DatePickerView.MONTH_DAYS ? (u(MonthView, { seatYearsView: () => setDatePickerView(DatePickerView.YEARS) })) : (u(YearsView, { setMonthView: () => setDatePickerView(DatePickerView.MONTH_DAYS) })) }) })); | ||
@@ -731,3 +761,3 @@ } | ||
return { | ||
inputRect: signals.signal({ x: 0, y: 0, width: 0, height: 0, right: 0 }), | ||
inputWrapperElement: signals.signal(undefined), | ||
isOpen, | ||
@@ -734,0 +764,0 @@ datePickerView, |
@@ -76,8 +76,3 @@ import { Signal } from "@preact/signals"; | ||
datePickerView: Signal<DatePickerView>; | ||
inputRect: Signal<{ | ||
x: number; | ||
y: number; | ||
height: number; | ||
width: number; | ||
}>; | ||
inputWrapperElement: Signal<HTMLDivElement | undefined>; | ||
open(): void; | ||
@@ -84,0 +79,0 @@ close(): void; |
@@ -93,16 +93,10 @@ 'use strict'; | ||
const [wrapperClasses, setWrapperClasses] = hooks.useState([]); | ||
const setInputDOMRect = () => { | ||
const setInputElement = () => { | ||
const inputWrapperEl = document.getElementById(inputWrapperId); | ||
if (inputWrapperEl === null) | ||
return; | ||
$app.datePickerState.inputRect.value = { | ||
x: inputWrapperEl.getBoundingClientRect().left + window.scrollX, | ||
y: inputWrapperEl.getBoundingClientRect().top + window.scrollY, | ||
height: inputWrapperEl.getBoundingClientRect().height, | ||
width: inputWrapperEl.getBoundingClientRect().width, | ||
}; | ||
$app.datePickerState.inputWrapperElement.value = | ||
inputWrapperEl instanceof HTMLDivElement ? inputWrapperEl : undefined; | ||
}; | ||
hooks.useEffect(() => { | ||
if ($app.config.teleportTo) | ||
setInputDOMRect(); | ||
setInputElement(); | ||
const newClasses = ['sx__date-input-wrapper']; | ||
@@ -400,2 +394,26 @@ if ($app.datePickerState.isOpen.value) | ||
const isScrollable = (el) => { | ||
if (el) { | ||
const hasScrollableContent = el.scrollHeight > el.clientHeight; | ||
const overflowYStyle = window.getComputedStyle(el).overflowY; | ||
const isOverflowHidden = overflowYStyle.indexOf('hidden') !== -1; | ||
return hasScrollableContent && !isOverflowHidden; | ||
} | ||
return true; | ||
}; | ||
const getScrollableParents = (el, acc = []) => { | ||
if (!el || | ||
el === document.body || | ||
el.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { | ||
acc.push(window); | ||
return acc; | ||
} | ||
if (isScrollable(el)) { | ||
acc.push(el); | ||
} | ||
return getScrollableParents((el.assignedSlot | ||
? el.assignedSlot.parentNode | ||
: el.parentNode), acc); | ||
}; | ||
const POPUP_CLASS_NAME = 'sx__date-picker-popup'; | ||
@@ -418,16 +436,28 @@ function AppPopup() { | ||
const popupWidth = 332; | ||
const fixedPositionStyle = { | ||
top: $app.config.placement.includes('bottom') | ||
? $app.datePickerState.inputRect.value.height + | ||
$app.datePickerState.inputRect.value.y + | ||
1 // 1px border | ||
: $app.datePickerState.inputRect.value.y - remSize - popupHeight, // subtract remsize to leave room for label text | ||
left: $app.config.placement.includes('start') | ||
? $app.datePickerState.inputRect.value.x | ||
: $app.datePickerState.inputRect.value.x + | ||
$app.datePickerState.inputRect.value.width - | ||
popupWidth, | ||
width: popupWidth, | ||
position: 'fixed', | ||
const getFixedPositionStyles = () => { | ||
const inputWrapperEl = $app.datePickerState.inputWrapperElement.value; | ||
const inputRect = inputWrapperEl === null || inputWrapperEl === void 0 ? void 0 : inputWrapperEl.getBoundingClientRect(); | ||
if (inputWrapperEl === undefined || !(inputRect instanceof DOMRect)) | ||
return undefined; | ||
return { | ||
top: $app.config.placement.includes('bottom') | ||
? inputRect.height + inputRect.y + 1 // 1px border | ||
: inputRect.y - remSize - popupHeight, // subtract remsize to leave room for label text | ||
left: $app.config.placement.includes('start') | ||
? inputRect.x | ||
: inputRect.x + inputRect.width - popupWidth, | ||
width: popupWidth, | ||
position: 'fixed', | ||
}; | ||
}; | ||
const [fixedPositionStyle, setFixedPositionStyle] = hooks.useState(getFixedPositionStyles()); | ||
hooks.useEffect(() => { | ||
const inputWrapper = $app.datePickerState.inputWrapperElement.value; | ||
if (inputWrapper === undefined) | ||
return; | ||
const scrollableParents = getScrollableParents(inputWrapper); | ||
const scrollListener = () => setFixedPositionStyle(getFixedPositionStyles()); | ||
scrollableParents.forEach((parent) => parent.addEventListener('scroll', scrollListener)); | ||
return () => scrollableParents.forEach((parent) => parent.removeEventListener('scroll', scrollListener)); | ||
}, []); | ||
return (u(preact.Fragment, { children: u("div", { style: $app.config.teleportTo ? fixedPositionStyle : undefined, "data-testid": "date-picker-popup", className: popupClasses.join(' '), children: datePickerView === DatePickerView.MONTH_DAYS ? (u(MonthView, { seatYearsView: () => setDatePickerView(DatePickerView.YEARS) })) : (u(YearsView, { setMonthView: () => setDatePickerView(DatePickerView.MONTH_DAYS) })) }) })); | ||
@@ -731,3 +761,3 @@ } | ||
return { | ||
inputRect: signals.signal({ x: 0, y: 0, width: 0, height: 0, right: 0 }), | ||
inputWrapperElement: signals.signal(undefined), | ||
isOpen, | ||
@@ -734,0 +764,0 @@ datePickerView, |
@@ -76,8 +76,3 @@ import { Signal } from "@preact/signals"; | ||
datePickerView: Signal<DatePickerView>; | ||
inputRect: Signal<{ | ||
x: number; | ||
y: number; | ||
height: number; | ||
width: number; | ||
}>; | ||
inputWrapperElement: Signal<HTMLDivElement | undefined>; | ||
open(): void; | ||
@@ -84,0 +79,0 @@ close(): void; |
@@ -91,16 +91,10 @@ import { options, createContext, Fragment, Component, createElement, toChildArray, render } from 'preact'; | ||
const [wrapperClasses, setWrapperClasses] = useState([]); | ||
const setInputDOMRect = () => { | ||
const setInputElement = () => { | ||
const inputWrapperEl = document.getElementById(inputWrapperId); | ||
if (inputWrapperEl === null) | ||
return; | ||
$app.datePickerState.inputRect.value = { | ||
x: inputWrapperEl.getBoundingClientRect().left + window.scrollX, | ||
y: inputWrapperEl.getBoundingClientRect().top + window.scrollY, | ||
height: inputWrapperEl.getBoundingClientRect().height, | ||
width: inputWrapperEl.getBoundingClientRect().width, | ||
}; | ||
$app.datePickerState.inputWrapperElement.value = | ||
inputWrapperEl instanceof HTMLDivElement ? inputWrapperEl : undefined; | ||
}; | ||
useEffect(() => { | ||
if ($app.config.teleportTo) | ||
setInputDOMRect(); | ||
setInputElement(); | ||
const newClasses = ['sx__date-input-wrapper']; | ||
@@ -398,2 +392,26 @@ if ($app.datePickerState.isOpen.value) | ||
const isScrollable = (el) => { | ||
if (el) { | ||
const hasScrollableContent = el.scrollHeight > el.clientHeight; | ||
const overflowYStyle = window.getComputedStyle(el).overflowY; | ||
const isOverflowHidden = overflowYStyle.indexOf('hidden') !== -1; | ||
return hasScrollableContent && !isOverflowHidden; | ||
} | ||
return true; | ||
}; | ||
const getScrollableParents = (el, acc = []) => { | ||
if (!el || | ||
el === document.body || | ||
el.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { | ||
acc.push(window); | ||
return acc; | ||
} | ||
if (isScrollable(el)) { | ||
acc.push(el); | ||
} | ||
return getScrollableParents((el.assignedSlot | ||
? el.assignedSlot.parentNode | ||
: el.parentNode), acc); | ||
}; | ||
const POPUP_CLASS_NAME = 'sx__date-picker-popup'; | ||
@@ -416,16 +434,28 @@ function AppPopup() { | ||
const popupWidth = 332; | ||
const fixedPositionStyle = { | ||
top: $app.config.placement.includes('bottom') | ||
? $app.datePickerState.inputRect.value.height + | ||
$app.datePickerState.inputRect.value.y + | ||
1 // 1px border | ||
: $app.datePickerState.inputRect.value.y - remSize - popupHeight, // subtract remsize to leave room for label text | ||
left: $app.config.placement.includes('start') | ||
? $app.datePickerState.inputRect.value.x | ||
: $app.datePickerState.inputRect.value.x + | ||
$app.datePickerState.inputRect.value.width - | ||
popupWidth, | ||
width: popupWidth, | ||
position: 'fixed', | ||
const getFixedPositionStyles = () => { | ||
const inputWrapperEl = $app.datePickerState.inputWrapperElement.value; | ||
const inputRect = inputWrapperEl === null || inputWrapperEl === void 0 ? void 0 : inputWrapperEl.getBoundingClientRect(); | ||
if (inputWrapperEl === undefined || !(inputRect instanceof DOMRect)) | ||
return undefined; | ||
return { | ||
top: $app.config.placement.includes('bottom') | ||
? inputRect.height + inputRect.y + 1 // 1px border | ||
: inputRect.y - remSize - popupHeight, // subtract remsize to leave room for label text | ||
left: $app.config.placement.includes('start') | ||
? inputRect.x | ||
: inputRect.x + inputRect.width - popupWidth, | ||
width: popupWidth, | ||
position: 'fixed', | ||
}; | ||
}; | ||
const [fixedPositionStyle, setFixedPositionStyle] = useState(getFixedPositionStyles()); | ||
useEffect(() => { | ||
const inputWrapper = $app.datePickerState.inputWrapperElement.value; | ||
if (inputWrapper === undefined) | ||
return; | ||
const scrollableParents = getScrollableParents(inputWrapper); | ||
const scrollListener = () => setFixedPositionStyle(getFixedPositionStyles()); | ||
scrollableParents.forEach((parent) => parent.addEventListener('scroll', scrollListener)); | ||
return () => scrollableParents.forEach((parent) => parent.removeEventListener('scroll', scrollListener)); | ||
}, []); | ||
return (u(Fragment, { children: u("div", { style: $app.config.teleportTo ? fixedPositionStyle : undefined, "data-testid": "date-picker-popup", className: popupClasses.join(' '), children: datePickerView === DatePickerView.MONTH_DAYS ? (u(MonthView, { seatYearsView: () => setDatePickerView(DatePickerView.YEARS) })) : (u(YearsView, { setMonthView: () => setDatePickerView(DatePickerView.MONTH_DAYS) })) }) })); | ||
@@ -729,3 +759,3 @@ } | ||
return { | ||
inputRect: signal({ x: 0, y: 0, width: 0, height: 0, right: 0 }), | ||
inputWrapperElement: signal(undefined), | ||
isOpen, | ||
@@ -732,0 +762,0 @@ datePickerView, |
@@ -76,8 +76,3 @@ import { Signal } from "@preact/signals"; | ||
datePickerView: Signal<DatePickerView>; | ||
inputRect: Signal<{ | ||
x: number; | ||
y: number; | ||
height: number; | ||
width: number; | ||
}>; | ||
inputWrapperElement: Signal<HTMLDivElement | undefined>; | ||
open(): void; | ||
@@ -84,0 +79,0 @@ close(): void; |
{ | ||
"name": "@schedule-x/date-picker", | ||
"version": "1.37.0", | ||
"version": "1.38.0", | ||
"description": "Schedule-X date picker component", | ||
@@ -34,3 +34,3 @@ "author": { | ||
"homepage": "https://schedule-x.dev", | ||
"gitHead": "56762ba2e48a7464fed988212d19492b813310b0" | ||
"gitHead": "cd0170be0e84ad61f203856861505d883d2a25cc" | ||
} |
Sorry, the diff of this file is too big to display
261547
6455