@ecohouse/ui 0.1.52 → 0.1.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +80 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +80 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/DatePicker/DatePicker.tsx +104 -15
package/dist/index.d.cts
CHANGED
|
@@ -958,6 +958,15 @@ type DatePickerBaseProps = Omit<ViewProps, "style" | "children"> & {
|
|
|
958
958
|
closeOnSelect?: boolean;
|
|
959
959
|
minDate?: Date;
|
|
960
960
|
maxDate?: Date;
|
|
961
|
+
/** Calendar days that cannot be selected, such as dates already booked. */
|
|
962
|
+
unavailableDates?: readonly Date[];
|
|
963
|
+
/**
|
|
964
|
+
* When true, unavailable days cannot be selected and a range cannot include them.
|
|
965
|
+
* Defaults to false so booked days can stay visual-only.
|
|
966
|
+
*/
|
|
967
|
+
blockUnavailableDates?: boolean;
|
|
968
|
+
/** Accessibility label for an unavailable day. */
|
|
969
|
+
unavailableDateLabel?: string;
|
|
961
970
|
/** First visible month when the calendar opens; defaults to the selected value's month, else today. */
|
|
962
971
|
defaultVisibleMonth?: Date;
|
|
963
972
|
/** Monday-first full month names. Defaults to Armenian. */
|
package/dist/index.d.ts
CHANGED
|
@@ -958,6 +958,15 @@ type DatePickerBaseProps = Omit<ViewProps, "style" | "children"> & {
|
|
|
958
958
|
closeOnSelect?: boolean;
|
|
959
959
|
minDate?: Date;
|
|
960
960
|
maxDate?: Date;
|
|
961
|
+
/** Calendar days that cannot be selected, such as dates already booked. */
|
|
962
|
+
unavailableDates?: readonly Date[];
|
|
963
|
+
/**
|
|
964
|
+
* When true, unavailable days cannot be selected and a range cannot include them.
|
|
965
|
+
* Defaults to false so booked days can stay visual-only.
|
|
966
|
+
*/
|
|
967
|
+
blockUnavailableDates?: boolean;
|
|
968
|
+
/** Accessibility label for an unavailable day. */
|
|
969
|
+
unavailableDateLabel?: string;
|
|
961
970
|
/** First visible month when the calendar opens; defaults to the selected value's month, else today. */
|
|
962
971
|
defaultVisibleMonth?: Date;
|
|
963
972
|
/** Monday-first full month names. Defaults to Armenian. */
|
package/dist/index.js
CHANGED
|
@@ -34240,6 +34240,16 @@ var DEFAULT_MONTH_NAMES = [
|
|
|
34240
34240
|
"\u0534\u0565\u056F\u057F\u0565\u0574\u0562\u0565\u0580"
|
|
34241
34241
|
];
|
|
34242
34242
|
var DEFAULT_WEEKDAY_LABELS = ["\u0535\u0550", "\u0535\u0554", "\u0549\u0550", "\u0540\u0546", "\u0548\u0552\u0550", "\u0547\u0532", "\u053F\u0550"];
|
|
34243
|
+
function rangeIncludesUnavailable(start, end, isUnavailable) {
|
|
34244
|
+
const cursor = startOfDay(start);
|
|
34245
|
+
const last = startOfDay(end);
|
|
34246
|
+
const step = isBefore(last, cursor) ? -1 : 1;
|
|
34247
|
+
while (true) {
|
|
34248
|
+
if (isUnavailable(cursor)) return true;
|
|
34249
|
+
if (isSameDay(cursor, last)) return false;
|
|
34250
|
+
cursor.setDate(cursor.getDate() + step);
|
|
34251
|
+
}
|
|
34252
|
+
}
|
|
34243
34253
|
var EMPTY_RANGE = { start: null, end: null };
|
|
34244
34254
|
var DEFAULT_WIDTH = 320;
|
|
34245
34255
|
var DEFAULT_MENU_HEIGHT = 388;
|
|
@@ -34293,6 +34303,9 @@ var DatePicker = forwardRef(
|
|
|
34293
34303
|
closeOnSelect = true,
|
|
34294
34304
|
minDate,
|
|
34295
34305
|
maxDate,
|
|
34306
|
+
unavailableDates,
|
|
34307
|
+
unavailableDateLabel = "Booked",
|
|
34308
|
+
blockUnavailableDates = false,
|
|
34296
34309
|
defaultVisibleMonth,
|
|
34297
34310
|
monthNames = DEFAULT_MONTH_NAMES,
|
|
34298
34311
|
weekdayLabels = DEFAULT_WEEKDAY_LABELS,
|
|
@@ -34311,6 +34324,17 @@ var DatePicker = forwardRef(
|
|
|
34311
34324
|
onValueChange: _onValueChange,
|
|
34312
34325
|
...rest
|
|
34313
34326
|
} = props;
|
|
34327
|
+
const unavailableDayKeys = useMemo(() => {
|
|
34328
|
+
const keys = /* @__PURE__ */ new Set();
|
|
34329
|
+
for (const date of unavailableDates ?? []) {
|
|
34330
|
+
keys.add(startOfDay(date).getTime());
|
|
34331
|
+
}
|
|
34332
|
+
return keys;
|
|
34333
|
+
}, [unavailableDates]);
|
|
34334
|
+
const isUnavailable = useCallback(
|
|
34335
|
+
(day) => unavailableDayKeys.has(startOfDay(day).getTime()),
|
|
34336
|
+
[unavailableDayKeys]
|
|
34337
|
+
);
|
|
34314
34338
|
const isRange = props.range === true;
|
|
34315
34339
|
const usesRangeTrigger = isRange && variant !== "default";
|
|
34316
34340
|
const formatValue = formatValueProp ?? (usesRangeTrigger ? (date) => formatDateDayShortMonth(date, monthNames) : formatDate);
|
|
@@ -34413,6 +34437,7 @@ var DatePicker = forwardRef(
|
|
|
34413
34437
|
const handleDayPress = useCallback(
|
|
34414
34438
|
(day) => {
|
|
34415
34439
|
if (disabled || isDateDisabled(day, minDate, maxDate)) return;
|
|
34440
|
+
if (blockUnavailableDates && isUnavailable(day)) return;
|
|
34416
34441
|
const picked = startOfDay(day);
|
|
34417
34442
|
if (!isRange) {
|
|
34418
34443
|
if (!isValueControlled) setUncontrolledSingle(picked);
|
|
@@ -34423,14 +34448,19 @@ var DatePicker = forwardRef(
|
|
|
34423
34448
|
const { start, end } = rangeValue;
|
|
34424
34449
|
const startingNewRange = !start || start && end;
|
|
34425
34450
|
const nextRange = startingNewRange ? { start: picked, end: null } : isBefore(picked, start) ? { start: picked, end: null } : { start, end: picked };
|
|
34451
|
+
if (blockUnavailableDates && nextRange.start && nextRange.end && rangeIncludesUnavailable(nextRange.start, nextRange.end, isUnavailable)) {
|
|
34452
|
+
return;
|
|
34453
|
+
}
|
|
34426
34454
|
if (!isValueControlled) setUncontrolledRange(nextRange);
|
|
34427
34455
|
props.onValueChange?.(nextRange);
|
|
34428
34456
|
if (closeOnSelect && nextRange.start && nextRange.end) setOpen(false);
|
|
34429
34457
|
},
|
|
34430
34458
|
[
|
|
34459
|
+
blockUnavailableDates,
|
|
34431
34460
|
closeOnSelect,
|
|
34432
34461
|
disabled,
|
|
34433
34462
|
isRange,
|
|
34463
|
+
isUnavailable,
|
|
34434
34464
|
isValueControlled,
|
|
34435
34465
|
maxDate,
|
|
34436
34466
|
minDate,
|
|
@@ -34509,7 +34539,8 @@ var DatePicker = forwardRef(
|
|
|
34509
34539
|
styles26.menu,
|
|
34510
34540
|
usesRangeTrigger && styles26.rangeMenu,
|
|
34511
34541
|
hideTrigger ? styles26.menuInline : menuAlignEnd ? styles26.menuAlignEnd : styles26.menuAlignStart,
|
|
34512
|
-
calendarStyle
|
|
34542
|
+
calendarStyle,
|
|
34543
|
+
styles26.menuFitContent
|
|
34513
34544
|
],
|
|
34514
34545
|
children: [
|
|
34515
34546
|
/* @__PURE__ */ jsxs(View, { style: styles26.calendarHeader, children: [
|
|
@@ -34541,7 +34572,7 @@ var DatePicker = forwardRef(
|
|
|
34541
34572
|
}
|
|
34542
34573
|
)
|
|
34543
34574
|
] }),
|
|
34544
|
-
/* @__PURE__ */ jsxs(View, { children: [
|
|
34575
|
+
/* @__PURE__ */ jsxs(View, { style: styles26.calendarGrid, children: [
|
|
34545
34576
|
/* @__PURE__ */ jsx(View, { style: styles26.weekdayRow, children: weekdayLabels.map((weekdayLabel, index) => /* @__PURE__ */ jsx(View, { style: styles26.weekdayCell, children: /* @__PURE__ */ jsx(Text, { style: styles26.weekdayText, children: weekdayLabel }) }, `${weekdayLabel}-${index}`)) }),
|
|
34546
34577
|
weeks.map((week, weekIndex) => {
|
|
34547
34578
|
let rangeHighlightStyle = null;
|
|
@@ -34596,24 +34627,26 @@ var DatePicker = forwardRef(
|
|
|
34596
34627
|
const isRangeStart = isRange && isSameDay(day, rangeValue.start);
|
|
34597
34628
|
const isRangeEnd = isRange && isSameDay(day, rangeValue.end);
|
|
34598
34629
|
const isSelectedEndpoint = isSelectedSingle || isRangeStart || isRangeEnd;
|
|
34630
|
+
const dayUnavailable = isUnavailable(day);
|
|
34631
|
+
const dayBlocked = blockUnavailableDates && dayUnavailable;
|
|
34599
34632
|
const dayDisabled = disabled || isDateDisabled(day, minDate, maxDate);
|
|
34600
34633
|
const dayKey = startOfDay(day).getTime();
|
|
34601
|
-
const isHovered = !dayDisabled && !isSelectedEndpoint && hoveredDayKey === dayKey;
|
|
34634
|
+
const isHovered = !dayDisabled && !dayBlocked && !isSelectedEndpoint && hoveredDayKey === dayKey;
|
|
34602
34635
|
const dayTextColor = isSelectedEndpoint ? colors.white : dayDisabled ? colors.grey400 : isToday ? colors.primary : !inCurrentMonth ? colors.grey300 : colors.white;
|
|
34603
34636
|
return /* @__PURE__ */ jsxs(
|
|
34604
34637
|
Pressable,
|
|
34605
34638
|
{
|
|
34606
34639
|
onPress: () => handleDayPress(day),
|
|
34607
|
-
disabled: dayDisabled,
|
|
34640
|
+
disabled: dayDisabled || dayBlocked,
|
|
34608
34641
|
onHoverIn: () => setHoveredDayKey(dayKey),
|
|
34609
34642
|
onHoverOut: () => setHoveredDayKey((current) => current === dayKey ? null : current),
|
|
34610
34643
|
onPressIn: () => setHoveredDayKey(dayKey),
|
|
34611
34644
|
onPressOut: () => setHoveredDayKey((current) => current === dayKey ? null : current),
|
|
34612
34645
|
style: styles26.dayCellWrap,
|
|
34613
34646
|
accessibilityRole: "button",
|
|
34614
|
-
accessibilityLabel: formatValue(day),
|
|
34647
|
+
accessibilityLabel: dayUnavailable ? `${formatValue(day)}, ${unavailableDateLabel}` : formatValue(day),
|
|
34615
34648
|
accessibilityState: {
|
|
34616
|
-
disabled: dayDisabled,
|
|
34649
|
+
disabled: dayDisabled || dayBlocked,
|
|
34617
34650
|
selected: isSelectedEndpoint
|
|
34618
34651
|
},
|
|
34619
34652
|
children: [
|
|
@@ -34623,9 +34656,20 @@ var DatePicker = forwardRef(
|
|
|
34623
34656
|
style: [
|
|
34624
34657
|
styles26.dayCircle,
|
|
34625
34658
|
isSelectedEndpoint && styles26.dayCircleSelected,
|
|
34659
|
+
dayUnavailable && styles26.dayCircleBooked,
|
|
34626
34660
|
isHovered && styles26.dayCircleHovered
|
|
34627
34661
|
],
|
|
34628
|
-
children: /* @__PURE__ */ jsx(
|
|
34662
|
+
children: /* @__PURE__ */ jsx(
|
|
34663
|
+
Text,
|
|
34664
|
+
{
|
|
34665
|
+
style: [
|
|
34666
|
+
styles26.dayText,
|
|
34667
|
+
{ color: dayTextColor },
|
|
34668
|
+
dayUnavailable && styles26.dayTextBooked
|
|
34669
|
+
],
|
|
34670
|
+
children: day.getDate()
|
|
34671
|
+
}
|
|
34672
|
+
)
|
|
34629
34673
|
}
|
|
34630
34674
|
),
|
|
34631
34675
|
isToday && !isSelectedEndpoint ? /* @__PURE__ */ jsx(View, { style: styles26.todayDot }) : null
|
|
@@ -34763,7 +34807,7 @@ var styles26 = StyleSheet.create({
|
|
|
34763
34807
|
menu: {
|
|
34764
34808
|
position: "absolute",
|
|
34765
34809
|
top: "100%",
|
|
34766
|
-
|
|
34810
|
+
alignSelf: "flex-start",
|
|
34767
34811
|
height: DEFAULT_MENU_HEIGHT,
|
|
34768
34812
|
marginTop: 8,
|
|
34769
34813
|
zIndex: 10,
|
|
@@ -34797,10 +34841,26 @@ var styles26 = StyleSheet.create({
|
|
|
34797
34841
|
right: "auto",
|
|
34798
34842
|
marginTop: 0
|
|
34799
34843
|
},
|
|
34800
|
-
rangeMenu: {
|
|
34801
|
-
|
|
34844
|
+
rangeMenu: {},
|
|
34845
|
+
menuFitContent: {
|
|
34846
|
+
width: MENU_CONTENT_WIDTH + MENU_PADDING * 2,
|
|
34847
|
+
maxWidth: MENU_CONTENT_WIDTH + MENU_PADDING * 2,
|
|
34848
|
+
alignSelf: "flex-start",
|
|
34849
|
+
alignItems: "flex-start",
|
|
34850
|
+
...Platform.select({
|
|
34851
|
+
web: {
|
|
34852
|
+
width: "fit-content",
|
|
34853
|
+
maxWidth: "fit-content"
|
|
34854
|
+
},
|
|
34855
|
+
default: {}
|
|
34856
|
+
})
|
|
34857
|
+
},
|
|
34858
|
+
calendarGrid: {
|
|
34859
|
+
width: MENU_CONTENT_WIDTH,
|
|
34860
|
+
alignSelf: "flex-start"
|
|
34802
34861
|
},
|
|
34803
34862
|
calendarHeader: {
|
|
34863
|
+
width: MENU_CONTENT_WIDTH,
|
|
34804
34864
|
height: HEADER_HEIGHT3,
|
|
34805
34865
|
paddingTop: 8,
|
|
34806
34866
|
paddingBottom: 8,
|
|
@@ -34834,9 +34894,8 @@ var styles26 = StyleSheet.create({
|
|
|
34834
34894
|
weekdayCell: {
|
|
34835
34895
|
width: DAY_CELL_WIDTH,
|
|
34836
34896
|
height: WEEKDAY_ROW_HEIGHT,
|
|
34837
|
-
flexGrow:
|
|
34838
|
-
flexShrink:
|
|
34839
|
-
flexBasis: 0,
|
|
34897
|
+
flexGrow: 0,
|
|
34898
|
+
flexShrink: 0,
|
|
34840
34899
|
alignItems: "center",
|
|
34841
34900
|
justifyContent: "center"
|
|
34842
34901
|
},
|
|
@@ -34864,9 +34923,8 @@ var styles26 = StyleSheet.create({
|
|
|
34864
34923
|
dayCellWrap: {
|
|
34865
34924
|
width: DAY_CELL_WIDTH,
|
|
34866
34925
|
height: DAY_CELL_HEIGHT,
|
|
34867
|
-
flexGrow:
|
|
34868
|
-
flexShrink:
|
|
34869
|
-
flexBasis: 0,
|
|
34926
|
+
flexGrow: 0,
|
|
34927
|
+
flexShrink: 0,
|
|
34870
34928
|
alignItems: "center",
|
|
34871
34929
|
justifyContent: "center",
|
|
34872
34930
|
opacity: 1
|
|
@@ -34883,6 +34941,12 @@ var styles26 = StyleSheet.create({
|
|
|
34883
34941
|
dayCircleSelected: {
|
|
34884
34942
|
backgroundColor: colors.primary
|
|
34885
34943
|
},
|
|
34944
|
+
dayCircleBooked: {
|
|
34945
|
+
backgroundColor: colors.grey700
|
|
34946
|
+
},
|
|
34947
|
+
dayTextBooked: {
|
|
34948
|
+
textDecorationLine: "line-through"
|
|
34949
|
+
},
|
|
34886
34950
|
dayCircleHovered: {
|
|
34887
34951
|
backgroundColor: colors.grey600
|
|
34888
34952
|
},
|