@wipco/sdui 0.18.1 → 0.19.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.
@@ -1,497 +0,0 @@
1
- import { useOverlayLayer } from './chunk-XQPTSEJC.js';
2
- import { Icon } from './chunk-WIDDHR7L.js';
3
- import { boxed } from './chunk-SAN4IX6N.js';
4
- import { createContext, useState, useRef, useMemo, useCallback, useEffect, useLayoutEffect, useContext } from 'react';
5
- import { jsxs, jsx } from 'react/jsx-runtime';
6
-
7
- // src/env.ts
8
- var DEV = (() => {
9
- try {
10
- const meta = import.meta;
11
- return Boolean(meta.env?.DEV);
12
- } catch {
13
- return false;
14
- }
15
- })();
16
-
17
- // src/adapter.ts
18
- function isSafeNavigationTarget(to) {
19
- if (typeof to !== "string") return false;
20
- const value = to.replace(/[\u0000-\u0020]/g, "");
21
- if (value === "") return false;
22
- if (value.startsWith("//")) return false;
23
- if (value.startsWith("/") || value.startsWith("?") || value.startsWith("#")) return true;
24
- return /^https?:\/\//i.test(value);
25
- }
26
- async function defaultFetch(path, init) {
27
- const response = await fetch(path, {
28
- method: init.method,
29
- headers: { "content-type": "application/json", accept: "application/json" },
30
- credentials: "include",
31
- body: init.body === void 0 ? void 0 : JSON.stringify(init.body),
32
- signal: init.signal
33
- });
34
- const text = await response.text();
35
- let json = null;
36
- if (text) {
37
- try {
38
- json = JSON.parse(text);
39
- } catch {
40
- json = null;
41
- }
42
- }
43
- if (!response.ok) {
44
- const message = json && typeof json === "object" && typeof json.message === "string" ? json.message : `\uC694\uCCAD\uC774 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4 (${response.status})`;
45
- throw new Error(message);
46
- }
47
- return json;
48
- }
49
- var defaultAdapter = {
50
- navigate: (to) => {
51
- if (!isSafeNavigationTarget(to)) {
52
- console.error(`[sdui] \uD5C8\uC6A9\uB418\uC9C0 \uC54A\uB294 navigate \uB300\uC0C1: ${String(to)}`);
53
- return;
54
- }
55
- window.location.assign(to);
56
- },
57
- fetch: defaultFetch,
58
- rawFetch: (path) => fetch(path, { credentials: "include" }),
59
- // 항등함수. 계약을 문서화하고, 컴포넌트가 `useSduiAssetResolver()`를 조건 없이
60
- // 부를 수 있게 하는 것이 전부다. **이 함수 참조 자체가 표식**이기도 하다 —
61
- // `assetResolverOf`가 이것과 같은지 보고 "주입 없음"을 판정한다.
62
- resolveAsset: (url) => url,
63
- invalidate: (prefix) => {
64
- if (DEV) console.warn(`[sdui] invalidate \uC561\uC158\uC774 \uC5B4\uB311\uD130 \uC5C6\uC774 \uD638\uCD9C\uB428 (prefix: ${prefix})`);
65
- },
66
- refresh: () => {
67
- if (DEV) console.warn("[sdui] refresh \uC561\uC158\uC774 \uC5B4\uB311\uD130 \uC5C6\uC774 \uD638\uCD9C\uB428");
68
- }
69
- };
70
- function resolveAdapter(adapter) {
71
- const merged = { ...defaultAdapter };
72
- if (adapter) {
73
- for (const [key, value] of Object.entries(adapter)) {
74
- if (value !== void 0) merged[key] = value;
75
- }
76
- }
77
- return merged;
78
- }
79
- var SduiAdapterContext = createContext(null);
80
- function useSduiAdapter() {
81
- return useContext(SduiAdapterContext);
82
- }
83
- function assetResolverOf(adapter) {
84
- const resolve = adapter?.resolveAsset;
85
- if (!resolve || resolve === defaultAdapter.resolveAsset) return null;
86
- return resolve;
87
- }
88
- function useSduiAssetResolver() {
89
- const adapter = useContext(SduiAdapterContext);
90
- return adapter?.resolveAsset ?? defaultAdapter.resolveAsset;
91
- }
92
- function useSduiSandbox() {
93
- return useContext(SduiAdapterContext)?.sandbox === true;
94
- }
95
- function hostFetchOf(adapter) {
96
- const hostFetch = adapter?.fetch;
97
- if (!hostFetch || hostFetch === defaultAdapter.fetch) return null;
98
- return hostFetch;
99
- }
100
- function HoistedStyle({ id, css }) {
101
- return /* @__PURE__ */ jsx("style", { href: id, precedence: "medium", children: css });
102
- }
103
- var YMD_RE = /^\d{4}-\d{2}-\d{2}$/;
104
- function parseYmd(value) {
105
- if (typeof value !== "string" || !YMD_RE.test(value)) return void 0;
106
- const y = Number(value.slice(0, 4));
107
- const m = Number(value.slice(5, 7));
108
- const d = Number(value.slice(8, 10));
109
- const date = new Date(y, m - 1, d, 12, 0, 0, 0);
110
- if (date.getFullYear() !== y || date.getMonth() !== m - 1 || date.getDate() !== d) return void 0;
111
- return date;
112
- }
113
- function formatYmd(date) {
114
- const y = String(date.getFullYear()).padStart(4, "0");
115
- const m = String(date.getMonth() + 1).padStart(2, "0");
116
- const d = String(date.getDate()).padStart(2, "0");
117
- return `${y}-${m}-${d}`;
118
- }
119
- function addDays(date, days) {
120
- const next = new Date(date);
121
- next.setDate(next.getDate() + days);
122
- return next;
123
- }
124
- function addMonths(date, months) {
125
- const next = new Date(date.getFullYear(), date.getMonth() + months, 1, 12, 0, 0, 0);
126
- const lastDay = new Date(next.getFullYear(), next.getMonth() + 1, 0).getDate();
127
- next.setDate(Math.min(date.getDate(), lastDay));
128
- return next;
129
- }
130
- function clampDate(date, min, max) {
131
- if (min && date.getTime() < min.getTime()) return min;
132
- if (max && date.getTime() > max.getTime()) return max;
133
- return date;
134
- }
135
- function monthIndex(date) {
136
- return date.getFullYear() * 12 + date.getMonth();
137
- }
138
- function monthStart(index) {
139
- return new Date(Math.floor(index / 12), index % 12, 1, 12, 0, 0, 0);
140
- }
141
- function isSameDay(a, b) {
142
- return a !== void 0 && b !== void 0 && formatYmd(a) === formatYmd(b);
143
- }
144
- var WEEKDAYS_KO = ["\uC77C", "\uC6D4", "\uD654", "\uC218", "\uBAA9", "\uAE08", "\uD1A0"];
145
- var WEEKS_PER_MONTH = 6;
146
- function buildMonthCells(index, min, max) {
147
- const first = monthStart(index);
148
- const gridStart = addDays(first, -first.getDay());
149
- const weeks = [];
150
- for (let w = 0; w < WEEKS_PER_MONTH; w += 1) {
151
- const row = [];
152
- for (let d = 0; d < 7; d += 1) {
153
- const date = addDays(gridStart, w * 7 + d);
154
- row.push({
155
- date,
156
- ymd: formatYmd(date),
157
- outside: monthIndex(date) !== index,
158
- disabled: min !== void 0 && date.getTime() < min.getTime() || max !== void 0 && date.getTime() > max.getTime()
159
- });
160
- }
161
- weeks.push(row);
162
- }
163
- return weeks;
164
- }
165
- function Calendar({
166
- monthCount,
167
- minDate,
168
- maxDate,
169
- dayState,
170
- onPick,
171
- focusDate,
172
- onFocusDateChange
173
- }) {
174
- const focusIdx = monthIndex(focusDate);
175
- const [viewIdx, setViewIdx] = useState(focusIdx);
176
- const gridRef = useRef(null);
177
- const focusYmd = formatYmd(focusDate);
178
- const visibleIdx = focusIdx < viewIdx ? focusIdx : focusIdx > viewIdx + monthCount - 1 ? focusIdx - monthCount + 1 : viewIdx;
179
- if (visibleIdx !== viewIdx) setViewIdx(visibleIdx);
180
- useLayoutEffect(() => {
181
- gridRef.current?.querySelector('[tabindex="0"]')?.focus();
182
- }, [focusYmd]);
183
- const todayYmd = formatYmd(/* @__PURE__ */ new Date());
184
- const minIdx = minDate ? monthIndex(minDate) : -Infinity;
185
- const maxIdx = maxDate ? monthIndex(maxDate) : Infinity;
186
- const prevDisabled = visibleIdx <= minIdx;
187
- const nextDisabled = visibleIdx + monthCount - 1 >= maxIdx;
188
- const moveFocus = (next) => {
189
- onFocusDateChange(clampDate(next, minDate, maxDate));
190
- };
191
- const handleKeyDown = (event) => {
192
- const deltaDays = event.key === "ArrowLeft" ? -1 : event.key === "ArrowRight" ? 1 : event.key === "ArrowUp" ? -7 : event.key === "ArrowDown" ? 7 : 0;
193
- if (deltaDays !== 0) {
194
- event.preventDefault();
195
- moveFocus(addDays(focusDate, deltaDays));
196
- return;
197
- }
198
- if (event.key === "Home" || event.key === "End") {
199
- event.preventDefault();
200
- const offset = event.key === "Home" ? -focusDate.getDay() : 6 - focusDate.getDay();
201
- moveFocus(addDays(focusDate, offset));
202
- return;
203
- }
204
- if (event.key === "PageUp" || event.key === "PageDown") {
205
- event.preventDefault();
206
- moveFocus(addMonths(focusDate, event.key === "PageUp" ? -1 : 1));
207
- }
208
- };
209
- return /* @__PURE__ */ jsx("div", { className: "wp-dp", children: /* @__PURE__ */ jsxs("div", { className: "wp-dp__months", ref: gridRef, onKeyDown: handleKeyDown, children: [
210
- /* @__PURE__ */ jsxs("div", { className: "wp-dp__nav", children: [
211
- /* @__PURE__ */ jsx(
212
- "button",
213
- {
214
- type: "button",
215
- className: "wp-dp__navbtn",
216
- "aria-label": "\uC774\uC804 \uB2EC",
217
- "aria-disabled": prevDisabled || void 0,
218
- disabled: prevDisabled,
219
- onClick: () => setViewIdx(visibleIdx - 1),
220
- children: /* @__PURE__ */ jsx(Icon, { name: "chevron-left", size: 16 })
221
- }
222
- ),
223
- /* @__PURE__ */ jsx(
224
- "button",
225
- {
226
- type: "button",
227
- className: "wp-dp__navbtn",
228
- "aria-label": "\uB2E4\uC74C \uB2EC",
229
- "aria-disabled": nextDisabled || void 0,
230
- disabled: nextDisabled,
231
- onClick: () => setViewIdx(visibleIdx + 1),
232
- children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 16 })
233
- }
234
- )
235
- ] }),
236
- Array.from({ length: monthCount }, (_, offset) => {
237
- const idx = visibleIdx + offset;
238
- const first = monthStart(idx);
239
- const weeks = buildMonthCells(idx, minDate, maxDate);
240
- const caption = `${first.getFullYear()}\uB144 ${first.getMonth() + 1}\uC6D4`;
241
- return /* @__PURE__ */ jsxs("div", { className: "wp-dp__month", children: [
242
- /* @__PURE__ */ jsx("div", { className: "wp-dp__caption", children: /* @__PURE__ */ jsx("span", { className: "wp-dp__caption-label", children: caption }) }),
243
- /* @__PURE__ */ jsxs("table", { className: "wp-dp__grid", role: "grid", "aria-label": caption, children: [
244
- /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { className: "wp-dp__weekdays", children: WEEKDAYS_KO.map((name) => /* @__PURE__ */ jsx("th", { scope: "col", className: "wp-dp__weekday", abbr: name, children: name }, name)) }) }),
245
- /* @__PURE__ */ jsx("tbody", { className: "wp-dp__weeks", children: weeks.map((week, w) => /* @__PURE__ */ jsx("tr", { className: "wp-dp__week", children: week.map((cell) => {
246
- const state = cell.disabled ? {} : dayState(cell.date);
247
- const classes = ["wp-dp__day"];
248
- if (cell.outside) classes.push("wp-dp__day--outside");
249
- if (cell.disabled) classes.push("wp-dp__day--disabled");
250
- if (cell.ymd === todayYmd) classes.push("wp-dp__day--today");
251
- if (state.selected) classes.push("wp-dp__day--selected");
252
- if (state.rangeStart) classes.push("wp-dp__day--range-start");
253
- if (state.rangeMiddle) classes.push("wp-dp__day--range-middle");
254
- if (state.rangeEnd) classes.push("wp-dp__day--range-end");
255
- return /* @__PURE__ */ jsx("td", { className: classes.join(" "), children: /* @__PURE__ */ jsx(
256
- "button",
257
- {
258
- type: "button",
259
- className: "wp-dp__day-btn",
260
- "data-ymd": cell.ymd,
261
- tabIndex: cell.ymd === focusYmd && !cell.outside ? 0 : -1,
262
- disabled: cell.disabled,
263
- "aria-selected": state.selected || state.rangeStart || state.rangeEnd || void 0,
264
- "aria-label": cell.ymd,
265
- onClick: () => {
266
- onFocusDateChange(cell.date);
267
- onPick(cell.date);
268
- },
269
- children: cell.date.getDate()
270
- }
271
- ) }, cell.ymd);
272
- }) }, w)) })
273
- ] })
274
- ] }, idx);
275
- })
276
- ] }) });
277
- }
278
- function useDismiss(open, hostRef, onDismiss) {
279
- useEffect(() => {
280
- if (!open) return;
281
- const handlePointerDown = (event) => {
282
- if (event.target instanceof Node && hostRef.current?.contains(event.target)) return;
283
- onDismiss("outside");
284
- };
285
- document.addEventListener("pointerdown", handlePointerDown);
286
- return () => {
287
- document.removeEventListener("pointerdown", handlePointerDown);
288
- };
289
- }, [open, hostRef, onDismiss]);
290
- useOverlayLayer(open, () => onDismiss("escape"), hostRef);
291
- }
292
- function triggerClassName(size, invalid) {
293
- const classes = ["wp-input", "wp-dp-trigger"];
294
- if (size !== "md") classes.push(`wp-input--${size}`);
295
- if (invalid) classes.push("wp-input--invalid");
296
- return classes.join(" ");
297
- }
298
- function DatePickerImpl({
299
- value,
300
- onChange,
301
- min,
302
- max,
303
- placeholder,
304
- invalid = false,
305
- disabled = false,
306
- size = "md"
307
- }) {
308
- const [open, setOpen] = useState(false);
309
- const [innerValue, setInnerValue] = useState("");
310
- const hostRef = useRef(null);
311
- const triggerRef = useRef(null);
312
- const isControlled = value !== void 0;
313
- const currentValue = isControlled ? value : innerValue;
314
- const selectedDate = useMemo(() => parseYmd(currentValue), [currentValue]);
315
- const minDate = useMemo(() => parseYmd(min), [min]);
316
- const maxDate = useMemo(() => parseYmd(max), [max]);
317
- const [focusDate, setFocusDate] = useState(() => selectedDate ?? clampDate(/* @__PURE__ */ new Date(), minDate, maxDate));
318
- const dismiss = useCallback((reason) => {
319
- setOpen(false);
320
- if (reason === "escape") triggerRef.current?.focus();
321
- }, []);
322
- useDismiss(open, hostRef, dismiss);
323
- const openCalendar = () => {
324
- setFocusDate(selectedDate ?? clampDate(/* @__PURE__ */ new Date(), minDate, maxDate));
325
- setOpen(true);
326
- };
327
- const isInvalid = Boolean(invalid);
328
- return /* @__PURE__ */ jsxs("div", { ref: hostRef, className: "wp-dp-host", children: [
329
- /* @__PURE__ */ jsx(HoistedStyle, { id: "wp-datepicker", css: DP_CSS }),
330
- /* @__PURE__ */ jsxs(
331
- "button",
332
- {
333
- ref: triggerRef,
334
- type: "button",
335
- className: triggerClassName(size, isInvalid),
336
- "aria-invalid": isInvalid || void 0,
337
- "aria-haspopup": "dialog",
338
- "aria-expanded": open,
339
- disabled,
340
- onClick: () => open ? setOpen(false) : openCalendar(),
341
- children: [
342
- /* @__PURE__ */ jsx("span", { className: "wp-dp-trigger__icon", children: /* @__PURE__ */ jsx(Icon, { name: "calendar", size: size === "lg" ? 16 : 15 }) }),
343
- currentValue ? /* @__PURE__ */ jsx("span", { className: "wp-dp-trigger__value", children: selectedDate ? formatYmd(selectedDate) : currentValue }) : /* @__PURE__ */ jsx("span", { className: "wp-dp-trigger__value wp-dp-trigger__value--placeholder", children: placeholder ?? "\uB0A0\uC9DC \uC120\uD0DD" })
344
- ]
345
- }
346
- ),
347
- open ? /* @__PURE__ */ jsx("div", { className: "wp-dp-pop", role: "dialog", "aria-label": "\uB0A0\uC9DC \uC120\uD0DD \uB2EC\uB825", children: /* @__PURE__ */ jsx("div", { className: "wp-dp-pop__body", children: /* @__PURE__ */ jsx(
348
- Calendar,
349
- {
350
- monthCount: 1,
351
- minDate,
352
- maxDate,
353
- focusDate,
354
- onFocusDateChange: setFocusDate,
355
- dayState: (date) => ({ selected: isSameDay(date, selectedDate) }),
356
- onPick: (date) => {
357
- const next = formatYmd(date);
358
- if (!isControlled) setInnerValue(next);
359
- onChange?.(next);
360
- setOpen(false);
361
- triggerRef.current?.focus();
362
- }
363
- }
364
- ) }) }) : null
365
- ] });
366
- }
367
- function DateRangePickerImpl({
368
- value,
369
- onChange,
370
- min,
371
- max,
372
- invalid = false,
373
- disabled = false
374
- }) {
375
- const [open, setOpen] = useState(false);
376
- const [innerRange, setInnerRange] = useState({});
377
- const hostRef = useRef(null);
378
- const triggerRef = useRef(null);
379
- const isControlled = value !== void 0;
380
- const currentRange = (isControlled ? value : innerRange) ?? {};
381
- const fromDate = useMemo(() => parseYmd(currentRange.from), [currentRange.from]);
382
- const toDate = useMemo(() => parseYmd(currentRange.to), [currentRange.to]);
383
- const minDate = useMemo(() => parseYmd(min), [min]);
384
- const maxDate = useMemo(() => parseYmd(max), [max]);
385
- const [focusDate, setFocusDate] = useState(() => fromDate ?? clampDate(/* @__PURE__ */ new Date(), minDate, maxDate));
386
- const dismiss = useCallback((reason) => {
387
- setOpen(false);
388
- if (reason === "escape") triggerRef.current?.focus();
389
- }, []);
390
- useDismiss(open, hostRef, dismiss);
391
- const hasValue = Boolean(currentRange.from || currentRange.to);
392
- const label = hasValue ? `${currentRange.from ?? ""} ~ ${currentRange.to ?? ""}` : "\uAE30\uAC04 \uC120\uD0DD";
393
- const isInvalid = Boolean(invalid);
394
- const openCalendar = () => {
395
- setFocusDate(fromDate ?? toDate ?? clampDate(/* @__PURE__ */ new Date(), minDate, maxDate));
396
- setOpen(true);
397
- };
398
- const commit = (next) => {
399
- if (!isControlled) setInnerRange(next);
400
- onChange?.(next);
401
- };
402
- const pick = (date) => {
403
- const ymd = formatYmd(date);
404
- const startingOver = fromDate === void 0 || toDate !== void 0 || date.getTime() < fromDate.getTime();
405
- if (startingOver) {
406
- commit({ from: ymd, to: void 0 });
407
- return;
408
- }
409
- commit({ from: currentRange.from, to: ymd });
410
- setOpen(false);
411
- triggerRef.current?.focus();
412
- };
413
- return /* @__PURE__ */ jsxs("div", { ref: hostRef, className: "wp-dp-host", children: [
414
- /* @__PURE__ */ jsx(HoistedStyle, { id: "wp-datepicker", css: DP_CSS }),
415
- /* @__PURE__ */ jsxs(
416
- "button",
417
- {
418
- ref: triggerRef,
419
- type: "button",
420
- className: triggerClassName("md", isInvalid),
421
- "aria-invalid": isInvalid || void 0,
422
- "aria-haspopup": "dialog",
423
- "aria-expanded": open,
424
- disabled,
425
- onClick: () => open ? setOpen(false) : openCalendar(),
426
- children: [
427
- /* @__PURE__ */ jsx("span", { className: "wp-dp-trigger__icon", children: /* @__PURE__ */ jsx(Icon, { name: "calendar", size: 15 }) }),
428
- /* @__PURE__ */ jsx("span", { className: `wp-dp-trigger__value${hasValue ? "" : " wp-dp-trigger__value--placeholder"}`, children: label })
429
- ]
430
- }
431
- ),
432
- open ? /* @__PURE__ */ jsx("div", { className: "wp-dp-pop wp-dp-pop--wide", role: "dialog", "aria-label": "\uAE30\uAC04 \uC120\uD0DD \uB2EC\uB825", children: /* @__PURE__ */ jsx("div", { className: "wp-dp-pop__body", children: /* @__PURE__ */ jsx(
433
- Calendar,
434
- {
435
- monthCount: 2,
436
- minDate,
437
- maxDate,
438
- focusDate,
439
- onFocusDateChange: setFocusDate,
440
- dayState: (date) => {
441
- const t = date.getTime();
442
- const start = fromDate?.getTime();
443
- const end = toDate?.getTime();
444
- if (start !== void 0 && end !== void 0 && t > start && t < end) return { rangeMiddle: true };
445
- return {
446
- rangeStart: start !== void 0 && t === start && end !== void 0,
447
- rangeEnd: end !== void 0 && t === end,
448
- // 아직 시작만 고른 상태는 단일 선택처럼 보인다
449
- selected: start !== void 0 && t === start && end === void 0 || void 0
450
- };
451
- },
452
- onPick: pick
453
- }
454
- ) }) }) : null
455
- ] });
456
- }
457
- var DP_CSS = `
458
- .wp-dp-host{position:relative}
459
- .wp-dp-pop{position:absolute;top:calc(100% + var(--wp-space-2));left:0;min-width:100%;width:max-content;background:var(--wp-surface-card);border:1px solid var(--wp-border-subtle);border-radius:var(--wp-radius-lg);box-shadow:var(--wp-shadow-lg);z-index:300}
460
- .wp-dp-pop--wide{max-width:min(640px,90vw)}
461
- .wp-dp-pop__body{padding:var(--wp-space-4);max-height:60vh;overflow:auto}
462
- .wp-dp-trigger{display:inline-flex;align-items:center;gap:var(--wp-space-2);text-align:left;cursor:pointer}
463
- .wp-dp-trigger:disabled{cursor:not-allowed}
464
- .wp-dp-trigger__icon{flex:none;display:inline-flex;color:var(--wp-text-muted)}
465
- .wp-dp-trigger:disabled .wp-dp-trigger__icon{color:var(--wp-text-disabled)}
466
- .wp-dp-trigger__value{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--wp-font-mono);font-size:12.5px;letter-spacing:-0.01em}
467
- .wp-dp-trigger__value--placeholder{font-family:inherit;font-size:13px;letter-spacing:normal;color:var(--wp-text-subtle)}
468
- .wp-dp{font-family:inherit;font-size:13px;color:var(--wp-text-default)}
469
- .wp-dp__months{position:relative;display:flex;flex-wrap:wrap;gap:var(--wp-space-5)}
470
- .wp-dp__nav{position:absolute;top:0;right:0;display:flex;gap:var(--wp-space-1);z-index:1}
471
- .wp-dp__navbtn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;background:transparent;border-radius:var(--wp-radius-sm);color:var(--wp-text-muted);cursor:pointer;transition:background 0.12s,color 0.12s}
472
- .wp-dp__navbtn:hover:not(:disabled){background:var(--wp-surface-hover);color:var(--wp-text-strong)}
473
- .wp-dp__navbtn:focus-visible{outline:2px solid var(--wp-border-focus);outline-offset:1px}
474
- .wp-dp__navbtn:disabled{color:var(--wp-text-disabled);cursor:default;background:transparent}
475
- .wp-dp__caption{display:flex;align-items:center;height:28px;margin-bottom:var(--wp-space-2);padding-left:var(--wp-space-1)}
476
- .wp-dp__caption-label{font-size:13px;font-weight:600;color:var(--wp-text-strong)}
477
- .wp-dp__grid{border-collapse:collapse}
478
- .wp-dp__weekday{width:32px;height:28px;padding:0;font-size:12px;font-weight:500;color:var(--wp-text-muted);text-align:center}
479
- .wp-dp__weekday:first-child{color:var(--wp-text-danger)}
480
- .wp-dp__day{padding:0;text-align:center}
481
- .wp-dp__day-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:30px;padding:0;border:none;background:transparent;border-radius:var(--wp-radius-sm);font:inherit;font-variant-numeric:tabular-nums;color:inherit;cursor:pointer;transition:background 0.12s,color 0.12s}
482
- .wp-dp__day:not(.wp-dp__day--selected):not(.wp-dp__day--disabled) .wp-dp__day-btn:hover{background:var(--wp-surface-hover)}
483
- .wp-dp__day-btn:focus-visible{outline:2px solid var(--wp-border-focus);outline-offset:-1px}
484
- .wp-dp__day--today .wp-dp__day-btn{box-shadow:inset 0 0 0 1px var(--wp-border-focus)}
485
- .wp-dp__day--outside{color:var(--wp-text-subtle)}
486
- .wp-dp__day--disabled{color:var(--wp-text-disabled)}
487
- .wp-dp__day--disabled .wp-dp__day-btn{cursor:default}
488
- .wp-dp__day--selected .wp-dp__day-btn{background:var(--wp-action-primary-bg);color:var(--wp-action-primary-fg);font-weight:500}
489
- .wp-dp__day--selected.wp-dp__day--today .wp-dp__day-btn{box-shadow:none}
490
- .wp-dp__day--range-middle .wp-dp__day-btn{background:var(--wp-surface-selected);color:var(--wp-text-default);border-radius:0;font-weight:400}
491
- .wp-dp__day--range-start .wp-dp__day-btn,.wp-dp__day--range-end .wp-dp__day-btn{background:var(--wp-action-primary-bg);color:var(--wp-action-primary-fg);font-weight:500}
492
- .wp-dp__day--range-start.wp-dp__day--today .wp-dp__day-btn,.wp-dp__day--range-end.wp-dp__day--today .wp-dp__day-btn{box-shadow:none}
493
- `;
494
- var DatePicker = boxed(DatePickerImpl, "DatePicker");
495
- var DateRangePicker = boxed(DateRangePickerImpl, "DateRangePicker");
496
-
497
- export { DEV, DatePicker, DateRangePicker, HoistedStyle, SduiAdapterContext, assetResolverOf, defaultAdapter, hostFetchOf, isSafeNavigationTarget, resolveAdapter, useSduiAdapter, useSduiAssetResolver, useSduiSandbox };