@olundot/ui 0.23.1 → 0.25.0
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/CHANGELOG.md +22 -0
- package/dist/index.d.ts +18 -1
- package/dist/index.js +282 -128
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @olundot/ui
|
|
2
2
|
|
|
3
|
+
## 0.25.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- a848a56: DataTable `isRowSelectable`가 `'hidden'`을 돌려주면 그 행의 선택 칸을 비웁니다.
|
|
8
|
+
|
|
9
|
+
- 폴더처럼 처음부터 고를 대상이 아닌 행에 씁니다. 체크박스 없이 같은 폭의 빈 칸을 둬 열이 어긋나지 않습니다. 1024px 미만 카드도 제목이 같은 자리에서 시작합니다.
|
|
10
|
+
- 선택 규칙은 `false`(막힌 행)와 같습니다. 전체 선택, 선택 개수, `onSelectionChange`에서 빠지고 `selectedIds`에 들어 있어도 선택으로 그리지 않습니다.
|
|
11
|
+
- 반환 타입만 `boolean | 'hidden'`으로 넓혔습니다. `boolean`을 돌려주는 코드는 그대로 동작합니다.
|
|
12
|
+
|
|
13
|
+
## 0.24.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- 052cb2d: DatePicker 기간 고르기를 다듬고 기간 이동을 더했습니다.
|
|
18
|
+
|
|
19
|
+
- 1024px 이상 `day` 기간 팝오버는 두 달을 나란히 보입니다(폭 558px). 이전 달, 다음 달 버튼은 양 끝에 하나씩이고 한 달씩 넘깁니다. 키보드는 두 달 사이를 그대로 넘습니다.
|
|
20
|
+
- `day` 기간에도 끝 버튼 「시작일」「종료일」을 둡니다. 누른 끝만 고칩니다. 두 끝이 찬 뒤 시작을 고르면 종료는 그대로 두고 반영합니다. 1024px 미만 시트에도 보입니다.
|
|
21
|
+
- 시작을 고른 뒤 가리킨 날(마우스, 키보드 포커스)까지 범위를 옅게 미리 보입니다.
|
|
22
|
+
- 새 prop `lockStart`(시작 끝 잠금)와 `endMin`(종료 전용 하한)을 더했습니다.
|
|
23
|
+
- 새 prop `onStep`, `prevStepDisabled`, `nextStepDisabled`: 칸 양옆에 「이전 기간」「다음 기간」 버튼을 두고, 옮길 폭은 사용하는 쪽이 정합니다.
|
|
24
|
+
|
|
3
25
|
## 0.23.1
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -396,6 +396,15 @@ interface DatePickerBaseProps {
|
|
|
396
396
|
className?: string;
|
|
397
397
|
"aria-label"?: string;
|
|
398
398
|
"aria-describedby"?: string;
|
|
399
|
+
/**
|
|
400
|
+
* Shows "이전 기간" and "다음 기간" buttons beside the field, for views and filters that page
|
|
401
|
+
* through periods. Called with -1 or 1; the caller moves the value by its own step.
|
|
402
|
+
*/
|
|
403
|
+
onStep?: (direction: -1 | 1) => void;
|
|
404
|
+
/** Disables "이전 기간". */
|
|
405
|
+
prevStepDisabled?: boolean;
|
|
406
|
+
/** Disables "다음 기간" (the next period would pass `max`, for example). */
|
|
407
|
+
nextStepDisabled?: boolean;
|
|
399
408
|
}
|
|
400
409
|
interface DatePickerSingleProps extends DatePickerBaseProps {
|
|
401
410
|
selectionMode?: "single";
|
|
@@ -403,6 +412,8 @@ interface DatePickerSingleProps extends DatePickerBaseProps {
|
|
|
403
412
|
value: string;
|
|
404
413
|
onChange: (value: string) => void;
|
|
405
414
|
maxDays?: never;
|
|
415
|
+
lockStart?: never;
|
|
416
|
+
endMin?: never;
|
|
406
417
|
}
|
|
407
418
|
interface DatePickerRangeProps extends DatePickerBaseProps {
|
|
408
419
|
selectionMode: "range";
|
|
@@ -412,6 +423,10 @@ interface DatePickerRangeProps extends DatePickerBaseProps {
|
|
|
412
423
|
onChange: (value: DateRangeValue) => void;
|
|
413
424
|
/** Most days the range spans, the start day included. */
|
|
414
425
|
maxDays?: number;
|
|
426
|
+
/** Keeps the start as it is: its end button is disabled and only the end is picked. Give the reason in `description`. */
|
|
427
|
+
lockStart?: boolean;
|
|
428
|
+
/** Earliest end, in the value format. Unlike `min`, it leaves the start alone. With it, an earlier end day no longer swaps the ends. */
|
|
429
|
+
endMin?: string;
|
|
415
430
|
}
|
|
416
431
|
type DatePickerProps = DatePickerSingleProps | DatePickerRangeProps;
|
|
417
432
|
declare function DatePicker(props: DatePickerProps): react_jsx_runtime.JSX.Element;
|
|
@@ -1192,9 +1207,11 @@ interface DataTableBaseProps<T> extends Omit<React.HTMLAttributes<HTMLDivElement
|
|
|
1192
1207
|
/**
|
|
1193
1208
|
* With `selectable`, `false` blocks a row's selection: its checkbox is disabled, it is never
|
|
1194
1209
|
* drawn selected or passed to `onSelectionChange`, and select-all counts only the other rows.
|
|
1210
|
+
* `'hidden'` blocks it the same way and draws no checkbox, for a row that is never selected (a
|
|
1211
|
+
* folder among items); its slot stays empty at the checkbox width, so the columns line up.
|
|
1195
1212
|
* Navigating, expanding and the row menu still work.
|
|
1196
1213
|
*/
|
|
1197
|
-
isRowSelectable?: (row: T) => boolean;
|
|
1214
|
+
isRowSelectable?: (row: T) => boolean | 'hidden';
|
|
1198
1215
|
selectedIds?: Set<string>;
|
|
1199
1216
|
onSelectionChange?: (ids: Set<string>) => void;
|
|
1200
1217
|
/** Unit in the screen-reader selection message — `12명 선택됨`. Defaults to `개`. */
|
package/dist/index.js
CHANGED
|
@@ -1887,7 +1887,7 @@ Select.displayName = "Select";
|
|
|
1887
1887
|
|
|
1888
1888
|
// src/components/ui/date-picker.tsx
|
|
1889
1889
|
import * as React19 from "react";
|
|
1890
|
-
import { AlertCircle as AlertCircle4, Calendar as CalendarIcon, ChevronLeft, ChevronRight } from "lucide-react";
|
|
1890
|
+
import { AlertCircle as AlertCircle4, Calendar as CalendarIcon, ChevronLeft, ChevronRight, Lock } from "lucide-react";
|
|
1891
1891
|
|
|
1892
1892
|
// src/components/ui/dialog.tsx
|
|
1893
1893
|
import * as React17 from "react";
|
|
@@ -3704,7 +3704,7 @@ function formatRangeParts(value, granularity, now) {
|
|
|
3704
3704
|
import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3705
3705
|
var WEEKDAYS = ["\uC77C", "\uC6D4", "\uD654", "\uC218", "\uBAA9", "\uAE08", "\uD1A0"];
|
|
3706
3706
|
var HOURS = Array.from({ length: 24 }, (_, hour) => hour);
|
|
3707
|
-
var POPOVER_WIDTH = { day: 280, minute: 424 };
|
|
3707
|
+
var POPOVER_WIDTH = { day: 280, dayRange: 558, minute: 424 };
|
|
3708
3708
|
var COLLISION_PADDING = 8;
|
|
3709
3709
|
var pad22 = (n) => String(n).padStart(2, "0");
|
|
3710
3710
|
var isoDay = (parts) => `${parts.year}-${pad22(parts.month)}-${pad22(parts.day)}`;
|
|
@@ -3742,11 +3742,17 @@ function DatePicker(props) {
|
|
|
3742
3742
|
id,
|
|
3743
3743
|
className,
|
|
3744
3744
|
"aria-label": ariaLabel,
|
|
3745
|
-
"aria-describedby": ariaDescribedBy
|
|
3745
|
+
"aria-describedby": ariaDescribedBy,
|
|
3746
|
+
onStep,
|
|
3747
|
+
prevStepDisabled = false,
|
|
3748
|
+
nextStepDisabled = false
|
|
3746
3749
|
} = props;
|
|
3747
3750
|
const range = props.selectionMode === "range";
|
|
3748
3751
|
const minute = granularity === "minute";
|
|
3749
3752
|
const maxDays = range ? props.maxDays : void 0;
|
|
3753
|
+
const lockStart = range && Boolean(props.lockStart);
|
|
3754
|
+
const endMinValue = range ? props.endMin : void 0;
|
|
3755
|
+
const popoverKind = minute ? "minute" : range ? "dayRange" : "day";
|
|
3750
3756
|
const field = useFormFieldControl();
|
|
3751
3757
|
const generatedId = React19.useId();
|
|
3752
3758
|
const baseId = `date-picker-${generatedId.replace(/:/g, "")}`;
|
|
@@ -3760,14 +3766,18 @@ function DatePicker(props) {
|
|
|
3760
3766
|
const parts = parseValue(max, granularity);
|
|
3761
3767
|
return parts && !minute ? { ...parts, hour: 23, minute: 59 } : parts;
|
|
3762
3768
|
}, [max, granularity, minute]);
|
|
3769
|
+
const endMinParts = React19.useMemo(() => parseValue(endMinValue, granularity), [endMinValue, granularity]);
|
|
3770
|
+
const swapEnds = !minute && !lockStart && !endMinParts;
|
|
3763
3771
|
const [open, setOpen] = React19.useState(false);
|
|
3764
3772
|
const [layer, setLayer] = React19.useState("popover");
|
|
3765
3773
|
const [align, setAlign] = React19.useState("start");
|
|
3766
3774
|
const [draft, setDraft] = React19.useState({ from: "", to: "" });
|
|
3767
|
-
const [
|
|
3775
|
+
const [pickedEnd, setActiveEnd] = React19.useState("from");
|
|
3776
|
+
const activeEnd = lockStart ? "to" : pickedEnd;
|
|
3768
3777
|
const [timeOpen, setTimeOpen] = React19.useState(false);
|
|
3769
3778
|
const [view, setView] = React19.useState(() => ({ year: 2e3, month: 1 }));
|
|
3770
3779
|
const [focusDay, setFocusDay] = React19.useState(() => todayParts(/* @__PURE__ */ new Date()));
|
|
3780
|
+
const [pointDay, setPointDay] = React19.useState(null);
|
|
3771
3781
|
const triggerRef = React19.useRef(null);
|
|
3772
3782
|
const [outerLabel, setOuterLabel] = React19.useState(void 0);
|
|
3773
3783
|
const [windowName, setWindowName] = React19.useState(void 0);
|
|
@@ -3807,7 +3817,7 @@ function DatePicker(props) {
|
|
|
3807
3817
|
setOuterLabel(labelTextOf(triggerRef.current));
|
|
3808
3818
|
}, [ariaLabel, label, field, triggerId]);
|
|
3809
3819
|
function startView() {
|
|
3810
|
-
const anchor = range ? parseValue(rangeValue.from, granularity) ?? parseValue(rangeValue.to, granularity) : parseValue(singleValue, granularity);
|
|
3820
|
+
const anchor = range ? (lockStart ? parseValue(rangeValue.to, granularity) : null) ?? parseValue(rangeValue.from, granularity) ?? parseValue(rangeValue.to, granularity) : parseValue(singleValue, granularity);
|
|
3811
3821
|
return anchor ?? parseValue(initialMonth, granularity) ?? todayParts(/* @__PURE__ */ new Date());
|
|
3812
3822
|
}
|
|
3813
3823
|
function handleOpenChange(next) {
|
|
@@ -3819,13 +3829,14 @@ function DatePicker(props) {
|
|
|
3819
3829
|
setDraft(rangeValue);
|
|
3820
3830
|
setActiveEnd(range && rangeValue.from && !rangeValue.to ? "to" : "from");
|
|
3821
3831
|
setTimeOpen(false);
|
|
3832
|
+
setPointDay(null);
|
|
3822
3833
|
followed.current = rangeValue;
|
|
3823
3834
|
lastEmitted.current = null;
|
|
3824
3835
|
setWindowName(currentWindowName());
|
|
3825
3836
|
const wide = isWideViewport();
|
|
3826
3837
|
setLayer(wide ? "popover" : "sheet");
|
|
3827
3838
|
const box = triggerRef.current?.getBoundingClientRect();
|
|
3828
|
-
const width = POPOVER_WIDTH[
|
|
3839
|
+
const width = POPOVER_WIDTH[popoverKind];
|
|
3829
3840
|
setAlign(box && typeof window !== "undefined" && box.left + width > window.innerWidth - COLLISION_PADDING ? "end" : "start");
|
|
3830
3841
|
}
|
|
3831
3842
|
setOpen(next);
|
|
@@ -3834,13 +3845,25 @@ function DatePicker(props) {
|
|
|
3834
3845
|
const toParts = parseValue(shownRange.to, granularity);
|
|
3835
3846
|
const singleParts = parseValue(singleValue, granularity);
|
|
3836
3847
|
const editing = range ? activeEnd === "from" ? fromParts : toParts : singleParts;
|
|
3837
|
-
const editMin = range && activeEnd === "to"
|
|
3848
|
+
const editMin = range && activeEnd === "to" ? [minParts, minute ? fromParts : null, endMinParts].reduce(
|
|
3849
|
+
(latest, parts) => parts && (!latest || minuteKey(parts) > minuteKey(latest)) ? parts : latest,
|
|
3850
|
+
null
|
|
3851
|
+
) : minParts;
|
|
3852
|
+
const editMax = (() => {
|
|
3853
|
+
if (!range || activeEnd !== "to" || !fromParts || maxDays === void 0) return maxParts;
|
|
3854
|
+
const last = { ...addDays(fromParts, maxDays - 1), hour: 23, minute: 59 };
|
|
3855
|
+
return maxParts && minuteKey(maxParts) < minuteKey(last) ? maxParts : last;
|
|
3856
|
+
})();
|
|
3838
3857
|
function commitRange(next, edited) {
|
|
3839
3858
|
const from = parseValue(next.from, granularity);
|
|
3840
3859
|
const to = parseValue(next.to, granularity);
|
|
3860
|
+
if (edited === "to" && to && (editMin && minuteKey(to) < minuteKey(editMin) || editMax && minuteKey(to) > minuteKey(editMax))) {
|
|
3861
|
+
return draft;
|
|
3862
|
+
}
|
|
3841
3863
|
let value = next;
|
|
3842
3864
|
if (from && to && (minuteKey(from) > minuteKey(to) || maxDays !== void 0 && daysBetween(from, to) > maxDays - 1)) {
|
|
3843
3865
|
const cleared = edited === "from" ? "to" : "from";
|
|
3866
|
+
if (lockStart && cleared === "from") return draft;
|
|
3844
3867
|
value = cleared === "to" ? { from: next.from, to: "" } : { from: "", to: next.to };
|
|
3845
3868
|
setActiveEnd(cleared);
|
|
3846
3869
|
}
|
|
@@ -3859,16 +3882,11 @@ function DatePicker(props) {
|
|
|
3859
3882
|
function dayDisabled(cell) {
|
|
3860
3883
|
if (minParts && dayKey(cell) < dayKey(minParts)) return true;
|
|
3861
3884
|
if (maxParts && dayKey(cell) > dayKey(maxParts)) return true;
|
|
3862
|
-
if (!range) return false;
|
|
3863
|
-
if (
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
}
|
|
3868
|
-
return false;
|
|
3869
|
-
}
|
|
3870
|
-
if (fromParts && !toParts && maxDays !== void 0) return daysBetween(fromParts, cell) > maxDays - 1;
|
|
3871
|
-
return false;
|
|
3885
|
+
if (!range || activeEnd !== "to") return false;
|
|
3886
|
+
if (endMinParts && dayKey(cell) < dayKey(endMinParts)) return true;
|
|
3887
|
+
if (!fromParts) return false;
|
|
3888
|
+
if (!swapEnds && dayKey(cell) < dayKey(fromParts)) return true;
|
|
3889
|
+
return maxDays !== void 0 && daysBetween(fromParts, cell) > maxDays - 1;
|
|
3872
3890
|
}
|
|
3873
3891
|
function selectDay(cell) {
|
|
3874
3892
|
if (dayDisabled(cell)) return;
|
|
@@ -3879,13 +3897,16 @@ function DatePicker(props) {
|
|
|
3879
3897
|
return;
|
|
3880
3898
|
}
|
|
3881
3899
|
if (!minute) {
|
|
3882
|
-
|
|
3883
|
-
|
|
3900
|
+
const picked = formatValue(cell, granularity);
|
|
3901
|
+
const filled = Boolean(fromParts && toParts);
|
|
3902
|
+
const next = activeEnd === "from" ? { from: picked, to: draft.to } : swapEnds && fromParts && dayKey(cell) < dayKey(fromParts) ? { from: picked, to: draft.from } : { from: draft.from, to: picked };
|
|
3903
|
+
const value = commitRange(next, activeEnd);
|
|
3904
|
+
if (!value.from || !value.to) {
|
|
3905
|
+
setActiveEnd(value.from ? "to" : "from");
|
|
3884
3906
|
return;
|
|
3885
3907
|
}
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
setOpen(false);
|
|
3908
|
+
if (activeEnd === "to" || !filled) setOpen(false);
|
|
3909
|
+
else setActiveEnd("to");
|
|
3889
3910
|
return;
|
|
3890
3911
|
}
|
|
3891
3912
|
if (activeEnd === "from") {
|
|
@@ -3893,7 +3914,7 @@ function DatePicker(props) {
|
|
|
3893
3914
|
if (!commitRange({ from: formatValue(nextFrom, granularity), to: draft.to }, "from").to) setActiveEnd("to");
|
|
3894
3915
|
return;
|
|
3895
3916
|
}
|
|
3896
|
-
const nextTo = clampParts({ ...baseFor("to"), year: cell.year, month: cell.month, day: cell.day }, editMin,
|
|
3917
|
+
const nextTo = clampParts({ ...baseFor("to"), year: cell.year, month: cell.month, day: cell.day }, editMin, editMax);
|
|
3897
3918
|
commitRange({ from: draft.from, to: formatValue(nextTo, granularity) }, "to");
|
|
3898
3919
|
}
|
|
3899
3920
|
function changeTime(patch) {
|
|
@@ -3901,9 +3922,18 @@ function DatePicker(props) {
|
|
|
3901
3922
|
props.onChange(formatValue(clampParts({ ...baseFor(null), ...patch }, minParts, maxParts), granularity));
|
|
3902
3923
|
return;
|
|
3903
3924
|
}
|
|
3904
|
-
const next = formatValue(clampParts({ ...baseFor(activeEnd), ...patch }, editMin,
|
|
3925
|
+
const next = formatValue(clampParts({ ...baseFor(activeEnd), ...patch }, editMin, editMax), granularity);
|
|
3905
3926
|
commitRange(activeEnd === "from" ? { from: next, to: draft.to } : { from: draft.from, to: next }, activeEnd);
|
|
3906
3927
|
}
|
|
3928
|
+
function activateEnd(end, kind) {
|
|
3929
|
+
setActiveEnd(end);
|
|
3930
|
+
const parts = end === "from" ? fromParts : toParts;
|
|
3931
|
+
if (!parts) return;
|
|
3932
|
+
const shown = kind === "popover" && popoverKind === "dayRange" ? 2 : 1;
|
|
3933
|
+
const offset = (parts.year - view.year) * 12 + parts.month - view.month;
|
|
3934
|
+
if (offset < 0 || offset >= shown) setView({ year: parts.year, month: parts.month });
|
|
3935
|
+
setFocusDay({ ...parts, hour: 0, minute: 0 });
|
|
3936
|
+
}
|
|
3907
3937
|
const endPlaceholder = minute ? "\uC885\uB8CC \uC77C\uC2DC" : "\uC885\uB8CC\uC77C";
|
|
3908
3938
|
let summary;
|
|
3909
3939
|
let summaryText = "";
|
|
@@ -3995,11 +4025,25 @@ function DatePicker(props) {
|
|
|
3995
4025
|
}
|
|
3996
4026
|
);
|
|
3997
4027
|
const today = todayParts(now);
|
|
4028
|
+
const preview = (() => {
|
|
4029
|
+
if (!range || !pointDay || dayDisabled(pointDay)) return null;
|
|
4030
|
+
const edited = activeEnd === "from" ? fromParts : toParts;
|
|
4031
|
+
if (edited && sameDay(pointDay, edited)) return null;
|
|
4032
|
+
if (activeEnd === "to" && fromParts) {
|
|
4033
|
+
return dayKey(pointDay) < dayKey(fromParts) ? { from: pointDay, to: fromParts, kept: fromParts } : { from: fromParts, to: pointDay, kept: fromParts };
|
|
4034
|
+
}
|
|
4035
|
+
if (activeEnd === "from" && toParts && dayKey(pointDay) <= dayKey(toParts) && (maxDays === void 0 || daysBetween(pointDay, toParts) <= maxDays - 1)) {
|
|
4036
|
+
return { from: pointDay, to: toParts, kept: toParts };
|
|
4037
|
+
}
|
|
4038
|
+
return null;
|
|
4039
|
+
})();
|
|
3998
4040
|
const selectedFor = (cell) => {
|
|
3999
4041
|
if (!range) return Boolean(singleParts && sameDay(cell, singleParts));
|
|
4042
|
+
if (preview) return sameDay(cell, preview.kept);
|
|
4000
4043
|
return Boolean(fromParts && sameDay(cell, fromParts) || toParts && sameDay(cell, toParts));
|
|
4001
4044
|
};
|
|
4002
|
-
const inRange = (cell) => Boolean(range && fromParts && toParts && dayKey(cell) > dayKey(fromParts) && dayKey(cell) < dayKey(toParts));
|
|
4045
|
+
const inRange = (cell) => Boolean(range && !preview && fromParts && toParts && dayKey(cell) > dayKey(fromParts) && dayKey(cell) < dayKey(toParts));
|
|
4046
|
+
const inPreview = (cell) => Boolean(preview && !sameDay(cell, preview.kept) && dayKey(cell) >= dayKey(preview.from) && dayKey(cell) <= dayKey(preview.to));
|
|
4003
4047
|
const focusCalendar = React19.useRef(false);
|
|
4004
4048
|
React19.useEffect(() => {
|
|
4005
4049
|
const active = typeof document !== "undefined" ? document.activeElement : null;
|
|
@@ -4032,6 +4076,7 @@ function DatePicker(props) {
|
|
|
4032
4076
|
{
|
|
4033
4077
|
kind,
|
|
4034
4078
|
baseId,
|
|
4079
|
+
months: kind === "popover" && popoverKind === "dayRange" ? 2 : 1,
|
|
4035
4080
|
view,
|
|
4036
4081
|
onView: setView,
|
|
4037
4082
|
focusDay,
|
|
@@ -4040,6 +4085,8 @@ function DatePicker(props) {
|
|
|
4040
4085
|
isDisabled: dayDisabled,
|
|
4041
4086
|
isSelected: selectedFor,
|
|
4042
4087
|
isInRange: inRange,
|
|
4088
|
+
isPreview: inPreview,
|
|
4089
|
+
onPoint: setPointDay,
|
|
4043
4090
|
onSelect: selectDay
|
|
4044
4091
|
}
|
|
4045
4092
|
);
|
|
@@ -4049,12 +4096,14 @@ function DatePicker(props) {
|
|
|
4049
4096
|
const timeRowValue = editing ? `${pad22(editing.hour)}:${pad22(editing.minute)}` : "-";
|
|
4050
4097
|
const panel = (kind) => /* @__PURE__ */ jsxs14("div", { "data-slot": "date-picker-panel", "data-layer": kind, "data-picker": baseId, className: "flex flex-col", children: [
|
|
4051
4098
|
popoverHeader != null ? /* @__PURE__ */ jsx16("div", { className: "mb-[var(--space-3)]", children: popoverHeader }) : null,
|
|
4052
|
-
range
|
|
4099
|
+
range ? /* @__PURE__ */ jsx16(
|
|
4053
4100
|
EndTabs,
|
|
4054
4101
|
{
|
|
4055
4102
|
kind,
|
|
4103
|
+
names: minute ? ["\uC2DC\uC791 \uC77C\uC2DC", "\uC885\uB8CC \uC77C\uC2DC"] : ["\uC2DC\uC791\uC77C", "\uC885\uB8CC\uC77C"],
|
|
4104
|
+
locked: lockStart ? "from" : void 0,
|
|
4056
4105
|
active: activeEnd,
|
|
4057
|
-
onActivate:
|
|
4106
|
+
onActivate: (end) => activateEnd(end, kind),
|
|
4058
4107
|
from: fromParts ? formatSingle(shownRange.from, granularity, now) : "",
|
|
4059
4108
|
to: toParts ? formatSingle(shownRange.to, granularity, now) : ""
|
|
4060
4109
|
}
|
|
@@ -4093,7 +4142,7 @@ function DatePicker(props) {
|
|
|
4093
4142
|
) : null
|
|
4094
4143
|
] })
|
|
4095
4144
|
] });
|
|
4096
|
-
const
|
|
4145
|
+
const picker = /* @__PURE__ */ jsxs14(Fragment3, { children: [
|
|
4097
4146
|
/* @__PURE__ */ jsxs14(Popover, { open: open && layer === "popover", onOpenChange: handleOpenChange, children: [
|
|
4098
4147
|
/* @__PURE__ */ jsx16(PopoverAnchor, { asChild: true, children: trigger }),
|
|
4099
4148
|
/* @__PURE__ */ jsx16(
|
|
@@ -4102,7 +4151,7 @@ function DatePicker(props) {
|
|
|
4102
4151
|
align,
|
|
4103
4152
|
sideOffset: 4,
|
|
4104
4153
|
collisionPadding: COLLISION_PADDING,
|
|
4105
|
-
className: cn("p-[var(--space-3)]",
|
|
4154
|
+
className: cn("p-[var(--space-3)]", { day: "w-[280px]", dayRange: "w-[558px]", minute: "w-[424px]" }[popoverKind]),
|
|
4106
4155
|
"aria-label": titleText,
|
|
4107
4156
|
onOpenAutoFocus: (event) => {
|
|
4108
4157
|
event.preventDefault();
|
|
@@ -4125,6 +4174,34 @@ function DatePicker(props) {
|
|
|
4125
4174
|
] }),
|
|
4126
4175
|
/* @__PURE__ */ jsx16(Dialog, { open: open && layer === "sheet", onOpenChange: handleOpenChange, title: titleText, size: "sm", children: /* @__PURE__ */ jsx16("div", { className: "mx-auto w-full max-w-[360px]", children: panel("sheet") }) })
|
|
4127
4176
|
] });
|
|
4177
|
+
const stepSize = { sm: "sm", md: "md", lg: "lg" };
|
|
4178
|
+
const control = onStep ? /* @__PURE__ */ jsxs14("div", { "data-slot": "date-picker-stepper", className: cn("flex items-center gap-[var(--space-1)]", fullWidth ? "w-full" : "w-fit"), children: [
|
|
4179
|
+
/* @__PURE__ */ jsx16(
|
|
4180
|
+
IconButton,
|
|
4181
|
+
{
|
|
4182
|
+
icon: ChevronLeft,
|
|
4183
|
+
appearance: "outline",
|
|
4184
|
+
tone: "neutral",
|
|
4185
|
+
size: stepSize[size],
|
|
4186
|
+
"aria-label": "\uC774\uC804 \uAE30\uAC04",
|
|
4187
|
+
disabled: disabled || prevStepDisabled,
|
|
4188
|
+
onClick: () => onStep(-1)
|
|
4189
|
+
}
|
|
4190
|
+
),
|
|
4191
|
+
/* @__PURE__ */ jsx16("div", { className: cn("min-w-0", fullWidth && "flex-1"), children: picker }),
|
|
4192
|
+
/* @__PURE__ */ jsx16(
|
|
4193
|
+
IconButton,
|
|
4194
|
+
{
|
|
4195
|
+
icon: ChevronRight,
|
|
4196
|
+
appearance: "outline",
|
|
4197
|
+
tone: "neutral",
|
|
4198
|
+
size: stepSize[size],
|
|
4199
|
+
"aria-label": "\uB2E4\uC74C \uAE30\uAC04",
|
|
4200
|
+
disabled: disabled || nextStepDisabled,
|
|
4201
|
+
onClick: () => onStep(1)
|
|
4202
|
+
}
|
|
4203
|
+
)
|
|
4204
|
+
] }) : picker;
|
|
4128
4205
|
if (!topLabel && !showDescription && !showMessage) return control;
|
|
4129
4206
|
return /* @__PURE__ */ jsxs14("div", { "data-slot": "date-picker-field", className: cn("flex flex-col gap-[var(--space-1)]", fullWidth ? "w-full" : "w-fit"), children: [
|
|
4130
4207
|
topLabel ? /* @__PURE__ */ jsx16(
|
|
@@ -4148,51 +4225,69 @@ function DatePicker(props) {
|
|
|
4148
4225
|
DatePicker.displayName = "DatePicker";
|
|
4149
4226
|
function EndTabs({
|
|
4150
4227
|
kind,
|
|
4228
|
+
names,
|
|
4229
|
+
locked,
|
|
4151
4230
|
active,
|
|
4152
4231
|
onActivate,
|
|
4153
4232
|
from,
|
|
4154
4233
|
to
|
|
4155
4234
|
}) {
|
|
4156
4235
|
const ends = [
|
|
4157
|
-
{ end: "from", name:
|
|
4158
|
-
{ end: "to", name:
|
|
4236
|
+
{ end: "from", name: names[0], value: from },
|
|
4237
|
+
{ end: "to", name: names[1], value: to }
|
|
4159
4238
|
];
|
|
4160
|
-
return /* @__PURE__ */ jsx16("div", { "data-slot": "date-picker-ends", className: cn("mb-[var(--space-3)] grid grid-cols-2 gap-[var(--space-2)]", kind === "sheet" && "mb-[var(--space-4)]"), children: ends.map(({ end, name, value }) =>
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4239
|
+
return /* @__PURE__ */ jsx16("div", { "data-slot": "date-picker-ends", className: cn("mb-[var(--space-3)] grid grid-cols-2 gap-[var(--space-2)]", kind === "sheet" && "mb-[var(--space-4)]"), children: ends.map(({ end, name, value }) => {
|
|
4240
|
+
const isLocked = locked === end;
|
|
4241
|
+
return /* @__PURE__ */ jsxs14(
|
|
4242
|
+
"button",
|
|
4243
|
+
{
|
|
4244
|
+
type: "button",
|
|
4245
|
+
"data-slot": "date-picker-end",
|
|
4246
|
+
"aria-pressed": active === end,
|
|
4247
|
+
disabled: isLocked,
|
|
4248
|
+
onClick: () => onActivate(end),
|
|
4249
|
+
className: cn(
|
|
4250
|
+
"flex min-w-0 flex-col items-start rounded-[var(--radius-md)] border px-[var(--space-3)] py-[var(--space-2)] text-left",
|
|
4251
|
+
"outline-none focus-visible:shadow-[0_0_0_2px_var(--focus-ring)]",
|
|
4252
|
+
isLocked ? "cursor-not-allowed border-[var(--border)] bg-[var(--action-disabled-bg)]" : active === end ? "border-[var(--border-strong)] bg-[var(--action-selected)]" : "border-[var(--border)] hover:bg-[var(--action-hover)]"
|
|
4253
|
+
),
|
|
4254
|
+
children: [
|
|
4255
|
+
/* @__PURE__ */ jsxs14("span", { className: "flex w-full items-center justify-between gap-[var(--space-1)] text-[11px] leading-snug text-text-tertiary", children: [
|
|
4256
|
+
/* @__PURE__ */ jsx16("span", { children: name }),
|
|
4257
|
+
isLocked ? /* @__PURE__ */ jsx16(Lock, { "aria-hidden": "true", size: 12, strokeWidth: 2, className: "shrink-0" }) : null
|
|
4258
|
+
] }),
|
|
4259
|
+
/* @__PURE__ */ jsx16(
|
|
4260
|
+
"span",
|
|
4261
|
+
{
|
|
4262
|
+
className: cn(
|
|
4263
|
+
"w-full truncate text-[13px] font-semibold leading-snug font-numeric tabular-nums",
|
|
4264
|
+
isLocked ? "text-text-disabled" : value ? "text-foreground" : "text-text-tertiary"
|
|
4265
|
+
),
|
|
4266
|
+
children: value || "-"
|
|
4267
|
+
}
|
|
4268
|
+
)
|
|
4269
|
+
]
|
|
4270
|
+
},
|
|
4271
|
+
end
|
|
4272
|
+
);
|
|
4273
|
+
}) });
|
|
4179
4274
|
}
|
|
4180
|
-
function Calendar({ kind, baseId, view, onView, focusDay, onFocusDay, today, isDisabled, isSelected, isInRange, onSelect }) {
|
|
4181
|
-
const
|
|
4275
|
+
function Calendar({ kind, baseId, months, view, onView, focusDay, onFocusDay, today, isDisabled, isSelected, isInRange, isPreview, onPoint, onSelect }) {
|
|
4276
|
+
const rootRef = React19.useRef(null);
|
|
4182
4277
|
const focusPending = React19.useRef(false);
|
|
4183
|
-
const
|
|
4184
|
-
const
|
|
4185
|
-
const
|
|
4186
|
-
const tabbable = focusDay.year === view.year && focusDay.month === view.month ? focusDay : { ...focusDay, year: view.year, month: view.month, day: 1 };
|
|
4278
|
+
const shown = Array.from({ length: months }, (_, index) => addMonths(view.year, view.month, index));
|
|
4279
|
+
const inView = (day) => shown.some((month) => month.year === day.year && month.month === day.month);
|
|
4280
|
+
const tabbable = inView(focusDay) ? focusDay : { ...focusDay, year: view.year, month: view.month, day: 1 };
|
|
4187
4281
|
React19.useEffect(() => {
|
|
4188
4282
|
if (!focusPending.current) return;
|
|
4189
4283
|
focusPending.current = false;
|
|
4190
|
-
|
|
4284
|
+
rootRef.current?.querySelector(`[data-date="${isoDay(focusDay)}"]`)?.focus();
|
|
4191
4285
|
});
|
|
4192
4286
|
function move(next) {
|
|
4193
4287
|
focusPending.current = true;
|
|
4194
4288
|
onFocusDay(next);
|
|
4195
|
-
if (next
|
|
4289
|
+
if (inView(next)) return;
|
|
4290
|
+
onView(dayKey(next) < dayKey({ ...view, day: 1 }) ? { year: next.year, month: next.month } : addMonths(next.year, next.month, 1 - months));
|
|
4196
4291
|
}
|
|
4197
4292
|
function moveMonth(delta) {
|
|
4198
4293
|
onView(addMonths(view.year, view.month, delta));
|
|
@@ -4216,61 +4311,100 @@ function Calendar({ kind, baseId, view, onView, focusDay, onFocusDay, today, isD
|
|
|
4216
4311
|
move(target());
|
|
4217
4312
|
}
|
|
4218
4313
|
const sheet = kind === "sheet";
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
"
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4314
|
+
const navSize = sheet ? "md" : "xs";
|
|
4315
|
+
const headingId = (index) => index === 0 ? `${baseId}-month` : `${baseId}-month-${index + 1}`;
|
|
4316
|
+
const width = sheet ? "w-full" : "w-[256px]";
|
|
4317
|
+
const blankOutside = months > 1;
|
|
4318
|
+
return /* @__PURE__ */ jsxs14("div", { ref: rootRef, "data-slot": "date-picker-calendar", className: cn("flex flex-col", sheet ? "w-full" : "shrink-0"), children: [
|
|
4319
|
+
/* @__PURE__ */ jsx16("div", { className: "flex gap-[var(--space-5)]", children: shown.map((month, index) => (
|
|
4320
|
+
// Keyed by position, not month: the ‹ › pressed stays the same node and keeps focus.
|
|
4321
|
+
/* @__PURE__ */ jsxs14("div", { className: cn("flex items-center justify-between", width), children: [
|
|
4322
|
+
index === 0 ? /* @__PURE__ */ jsx16(IconButton, { icon: ChevronLeft, appearance: "ghost", tone: "neutral", size: navSize, "aria-label": "\uC774\uC804 \uB2EC", onClick: () => moveMonth(-1) }) : /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: "size-[28px]" }),
|
|
4323
|
+
/* @__PURE__ */ jsxs14("span", { id: headingId(index), "aria-live": "polite", className: "text-[13px] font-semibold text-text-primary font-numeric tabular-nums", children: [
|
|
4324
|
+
month.year,
|
|
4325
|
+
"\uB144 ",
|
|
4326
|
+
month.month,
|
|
4327
|
+
"\uC6D4"
|
|
4328
|
+
] }),
|
|
4329
|
+
index === months - 1 ? /* @__PURE__ */ jsx16(IconButton, { icon: ChevronRight, appearance: "ghost", tone: "neutral", size: navSize, "aria-label": "\uB2E4\uC74C \uB2EC", onClick: () => moveMonth(1) }) : /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: "size-[28px]" })
|
|
4330
|
+
] }, index)
|
|
4331
|
+
)) }),
|
|
4332
|
+
/* @__PURE__ */ jsx16(
|
|
4333
|
+
"div",
|
|
4334
|
+
{
|
|
4335
|
+
className: "mt-[var(--space-1)] flex gap-[var(--space-5)]",
|
|
4336
|
+
onMouseLeave: () => onPoint(null),
|
|
4337
|
+
onBlur: (event) => {
|
|
4338
|
+
if (!(event.relatedTarget instanceof Node && event.currentTarget.contains(event.relatedTarget))) onPoint(null);
|
|
4339
|
+
},
|
|
4340
|
+
children: shown.map((month, index) => {
|
|
4341
|
+
const cells = buildCalendarCells(month.year, month.month).map((cell) => ({ ...cell, hour: 0, minute: 0 }));
|
|
4342
|
+
const weeks = Array.from({ length: 6 }, (_, week) => cells.slice(week * 7, week * 7 + 7));
|
|
4343
|
+
return /* @__PURE__ */ jsxs14(
|
|
4344
|
+
"div",
|
|
4345
|
+
{
|
|
4346
|
+
role: "grid",
|
|
4347
|
+
"aria-labelledby": headingId(index),
|
|
4348
|
+
"data-slot": "date-picker-grid",
|
|
4349
|
+
className: cn("flex flex-col gap-[2px]", width),
|
|
4350
|
+
children: [
|
|
4351
|
+
/* @__PURE__ */ jsx16("div", { role: "row", className: "grid grid-cols-7 gap-[2px]", children: WEEKDAYS.map((weekday) => /* @__PURE__ */ jsx16("span", { role: "columnheader", className: "py-[var(--space-1)] text-center text-[10px] font-semibold text-text-tertiary", children: weekday }, weekday)) }),
|
|
4352
|
+
weeks.map((week, row) => /* @__PURE__ */ jsx16("div", { role: "row", className: "grid grid-cols-7 gap-[2px]", children: week.map((cell) => {
|
|
4353
|
+
const outside = !cell.inMonth;
|
|
4354
|
+
if (outside && blankOutside) {
|
|
4355
|
+
return /* @__PURE__ */ jsx16("span", { role: "gridcell", "data-outside": "", className: "aspect-square" }, isoDay(cell));
|
|
4356
|
+
}
|
|
4357
|
+
const disabled = isDisabled(cell);
|
|
4358
|
+
const selected = !outside && isSelected(cell);
|
|
4359
|
+
const between = !outside && !selected && isInRange(cell);
|
|
4360
|
+
const previewed = !outside && !selected && isPreview(cell);
|
|
4361
|
+
const isToday = !outside && sameDay(cell, today);
|
|
4362
|
+
return /* @__PURE__ */ jsx16(
|
|
4363
|
+
"button",
|
|
4364
|
+
{
|
|
4365
|
+
type: "button",
|
|
4366
|
+
role: "gridcell",
|
|
4367
|
+
"data-date": outside ? void 0 : isoDay(cell),
|
|
4368
|
+
"data-selected": selected ? "" : void 0,
|
|
4369
|
+
"data-in-range": between ? "" : void 0,
|
|
4370
|
+
"data-preview": previewed ? "" : void 0,
|
|
4371
|
+
disabled: outside,
|
|
4372
|
+
tabIndex: !outside && sameDay(cell, tabbable) ? 0 : -1,
|
|
4373
|
+
"aria-label": `${cell.year}\uB144 ${cell.month}\uC6D4 ${cell.day}\uC77C`,
|
|
4374
|
+
"aria-selected": outside ? void 0 : selected,
|
|
4375
|
+
"aria-disabled": !outside && disabled ? true : void 0,
|
|
4376
|
+
"aria-current": isToday ? "date" : void 0,
|
|
4377
|
+
onClick: () => {
|
|
4378
|
+
if (outside || disabled) return;
|
|
4379
|
+
focusPending.current = false;
|
|
4380
|
+
onFocusDay(cell);
|
|
4381
|
+
onSelect(cell);
|
|
4382
|
+
},
|
|
4383
|
+
onKeyDown: (event) => onKeyDown(event, cell),
|
|
4384
|
+
onMouseEnter: () => onPoint(cell),
|
|
4385
|
+
onFocus: () => onPoint(cell),
|
|
4386
|
+
className: cn(
|
|
4387
|
+
"flex items-center justify-center rounded-[var(--radius-sm)] text-[12px] font-numeric tabular-nums outline-none",
|
|
4388
|
+
sheet ? "h-[40px] text-[14px]" : "aspect-square",
|
|
4389
|
+
"focus-visible:shadow-[0_0_0_2px_var(--focus-ring)]",
|
|
4390
|
+
outside || disabled ? "cursor-default text-text-disabled" : "cursor-pointer text-text-secondary hover:bg-[var(--action-hover)]",
|
|
4391
|
+
between && "bg-[var(--action-selected)] text-foreground",
|
|
4392
|
+
previewed && "bg-[var(--action-hover)] text-foreground shadow-[inset_0_1px_0_0_var(--border-strong),inset_0_-1px_0_0_var(--border-strong)]",
|
|
4393
|
+
isToday && !selected && "border border-[var(--border-strong)]",
|
|
4394
|
+
selected && "bg-[var(--primary)] font-bold text-[var(--primary-fg)] hover:bg-[var(--primary)]"
|
|
4395
|
+
),
|
|
4396
|
+
children: cell.day
|
|
4397
|
+
},
|
|
4398
|
+
isoDay(cell)
|
|
4399
|
+
);
|
|
4400
|
+
}) }, row))
|
|
4401
|
+
]
|
|
4257
4402
|
},
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
outside || disabled ? "cursor-default text-text-disabled" : "cursor-pointer text-text-secondary hover:bg-[var(--action-hover)]",
|
|
4264
|
-
between && "bg-[var(--action-selected)] text-foreground",
|
|
4265
|
-
isToday && !selected && "border border-[var(--border-strong)]",
|
|
4266
|
-
selected && "bg-[var(--primary)] font-bold text-[var(--primary-fg)] hover:bg-[var(--primary)]"
|
|
4267
|
-
),
|
|
4268
|
-
children: cell.day
|
|
4269
|
-
},
|
|
4270
|
-
isoDay(cell)
|
|
4271
|
-
);
|
|
4272
|
-
}) }, index))
|
|
4273
|
-
] })
|
|
4403
|
+
`${month.year}-${month.month}`
|
|
4404
|
+
);
|
|
4405
|
+
})
|
|
4406
|
+
}
|
|
4407
|
+
)
|
|
4274
4408
|
] });
|
|
4275
4409
|
}
|
|
4276
4410
|
function TimeColumns({ kind, baseId, editing, hasValue, centerKey, minuteStep, min, max, onChange, onEnter, autoFocus = false }) {
|
|
@@ -4328,15 +4462,10 @@ function TimeColumn({ kind, id, name, options, selected, centerKey, onSelect, on
|
|
|
4328
4462
|
if (!list || !item) return;
|
|
4329
4463
|
list.scrollTop = item.offsetTop - list.offsetTop - (list.clientHeight - item.offsetHeight) / 2;
|
|
4330
4464
|
}, [centerKey]);
|
|
4331
|
-
const
|
|
4465
|
+
const [focusAsk, setFocusAsk] = React19.useState(0);
|
|
4332
4466
|
React19.useEffect(() => {
|
|
4333
|
-
if (
|
|
4334
|
-
|
|
4335
|
-
pendingFocus.current = null;
|
|
4336
|
-
});
|
|
4337
|
-
function focusValue(value) {
|
|
4338
|
-
pendingFocus.current = value;
|
|
4339
|
-
}
|
|
4467
|
+
if (focusAsk) listRef.current?.querySelector('[aria-selected="true"]')?.focus();
|
|
4468
|
+
}, [focusAsk]);
|
|
4340
4469
|
function onKeyDown(event, value) {
|
|
4341
4470
|
if (event.key === "Enter") {
|
|
4342
4471
|
event.preventDefault();
|
|
@@ -4368,7 +4497,7 @@ function TimeColumn({ kind, id, name, options, selected, centerKey, onSelect, on
|
|
|
4368
4497
|
const next = target();
|
|
4369
4498
|
if (!next || next.value === value) return;
|
|
4370
4499
|
onSelect(next.value);
|
|
4371
|
-
|
|
4500
|
+
setFocusAsk((count) => count + 1);
|
|
4372
4501
|
}
|
|
4373
4502
|
const sheet = kind === "sheet";
|
|
4374
4503
|
return /* @__PURE__ */ jsxs14("div", { className: cn("flex flex-col", sheet ? "w-[88px]" : "h-full w-[56px]"), children: [
|
|
@@ -5621,7 +5750,7 @@ import * as React30 from "react";
|
|
|
5621
5750
|
import * as React29 from "react";
|
|
5622
5751
|
import { Tabs as TabsPrimitive } from "radix-ui";
|
|
5623
5752
|
import { cva as cva10 } from "class-variance-authority";
|
|
5624
|
-
import { Lock } from "lucide-react";
|
|
5753
|
+
import { Lock as Lock2 } from "lucide-react";
|
|
5625
5754
|
import { Fragment as Fragment10, jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
5626
5755
|
var tabsRootVariants = cva10("w-full", {
|
|
5627
5756
|
variants: {
|
|
@@ -5894,7 +6023,7 @@ var Tabs = React29.forwardRef(
|
|
|
5894
6023
|
/* @__PURE__ */ jsx26("span", { className: "sr-only", children: ` ${tab.badge}` })
|
|
5895
6024
|
] }) : null,
|
|
5896
6025
|
tab.disabled ? /* @__PURE__ */ jsx26(
|
|
5897
|
-
|
|
6026
|
+
Lock2,
|
|
5898
6027
|
{
|
|
5899
6028
|
"aria-hidden": "true",
|
|
5900
6029
|
"data-slot": "tabs-disabled-icon",
|
|
@@ -8524,8 +8653,19 @@ function RowCheckbox({
|
|
|
8524
8653
|
columns,
|
|
8525
8654
|
selected,
|
|
8526
8655
|
selectionBlocked,
|
|
8656
|
+
selectionHidden,
|
|
8527
8657
|
onToggle
|
|
8528
8658
|
}) {
|
|
8659
|
+
if (selectionHidden) {
|
|
8660
|
+
return /* @__PURE__ */ jsx39(
|
|
8661
|
+
"span",
|
|
8662
|
+
{
|
|
8663
|
+
"aria-hidden": "true",
|
|
8664
|
+
"data-slot": "data-table-row-checkbox-placeholder",
|
|
8665
|
+
className: "block h-[calc(var(--space-4)+var(--space-1))] w-[calc(var(--space-4)+var(--space-1)+var(--space-3))] shrink-0"
|
|
8666
|
+
}
|
|
8667
|
+
);
|
|
8668
|
+
}
|
|
8529
8669
|
return /* @__PURE__ */ jsx39(
|
|
8530
8670
|
Checkbox,
|
|
8531
8671
|
{
|
|
@@ -8636,6 +8776,7 @@ function DataTableRowView({
|
|
|
8636
8776
|
selectable,
|
|
8637
8777
|
selected,
|
|
8638
8778
|
selectionBlocked,
|
|
8779
|
+
selectionHidden,
|
|
8639
8780
|
visuallySelected,
|
|
8640
8781
|
href,
|
|
8641
8782
|
activatable,
|
|
@@ -8672,7 +8813,7 @@ function DataTableRowView({
|
|
|
8672
8813
|
} : handlers.onClick,
|
|
8673
8814
|
onKeyDown: handlers.onKeyDown,
|
|
8674
8815
|
children: [
|
|
8675
|
-
selectable ? /* @__PURE__ */ jsx39("div", { role: "cell", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx39(RowCheckbox, { row, rowId, columns, selected, selectionBlocked, onToggle }) }) : null,
|
|
8816
|
+
selectable ? /* @__PURE__ */ jsx39("div", { role: "cell", className: "px-[var(--space-4)]", children: /* @__PURE__ */ jsx39(RowCheckbox, { row, rowId, columns, selected, selectionBlocked, selectionHidden, onToggle }) }) : null,
|
|
8676
8817
|
columns.map((column, columnIndex) => {
|
|
8677
8818
|
const align = column.align ?? "left";
|
|
8678
8819
|
const content = getRenderedCell(row, column);
|
|
@@ -8746,6 +8887,7 @@ function DataTableMobileCardView({
|
|
|
8746
8887
|
selectable,
|
|
8747
8888
|
selected,
|
|
8748
8889
|
selectionBlocked,
|
|
8890
|
+
selectionHidden,
|
|
8749
8891
|
visuallySelected,
|
|
8750
8892
|
href,
|
|
8751
8893
|
activatable,
|
|
@@ -8772,7 +8914,7 @@ function DataTableMobileCardView({
|
|
|
8772
8914
|
const navigable = linked || activatable;
|
|
8773
8915
|
const opened = useOpenedOnce(expand?.expanded ?? false);
|
|
8774
8916
|
const leading = selectable || content.leading != null ? /* @__PURE__ */ jsxs35("span", { className: "flex items-center gap-[var(--space-2)]", children: [
|
|
8775
|
-
selectable ? /* @__PURE__ */ jsx39(RowCheckbox, { row, rowId, columns, selected, selectionBlocked, onToggle }) : null,
|
|
8917
|
+
selectable ? /* @__PURE__ */ jsx39(RowCheckbox, { row, rowId, columns, selected, selectionBlocked, selectionHidden, onToggle }) : null,
|
|
8776
8918
|
content.leading
|
|
8777
8919
|
] }) : void 0;
|
|
8778
8920
|
let title = content.title;
|
|
@@ -9252,9 +9394,19 @@ function DataTableInner({
|
|
|
9252
9394
|
mobile: () => mobileListRef.current ?? mobileRef.current
|
|
9253
9395
|
}
|
|
9254
9396
|
});
|
|
9255
|
-
const blockedIds = new Set(
|
|
9256
|
-
|
|
9257
|
-
)
|
|
9397
|
+
const blockedIds = /* @__PURE__ */ new Set();
|
|
9398
|
+
const hiddenIds = /* @__PURE__ */ new Set();
|
|
9399
|
+
if (selectable && isRowSelectable) {
|
|
9400
|
+
data.forEach((row) => {
|
|
9401
|
+
const verdict = isRowSelectable(row);
|
|
9402
|
+
if (verdict === "hidden") {
|
|
9403
|
+
hiddenIds.add(getRowId(row, keyField));
|
|
9404
|
+
}
|
|
9405
|
+
if (!verdict || verdict === "hidden") {
|
|
9406
|
+
blockedIds.add(getRowId(row, keyField));
|
|
9407
|
+
}
|
|
9408
|
+
});
|
|
9409
|
+
}
|
|
9258
9410
|
const selectableRowIds = rowIds.filter((id) => !blockedIds.has(id));
|
|
9259
9411
|
const resolvedSelectedIds = selectedIds ?? /* @__PURE__ */ new Set();
|
|
9260
9412
|
const selectedCount = selectableRowIds.filter((id) => resolvedSelectedIds.has(id)).length;
|
|
@@ -9377,6 +9529,7 @@ function DataTableInner({
|
|
|
9377
9529
|
const getItemProps = (row, layout, index) => {
|
|
9378
9530
|
const rowId = getRowId(row, keyField);
|
|
9379
9531
|
const selectionBlocked = blockedIds.has(rowId);
|
|
9532
|
+
const selectionHidden = hiddenIds.has(rowId);
|
|
9380
9533
|
const selected = !selectionBlocked && resolvedSelectedIds.has(rowId);
|
|
9381
9534
|
const href = rowHref?.(row);
|
|
9382
9535
|
const linked = Boolean(linkComponent && href);
|
|
@@ -9387,6 +9540,7 @@ function DataTableInner({
|
|
|
9387
9540
|
selectable,
|
|
9388
9541
|
selected,
|
|
9389
9542
|
selectionBlocked,
|
|
9543
|
+
selectionHidden,
|
|
9390
9544
|
visuallySelected: selected || rowId === activeRowId || rowId === contextMenu?.rowId,
|
|
9391
9545
|
href,
|
|
9392
9546
|
activatable: !linked && Boolean(href || onRowClick),
|