@evinvest/uikit 0.16.0 → 0.17.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/README.md +11 -7
- package/dist/index.d.ts +45 -14
- package/dist/index.js +173 -56
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -170,8 +170,8 @@ measuring needs host-only `web-sys`). Known gaps:
|
|
|
170
170
|
- **Rust overlays** (dialog, popover, dropdown, select, menus, tooltip, …) render
|
|
171
171
|
inline with `position:fixed` + a backdrop and CSS-only placement — no portal,
|
|
172
172
|
no viewport-measured floating, native focus order (no trap). TS overlays use a
|
|
173
|
-
real `Portal`, single-flip `useFloating
|
|
174
|
-
`useFocusScope`.
|
|
173
|
+
real `Portal`, single-flip `useFloating` (absolute in the document, so it
|
|
174
|
+
scrolls with the page natively), `useDismissableLayer`, and `useFocusScope`.
|
|
175
175
|
- **chart:** the recharts plotting engine is not bundled. `ChartContainer` is a
|
|
176
176
|
themed SVG host (emits `--color-*` from its config); `ChartTooltipContent` /
|
|
177
177
|
`ChartLegendContent` are presentational and take explicit items. Draw series
|
|
@@ -182,17 +182,21 @@ measuring needs host-only `web-sys`). Known gaps:
|
|
|
182
182
|
submit's default — inputs, validation and the order itself are the
|
|
183
183
|
consumer's. The open-orders pane reuses `Table` and `Tabs`.
|
|
184
184
|
- **calendar:** single month, single-date selection (no range/multi-month, no
|
|
185
|
-
dropdown captions).
|
|
186
|
-
|
|
187
|
-
|
|
185
|
+
dropdown captions). The grid is always six fixed weeks of 36px cells, so its
|
|
186
|
+
size never changes with the month or the locale's weekday labels, and it
|
|
187
|
+
paints no background of its own (the host does). `min`/`max` bound the grid
|
|
188
|
+
at day granularity (days outside render `disabled` + `data-disabled="true"`);
|
|
189
|
+
`disabled` freezes the whole grid and the nav the same way; the nav buttons
|
|
190
|
+
take label overrides. TS-only `locale` renders the caption and weekday headers through
|
|
188
191
|
`Intl` (Monday-first); Rust has no `Intl`, so its captions stay English. Rust
|
|
189
192
|
does manual date math; TS uses the built-in `Date`.
|
|
190
193
|
- **date-time-picker:** the kit's own bricks only — an outline trigger, a
|
|
191
194
|
`Popover` with the `Calendar` and two numeric 24-hour hours/minutes fields (no
|
|
192
195
|
native `datetime-local` / `time` input, so the browser's locale popup never
|
|
193
196
|
appears). Its ARIA and button strings are `labels` overrides with English
|
|
194
|
-
defaults — the nav buttons, the hours/minutes `aria-label`s, the clear button
|
|
195
|
-
|
|
197
|
+
defaults — the nav buttons, the hours/minutes `aria-label`s, the clear button,
|
|
198
|
+
the close button (`labels.close`, which keeps the value) and the popover's own
|
|
199
|
+
accessible name (`labels.dialog`). TS formats the trigger label through `Intl` when `locale` is set,
|
|
196
200
|
else `YYYY-MM-DD HH:MM`; Rust has no `Intl`: the ISO-like label or the
|
|
197
201
|
`format` callback, English month/weekday captions. The hidden form value is
|
|
198
202
|
unix seconds in TS and `YYYY-MM-DDTHH:MM` in Rust (no zone there). The Rust
|
package/dist/index.d.ts
CHANGED
|
@@ -80,11 +80,28 @@ interface FloatingResult {
|
|
|
80
80
|
align: Align;
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
|
-
* Positions a floating element against an anchor with `position:
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
83
|
+
* Positions a floating element against an anchor with `position: absolute` in
|
|
84
|
+
* the coordinate space of its containing block (the `Portal` puts it in
|
|
85
|
+
* `document.body`, so normally document coordinates) — the dep-light stand-in
|
|
86
|
+
* for `@radix-ui/react-popper` / floating-ui. Supports a preferred
|
|
87
|
+
* `side`/`align`, an `offset`, and a single collision flip onto the opposite
|
|
88
|
+
* side when the preferred side overflows the viewport.
|
|
89
|
+
*
|
|
90
|
+
* Two update modes:
|
|
91
|
+
* - `place()` — full pass (flip + clamp into the viewport) on open, on window
|
|
92
|
+
* `resize`, and whenever the anchor or the floating element changes size.
|
|
93
|
+
* - `sync()` — re-derives the coordinates from the anchor with the side and
|
|
94
|
+
* the clamp shift already chosen; runs on every `scroll` (captured on
|
|
95
|
+
* `window`, so nested scroll containers count too).
|
|
96
|
+
*
|
|
97
|
+
* Because the element is absolutely positioned in the document, a document
|
|
98
|
+
* scroll moves it natively with the page — `sync()` then computes the same
|
|
99
|
+
* numbers and is a no-op — so the overlay never lags behind the compositor.
|
|
100
|
+
* Only a nested scroll container changes the coordinates, and there a frame
|
|
101
|
+
* of lag is acceptable. The side is never revisited on scroll: no jumping.
|
|
102
|
+
* A page that scrolls `body` instead of the document (`html { overflow:
|
|
103
|
+
* hidden } body { overflow: auto }`) is such a nested scroller: correct, but
|
|
104
|
+
* with the frame of lag the `fixed` strategy had.
|
|
88
105
|
*
|
|
89
106
|
* Rust's overlays use CSS-only placement (`data-side`) and do not measure; see
|
|
90
107
|
* the README "Limitations".
|
|
@@ -109,11 +126,22 @@ declare function useFloating(opts: {
|
|
|
109
126
|
declare function useFocusScope(enabled: boolean): React.RefObject<HTMLDivElement | null>;
|
|
110
127
|
|
|
111
128
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
129
|
+
* Keeps an overlay mounted through its exit animation. Enter animations
|
|
130
|
+
* (`data-[state=open]:animate-in`) play on mount; once `present` turns false
|
|
131
|
+
* the consumer flips the node to `data-state="closed"` in the same render and
|
|
132
|
+
* the node stays until its exit animation ends (or the fallback timer fires).
|
|
133
|
+
* Re-opening mid-exit just flips the state back; the node is never remounted.
|
|
134
|
+
*
|
|
135
|
+
* The exit was dropped once (5728b40) because closing flickered: tw-animate's
|
|
136
|
+
* `animate-out` runs with `animation-fill-mode: none`, so after `animationend`
|
|
137
|
+
* the node snaps back to full opacity/scale for the frame React needs to
|
|
138
|
+
* process an async unmount. Hence `flushSync` inside the native listener —
|
|
139
|
+
* the unmount commits before the browser paints that frame (Radix Presence
|
|
140
|
+
* does the same). With no animation on the node (jsdom, overlays without an
|
|
141
|
+
* exit class) unmount is immediate, as before. The Rust mirror still does not
|
|
142
|
+
* defer unmount.
|
|
143
|
+
*
|
|
144
|
+
* Pass `ref` to the animated node — the one carrying `data-state`.
|
|
117
145
|
*/
|
|
118
146
|
declare function usePresence(present: boolean): {
|
|
119
147
|
isPresent: boolean;
|
|
@@ -1444,6 +1472,8 @@ interface DateTimePickerLabels {
|
|
|
1444
1472
|
clear?: string;
|
|
1445
1473
|
/** `aria-label` of the popover dialog; "Choose date and time". */
|
|
1446
1474
|
dialog?: string;
|
|
1475
|
+
/** `aria-label` of the close button; "Close". */
|
|
1476
|
+
close?: string;
|
|
1447
1477
|
}
|
|
1448
1478
|
interface DateTimePickerProps extends React.AriaAttributes, Pick<React.ComponentProps<"button">, "onFocus" | "onBlur"> {
|
|
1449
1479
|
/** Controlled value; `null` = empty. Local-zone `Date` (seconds/ms are zeroed on every change). */
|
|
@@ -1489,10 +1519,11 @@ interface DateTimePickerProps extends React.AriaAttributes, Pick<React.Component
|
|
|
1489
1519
|
* `datetime-local`, so the browser's locale popup never appears.
|
|
1490
1520
|
*
|
|
1491
1521
|
* Every edit reports through `onChange`; the popover stays open after a day
|
|
1492
|
-
* click (the operator still sets the time) and closes on clear
|
|
1493
|
-
*
|
|
1494
|
-
*
|
|
1495
|
-
* and `onBlur` land on the
|
|
1522
|
+
* click (the operator still sets the time) and closes on clear or on the close
|
|
1523
|
+
* button (which keeps the value). Opening moves focus into the hours field;
|
|
1524
|
+
* closing hands it back to the trigger unless the operator already focused
|
|
1525
|
+
* something else. Any other `aria-*` prop, `onFocus` and `onBlur` land on the
|
|
1526
|
+
* trigger.
|
|
1496
1527
|
*/
|
|
1497
1528
|
declare function DateTimePicker({ value: valueProp, defaultValue, onChange, min, max, locale, format, placeholder, labels, disabled, name, today, open, defaultOpen, onOpenChange, align, className, id, ...rest }: DateTimePickerProps): React.JSX.Element;
|
|
1498
1529
|
|
package/dist/index.js
CHANGED
|
@@ -109,37 +109,46 @@ function useDismissableLayer(opts) {
|
|
|
109
109
|
|
|
110
110
|
// src/primitives/use-floating.ts
|
|
111
111
|
import * as React5 from "react";
|
|
112
|
+
var ABSOLUTE = Object.freeze({ position: "absolute", top: 0, left: 0 });
|
|
113
|
+
var POSITIONED = /* @__PURE__ */ new Set(["relative", "absolute", "fixed", "sticky"]);
|
|
114
|
+
function toContainingBlock(floating, x, y) {
|
|
115
|
+
const parent = floating.offsetParent;
|
|
116
|
+
const doc = floating.ownerDocument;
|
|
117
|
+
const root = parent === doc.body || parent === doc.documentElement || parent === null;
|
|
118
|
+
const positioned = parent instanceof HTMLElement && (!root || POSITIONED.has(doc.defaultView?.getComputedStyle(parent).position ?? ""));
|
|
119
|
+
if (!positioned) {
|
|
120
|
+
const win = doc.defaultView;
|
|
121
|
+
return { x: x + (win?.scrollX ?? 0), y: y + (win?.scrollY ?? 0), root: true };
|
|
122
|
+
}
|
|
123
|
+
const p = parent.getBoundingClientRect();
|
|
124
|
+
return {
|
|
125
|
+
x: x - p.left - parent.clientLeft + parent.scrollLeft,
|
|
126
|
+
y: y - p.top - parent.clientTop + parent.scrollTop,
|
|
127
|
+
root: false
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function layoutSize(el) {
|
|
131
|
+
return { width: el.offsetWidth, height: el.offsetHeight };
|
|
132
|
+
}
|
|
133
|
+
function viewport() {
|
|
134
|
+
const el = document.documentElement;
|
|
135
|
+
return {
|
|
136
|
+
vw: el.clientWidth || window.innerWidth,
|
|
137
|
+
vh: el.clientHeight || window.innerHeight
|
|
138
|
+
};
|
|
139
|
+
}
|
|
112
140
|
function useFloating(opts) {
|
|
113
141
|
const { anchorRef, open, side = "bottom", align = "center", offset = 4 } = opts;
|
|
114
142
|
const floatingRef = React5.useRef(null);
|
|
115
|
-
const [
|
|
116
|
-
|
|
117
|
-
top: 0,
|
|
118
|
-
left: 0
|
|
119
|
-
});
|
|
120
|
-
const [resolved, setResolved] = React5.useState({
|
|
143
|
+
const [placedSide, setPlacedSide] = React5.useState(side);
|
|
144
|
+
const placement = React5.useRef({
|
|
121
145
|
side,
|
|
122
|
-
|
|
146
|
+
shiftX: 0,
|
|
147
|
+
shiftY: 0
|
|
123
148
|
});
|
|
124
149
|
React5.useLayoutEffect(() => {
|
|
125
150
|
if (!open) return;
|
|
126
|
-
function
|
|
127
|
-
const anchor = anchorRef.current;
|
|
128
|
-
const floating = floatingRef.current;
|
|
129
|
-
if (!anchor || !floating) return;
|
|
130
|
-
const a = anchor.getBoundingClientRect();
|
|
131
|
-
const f = floating.getBoundingClientRect();
|
|
132
|
-
const vw = window.innerWidth;
|
|
133
|
-
const vh = window.innerHeight;
|
|
134
|
-
let placed = side;
|
|
135
|
-
if (side === "bottom" && a.bottom + offset + f.height > vh && a.top - offset - f.height > 0)
|
|
136
|
-
placed = "top";
|
|
137
|
-
else if (side === "top" && a.top - offset - f.height < 0 && a.bottom + offset + f.height < vh)
|
|
138
|
-
placed = "bottom";
|
|
139
|
-
else if (side === "right" && a.right + offset + f.width > vw && a.left - offset - f.width > 0)
|
|
140
|
-
placed = "left";
|
|
141
|
-
else if (side === "left" && a.left - offset - f.width < 0 && a.right + offset + f.width < vw)
|
|
142
|
-
placed = "right";
|
|
151
|
+
function ideal(a, f, placed) {
|
|
143
152
|
let top = 0;
|
|
144
153
|
let left = 0;
|
|
145
154
|
const vertical = placed === "top" || placed === "bottom";
|
|
@@ -156,29 +165,71 @@ function useFloating(opts) {
|
|
|
156
165
|
else if (align === "end") top = a.bottom - f.height;
|
|
157
166
|
else top = a.top + a.height / 2 - f.height / 2;
|
|
158
167
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
168
|
+
return { top, left };
|
|
169
|
+
}
|
|
170
|
+
function write(floating, f, top, left, contain) {
|
|
171
|
+
const p = toContainingBlock(floating, left, top);
|
|
172
|
+
let { x, y } = p;
|
|
173
|
+
if (contain && p.root) {
|
|
174
|
+
const icbWidth = floating.ownerDocument.documentElement.clientWidth || window.innerWidth;
|
|
175
|
+
x = Math.max(0, Math.min(x, icbWidth - f.width));
|
|
176
|
+
y = Math.max(0, y);
|
|
177
|
+
}
|
|
178
|
+
floating.style.translate = `${Math.round(x)}px ${Math.round(y)}px`;
|
|
179
|
+
}
|
|
180
|
+
function place() {
|
|
181
|
+
const anchor = anchorRef.current;
|
|
182
|
+
const floating = floatingRef.current;
|
|
183
|
+
if (!anchor || !floating) return;
|
|
184
|
+
const a = anchor.getBoundingClientRect();
|
|
185
|
+
const f = layoutSize(floating);
|
|
186
|
+
const { vw, vh } = viewport();
|
|
187
|
+
let placed = side;
|
|
188
|
+
if (side === "bottom" && a.bottom + offset + f.height > vh && a.top - offset - f.height > 0)
|
|
189
|
+
placed = "top";
|
|
190
|
+
else if (side === "top" && a.top - offset - f.height < 0 && a.bottom + offset + f.height < vh)
|
|
191
|
+
placed = "bottom";
|
|
192
|
+
else if (side === "right" && a.right + offset + f.width > vw && a.left - offset - f.width > 0)
|
|
193
|
+
placed = "left";
|
|
194
|
+
else if (side === "left" && a.left - offset - f.width < 0 && a.right + offset + f.width < vw)
|
|
195
|
+
placed = "right";
|
|
196
|
+
const { top, left } = ideal(a, f, placed);
|
|
197
|
+
const clampedLeft = Math.max(offset, Math.min(left, vw - f.width - offset));
|
|
198
|
+
const clampedTop = Math.max(offset, Math.min(top, vh - f.height - offset));
|
|
199
|
+
placement.current = {
|
|
200
|
+
side: placed,
|
|
201
|
+
shiftX: clampedLeft - left,
|
|
202
|
+
shiftY: clampedTop - top
|
|
203
|
+
};
|
|
204
|
+
write(floating, f, clampedTop, clampedLeft, false);
|
|
205
|
+
setPlacedSide((prev) => prev === placed ? prev : placed);
|
|
206
|
+
}
|
|
207
|
+
function sync() {
|
|
208
|
+
const anchor = anchorRef.current;
|
|
209
|
+
const floating = floatingRef.current;
|
|
210
|
+
if (!anchor || !floating) return;
|
|
211
|
+
const a = anchor.getBoundingClientRect();
|
|
212
|
+
const f = layoutSize(floating);
|
|
213
|
+
const { side: placed, shiftX, shiftY } = placement.current;
|
|
214
|
+
const { top, left } = ideal(a, f, placed);
|
|
215
|
+
write(floating, f, top + shiftY, left + shiftX, true);
|
|
216
|
+
}
|
|
217
|
+
place();
|
|
218
|
+
window.addEventListener("scroll", sync, true);
|
|
219
|
+
window.addEventListener("resize", place);
|
|
220
|
+
let observer;
|
|
221
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
222
|
+
observer = new ResizeObserver(place);
|
|
223
|
+
if (anchorRef.current) observer.observe(anchorRef.current);
|
|
224
|
+
if (floatingRef.current) observer.observe(floatingRef.current);
|
|
225
|
+
}
|
|
175
226
|
return () => {
|
|
176
|
-
|
|
177
|
-
window.removeEventListener("
|
|
178
|
-
|
|
227
|
+
window.removeEventListener("scroll", sync, true);
|
|
228
|
+
window.removeEventListener("resize", place);
|
|
229
|
+
observer?.disconnect();
|
|
179
230
|
};
|
|
180
231
|
}, [open, side, align, offset, anchorRef]);
|
|
181
|
-
return { floatingRef, style, side:
|
|
232
|
+
return { floatingRef, style: ABSOLUTE, side: placedSide, align };
|
|
182
233
|
}
|
|
183
234
|
|
|
184
235
|
// src/primitives/focus-scope.tsx
|
|
@@ -227,9 +278,44 @@ function useFocusScope(enabled) {
|
|
|
227
278
|
|
|
228
279
|
// src/primitives/presence.ts
|
|
229
280
|
import * as React7 from "react";
|
|
281
|
+
import { flushSync } from "react-dom";
|
|
282
|
+
var EXIT_FALLBACK_MS = 1e3;
|
|
230
283
|
function usePresence(present) {
|
|
231
284
|
const ref = React7.useRef(null);
|
|
232
|
-
|
|
285
|
+
const [mounted, setMounted] = React7.useState(present);
|
|
286
|
+
React7.useLayoutEffect(() => {
|
|
287
|
+
if (present) {
|
|
288
|
+
setMounted(true);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
const node = ref.current;
|
|
292
|
+
if (!node) {
|
|
293
|
+
setMounted(false);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
const name = getComputedStyle(node).animationName;
|
|
297
|
+
if (name === "" || name === "none") {
|
|
298
|
+
setMounted(false);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
const prevPointerEvents = node.style.pointerEvents;
|
|
302
|
+
node.style.pointerEvents = "none";
|
|
303
|
+
const onEnd = (e) => {
|
|
304
|
+
if (e.target !== node) return;
|
|
305
|
+
if (e.animationName && !name.includes(e.animationName)) return;
|
|
306
|
+
flushSync(() => setMounted(false));
|
|
307
|
+
};
|
|
308
|
+
node.addEventListener("animationend", onEnd);
|
|
309
|
+
node.addEventListener("animationcancel", onEnd);
|
|
310
|
+
const timer = setTimeout(() => setMounted(false), EXIT_FALLBACK_MS);
|
|
311
|
+
return () => {
|
|
312
|
+
clearTimeout(timer);
|
|
313
|
+
node.removeEventListener("animationend", onEnd);
|
|
314
|
+
node.removeEventListener("animationcancel", onEnd);
|
|
315
|
+
node.style.pointerEvents = prevPointerEvents;
|
|
316
|
+
};
|
|
317
|
+
}, [present]);
|
|
318
|
+
return { isPresent: present || mounted, ref };
|
|
233
319
|
}
|
|
234
320
|
|
|
235
321
|
// src/primitives/use-roving-focus.ts
|
|
@@ -5197,14 +5283,14 @@ function useItem() {
|
|
|
5197
5283
|
function NavigationMenu({
|
|
5198
5284
|
className,
|
|
5199
5285
|
children,
|
|
5200
|
-
viewport = true,
|
|
5286
|
+
viewport: viewport2 = true,
|
|
5201
5287
|
...props
|
|
5202
5288
|
}) {
|
|
5203
5289
|
return /* @__PURE__ */ jsxs18(
|
|
5204
5290
|
"nav",
|
|
5205
5291
|
{
|
|
5206
5292
|
"data-slot": "navigation-menu",
|
|
5207
|
-
"data-viewport":
|
|
5293
|
+
"data-viewport": viewport2,
|
|
5208
5294
|
role: "navigation",
|
|
5209
5295
|
className: cn(
|
|
5210
5296
|
NAVIGATION_MENU,
|
|
@@ -5213,7 +5299,7 @@ function NavigationMenu({
|
|
|
5213
5299
|
...props,
|
|
5214
5300
|
children: [
|
|
5215
5301
|
children,
|
|
5216
|
-
|
|
5302
|
+
viewport2 && /* @__PURE__ */ jsx48(NavigationMenuViewport, {})
|
|
5217
5303
|
]
|
|
5218
5304
|
}
|
|
5219
5305
|
);
|
|
@@ -5911,7 +5997,7 @@ import { jsx as jsx52, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
|
5911
5997
|
var CLOSE_THRESHOLD = 0.25;
|
|
5912
5998
|
var VELOCITY_THRESHOLD = 0.4;
|
|
5913
5999
|
var DRAG_AFTER_OPEN_MS = 500;
|
|
5914
|
-
var
|
|
6000
|
+
var EXIT_FALLBACK_MS2 = 600;
|
|
5915
6001
|
var DrawerContext = React62.createContext(null);
|
|
5916
6002
|
function useDrawer() {
|
|
5917
6003
|
const ctx = React62.useContext(DrawerContext);
|
|
@@ -6118,7 +6204,7 @@ function DrawerContent({ className, children, ...props }) {
|
|
|
6118
6204
|
}, [open]);
|
|
6119
6205
|
React62.useEffect(() => {
|
|
6120
6206
|
if (!closing) return;
|
|
6121
|
-
const id = setTimeout(() => setPresent(false),
|
|
6207
|
+
const id = setTimeout(() => setPresent(false), EXIT_FALLBACK_MS2);
|
|
6122
6208
|
return () => clearTimeout(id);
|
|
6123
6209
|
}, [closing]);
|
|
6124
6210
|
const drag = useDrawerDrag({
|
|
@@ -6878,17 +6964,17 @@ function ChartLegendContent({
|
|
|
6878
6964
|
import * as React66 from "react";
|
|
6879
6965
|
|
|
6880
6966
|
// src/generated/calendar.ts
|
|
6881
|
-
var CALENDAR_ROOT = "
|
|
6967
|
+
var CALENDAR_ROOT = "p-3 w-fit";
|
|
6882
6968
|
var CALENDAR_NAV_BUTTON = "size-8 p-0 select-none";
|
|
6883
6969
|
var CALENDAR_NAV = "flex items-center justify-between gap-1 w-full px-1";
|
|
6884
6970
|
var CALENDAR_CAPTION = "text-sm font-medium select-none";
|
|
6885
6971
|
var CALENDAR_GRID = "w-full border-collapse mt-4";
|
|
6886
6972
|
var CALENDAR_WEEKDAY_ROW = "flex";
|
|
6887
|
-
var CALENDAR_WEEKDAY = "text-ink-soft rounded-md
|
|
6973
|
+
var CALENDAR_WEEKDAY = "text-ink-soft rounded-md w-9 shrink-0 font-normal text-[0.8rem] select-none";
|
|
6888
6974
|
var CALENDAR_WEEK = "flex w-full mt-2";
|
|
6889
|
-
var CALENDAR_DAY_EMPTY = "relative
|
|
6890
|
-
var CALENDAR_DAY_CELL = "relative
|
|
6891
|
-
var CALENDAR_DAY = "size-auto w-full aspect-square font-normal leading-none";
|
|
6975
|
+
var CALENDAR_DAY_EMPTY = "relative size-9 shrink-0 p-0 select-none";
|
|
6976
|
+
var CALENDAR_DAY_CELL = "relative size-9 shrink-0 p-0 text-center select-none";
|
|
6977
|
+
var CALENDAR_DAY = "size-auto w-full aspect-square font-normal leading-none tabular-nums";
|
|
6892
6978
|
var CALENDAR_DAY_SELECTED = "bg-primary text-on-primary";
|
|
6893
6979
|
var CALENDAR_DAY_TODAY = "bg-hover text-ink rounded-md";
|
|
6894
6980
|
|
|
@@ -6987,7 +7073,7 @@ function Calendar({
|
|
|
6987
7073
|
const cells = [];
|
|
6988
7074
|
for (let i = 0; i < lead; i += 1) cells.push(null);
|
|
6989
7075
|
for (let day = 1; day <= total; day += 1) cells.push(day);
|
|
6990
|
-
while (cells.length
|
|
7076
|
+
while (cells.length < 42) cells.push(null);
|
|
6991
7077
|
const weeks = [];
|
|
6992
7078
|
for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7));
|
|
6993
7079
|
const navClass = buttonVariants({
|
|
@@ -7129,6 +7215,25 @@ function CalendarIcon() {
|
|
|
7129
7215
|
}
|
|
7130
7216
|
);
|
|
7131
7217
|
}
|
|
7218
|
+
function XIcon3() {
|
|
7219
|
+
return /* @__PURE__ */ jsx57(
|
|
7220
|
+
"svg",
|
|
7221
|
+
{
|
|
7222
|
+
className: "size-4",
|
|
7223
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
7224
|
+
width: "24",
|
|
7225
|
+
height: "24",
|
|
7226
|
+
viewBox: "0 0 24 24",
|
|
7227
|
+
fill: "none",
|
|
7228
|
+
stroke: "currentColor",
|
|
7229
|
+
strokeWidth: "2",
|
|
7230
|
+
strokeLinecap: "round",
|
|
7231
|
+
strokeLinejoin: "round",
|
|
7232
|
+
"aria-hidden": true,
|
|
7233
|
+
children: /* @__PURE__ */ jsx57("path", { d: "M18 6 6 18M6 6l12 12" })
|
|
7234
|
+
}
|
|
7235
|
+
);
|
|
7236
|
+
}
|
|
7132
7237
|
var pad = (n) => String(n).padStart(2, "0");
|
|
7133
7238
|
function atMinute(d) {
|
|
7134
7239
|
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes());
|
|
@@ -7336,6 +7441,18 @@ function DateTimePicker({
|
|
|
7336
7441
|
onClick: onClear,
|
|
7337
7442
|
children: labels.clear ?? "Clear"
|
|
7338
7443
|
}
|
|
7444
|
+
),
|
|
7445
|
+
/* @__PURE__ */ jsx57(
|
|
7446
|
+
"button",
|
|
7447
|
+
{
|
|
7448
|
+
type: "button",
|
|
7449
|
+
className: buttonVariants({ variant: "ghost", size: "sm", icon: true }),
|
|
7450
|
+
"data-slot": "date-time-picker-close",
|
|
7451
|
+
"aria-label": labels.close ?? "Close",
|
|
7452
|
+
disabled,
|
|
7453
|
+
onClick: () => setOpen(false),
|
|
7454
|
+
children: /* @__PURE__ */ jsx57(XIcon3, {})
|
|
7455
|
+
}
|
|
7339
7456
|
)
|
|
7340
7457
|
] })
|
|
7341
7458
|
]
|