@apotech-os/ui-sdk 2.5.0 → 2.6.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/dist/index.cjs +273 -121
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -2
- package/dist/index.d.ts +18 -2
- package/dist/index.js +275 -124
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1100,8 +1100,15 @@ function DataTable({
|
|
|
1100
1100
|
TableRow,
|
|
1101
1101
|
{
|
|
1102
1102
|
"data-state": selected.has(row.id) ? "selected" : void 0,
|
|
1103
|
-
className: onRowClick ? "cursor-pointer" : "hover:bg-transparent",
|
|
1103
|
+
className: onRowClick ? "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset" : "hover:bg-transparent",
|
|
1104
|
+
tabIndex: onRowClick ? 0 : void 0,
|
|
1104
1105
|
onClick: onRowClick ? () => onRowClick(row.original) : void 0,
|
|
1106
|
+
onKeyDown: onRowClick ? (event) => {
|
|
1107
|
+
if (event.target !== event.currentTarget) return;
|
|
1108
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
1109
|
+
event.preventDefault();
|
|
1110
|
+
onRowClick(row.original);
|
|
1111
|
+
} : void 0,
|
|
1105
1112
|
children: [
|
|
1106
1113
|
selectable && /* @__PURE__ */ jsxRuntime.jsx(TableCell, { onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1107
1114
|
Checkbox,
|
|
@@ -1375,20 +1382,20 @@ var PERIOD_PRESETS = [
|
|
|
1375
1382
|
{ key: "all", label: "Tout l'historique" }
|
|
1376
1383
|
];
|
|
1377
1384
|
var COMPARE_LABELS = {
|
|
1378
|
-
none: "
|
|
1385
|
+
none: "Ne pas comparer",
|
|
1379
1386
|
previous_period: "P\xE9riode pr\xE9c\xE9dente",
|
|
1380
1387
|
previous_year: "Ann\xE9e pr\xE9c\xE9dente",
|
|
1381
|
-
custom: "
|
|
1388
|
+
custom: "P\xE9riode personnalis\xE9e"
|
|
1389
|
+
};
|
|
1390
|
+
var COMPARE_SHORT_LABELS = {
|
|
1391
|
+
none: "",
|
|
1392
|
+
previous_period: "p\xE9riode pr\xE9c.",
|
|
1393
|
+
previous_year: "N-1",
|
|
1394
|
+
custom: "p\xE9riode choisie"
|
|
1382
1395
|
};
|
|
1383
1396
|
var DAY_FORMAT = "yyyy-MM-dd";
|
|
1384
1397
|
var toDay = (date) => dateFns.format(date, DAY_FORMAT);
|
|
1385
1398
|
var fromDay = (day) => dateFns.parse(day, DAY_FORMAT, /* @__PURE__ */ new Date());
|
|
1386
|
-
var CALENDAR_UNIT = {
|
|
1387
|
-
thisMonth: "month",
|
|
1388
|
-
lastMonth: "month",
|
|
1389
|
-
thisQuarter: "quarter",
|
|
1390
|
-
thisYear: "year"
|
|
1391
|
-
};
|
|
1392
1399
|
function presetRange(preset, today) {
|
|
1393
1400
|
const day = toDay(today);
|
|
1394
1401
|
switch (preset) {
|
|
@@ -1405,17 +1412,17 @@ function presetRange(preset, today) {
|
|
|
1405
1412
|
case "last90":
|
|
1406
1413
|
return { from: toDay(dateFns.subDays(today, 89)), to: day };
|
|
1407
1414
|
case "thisMonth":
|
|
1408
|
-
return { from: toDay(dateFns.startOfMonth(today)), to:
|
|
1415
|
+
return { from: toDay(dateFns.startOfMonth(today)), to: day };
|
|
1409
1416
|
case "lastMonth": {
|
|
1410
1417
|
const previous = dateFns.subMonths(today, 1);
|
|
1411
1418
|
return { from: toDay(dateFns.startOfMonth(previous)), to: toDay(dateFns.endOfMonth(previous)) };
|
|
1412
1419
|
}
|
|
1413
1420
|
case "thisQuarter":
|
|
1414
|
-
return { from: toDay(dateFns.startOfQuarter(today)), to:
|
|
1421
|
+
return { from: toDay(dateFns.startOfQuarter(today)), to: day };
|
|
1415
1422
|
case "last12Months":
|
|
1416
|
-
return { from: toDay(dateFns.
|
|
1423
|
+
return { from: toDay(dateFns.subMonths(today, 12)), to: day };
|
|
1417
1424
|
case "thisYear":
|
|
1418
|
-
return { from: toDay(dateFns.startOfYear(today)), to:
|
|
1425
|
+
return { from: toDay(dateFns.startOfYear(today)), to: day };
|
|
1419
1426
|
case "all":
|
|
1420
1427
|
return { to: day };
|
|
1421
1428
|
case "custom":
|
|
@@ -1429,19 +1436,6 @@ function comparisonRange(preset, range, compare2) {
|
|
|
1429
1436
|
if (compare2 === "previous_year") {
|
|
1430
1437
|
return { from: toDay(dateFns.subYears(from, 1)), to: toDay(dateFns.subYears(to, 1)) };
|
|
1431
1438
|
}
|
|
1432
|
-
const unit = CALENDAR_UNIT[preset];
|
|
1433
|
-
if (unit === "month") {
|
|
1434
|
-
const previous = dateFns.subMonths(from, 1);
|
|
1435
|
-
return { from: toDay(dateFns.startOfMonth(previous)), to: toDay(dateFns.endOfMonth(previous)) };
|
|
1436
|
-
}
|
|
1437
|
-
if (unit === "quarter") {
|
|
1438
|
-
const previous = dateFns.addQuarters(from, -1);
|
|
1439
|
-
return { from: toDay(dateFns.startOfQuarter(previous)), to: toDay(dateFns.endOfQuarter(previous)) };
|
|
1440
|
-
}
|
|
1441
|
-
if (unit === "year") {
|
|
1442
|
-
const previous = dateFns.subYears(from, 1);
|
|
1443
|
-
return { from: toDay(dateFns.startOfYear(previous)), to: toDay(dateFns.endOfYear(previous)) };
|
|
1444
|
-
}
|
|
1445
1439
|
const length = dateFns.differenceInCalendarDays(to, from) + 1;
|
|
1446
1440
|
return { from: toDay(dateFns.subDays(from, length)), to: toDay(dateFns.subDays(to, length)) };
|
|
1447
1441
|
}
|
|
@@ -1531,12 +1525,20 @@ var DAY_PICKER_CLASS_NAMES = {
|
|
|
1531
1525
|
today: "font-semibold text-primary",
|
|
1532
1526
|
outside: "text-muted-foreground/50",
|
|
1533
1527
|
disabled: "opacity-40",
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1528
|
+
// A cell DayPicker decided not to fill still occupies the grid, and still
|
|
1529
|
+
// matches the range modifiers below — without this it would show a stretch of
|
|
1530
|
+
// painted band with no number in it. `invisible`, not `hidden`: the six-week
|
|
1531
|
+
// grid keeps its height either way.
|
|
1532
|
+
hidden: "invisible"
|
|
1533
|
+
};
|
|
1534
|
+
var DAY_MODIFIER_CLASS_NAMES = {
|
|
1535
|
+
period_middle: "bg-primary/15",
|
|
1536
|
+
period_start: "rounded-l-md [&_button]:bg-primary [&_button]:text-primary-foreground [&_button]:hover:bg-primary",
|
|
1537
|
+
period_end: "rounded-r-md [&_button]:bg-primary [&_button]:text-primary-foreground [&_button]:hover:bg-primary",
|
|
1538
|
+
compare_middle: "bg-chart-2/30",
|
|
1539
|
+
compare_start: "rounded-l-md bg-chart-2/30 [&_button]:ring-2 [&_button]:ring-inset [&_button]:ring-chart-2 [&_button]:font-semibold [&_button]:text-chart-2",
|
|
1540
|
+
compare_end: "rounded-r-md bg-chart-2/30 [&_button]:ring-2 [&_button]:ring-inset [&_button]:ring-chart-2 [&_button]:font-semibold [&_button]:text-chart-2"
|
|
1538
1541
|
};
|
|
1539
|
-
var COMPARE_MODIFIER_CLASS = "bg-chart-2/25 ring-1 ring-inset ring-chart-2/40";
|
|
1540
1542
|
function draftOf(value) {
|
|
1541
1543
|
return {
|
|
1542
1544
|
preset: value.preset,
|
|
@@ -1568,16 +1570,38 @@ function previewCompare(draft) {
|
|
|
1568
1570
|
function activeCompare(draft) {
|
|
1569
1571
|
return draft.preset === "all" ? "none" : draft.compare;
|
|
1570
1572
|
}
|
|
1571
|
-
function
|
|
1572
|
-
if (!
|
|
1573
|
-
|
|
1574
|
-
return isDay(
|
|
1573
|
+
function bandOf(from, to) {
|
|
1574
|
+
if (!isDay(from)) return void 0;
|
|
1575
|
+
const start = fromDay(from);
|
|
1576
|
+
return { from: start, to: isDay(to) ? fromDay(to) : start };
|
|
1577
|
+
}
|
|
1578
|
+
var inBand = (band, date) => band !== void 0 && date >= band.from && date <= band.to;
|
|
1579
|
+
var isBound = (date, bound) => bound !== void 0 && date.getTime() === bound.getTime();
|
|
1580
|
+
function compareBandOf(draft) {
|
|
1581
|
+
const active = activeCompare(draft);
|
|
1582
|
+
if (active === "none") return void 0;
|
|
1583
|
+
if (active === "custom") return bandOf(draft.compareFrom, draft.compareTo);
|
|
1584
|
+
const derived = previewCompare(draft);
|
|
1585
|
+
return derived?.from ? { from: fromDay(derived.from), to: fromDay(derived.to) } : void 0;
|
|
1586
|
+
}
|
|
1587
|
+
function anchorMonth(range, visible, today) {
|
|
1588
|
+
const from = isDay(range.from) ? fromDay(range.from) : void 0;
|
|
1589
|
+
const to = isDay(range.to) ? fromDay(range.to) : void 0;
|
|
1590
|
+
if (visible === 2) return from ?? to;
|
|
1591
|
+
if (!to) return from;
|
|
1592
|
+
if (to <= today) return to;
|
|
1593
|
+
return from && from <= today ? today : from ?? today;
|
|
1594
|
+
}
|
|
1595
|
+
function selectionOf(from, to) {
|
|
1596
|
+
if (!isDay(from)) return void 0;
|
|
1597
|
+
return { from: fromDay(from), to: isDay(to) ? fromDay(to) : void 0 };
|
|
1575
1598
|
}
|
|
1576
1599
|
function DateRangeCompare({
|
|
1577
1600
|
value,
|
|
1578
1601
|
onChange,
|
|
1579
1602
|
comparable = true,
|
|
1580
1603
|
presets = PERIOD_PRESETS,
|
|
1604
|
+
months = 1,
|
|
1581
1605
|
align = "start",
|
|
1582
1606
|
disabled,
|
|
1583
1607
|
className
|
|
@@ -1585,44 +1609,76 @@ function DateRangeCompare({
|
|
|
1585
1609
|
const [open, setOpen] = React2__namespace.useState(false);
|
|
1586
1610
|
const [draft, setDraft] = React2__namespace.useState(() => draftOf(value));
|
|
1587
1611
|
const [month, setMonth] = React2__namespace.useState(void 0);
|
|
1588
|
-
const [
|
|
1589
|
-
const
|
|
1590
|
-
|
|
1591
|
-
|
|
1612
|
+
const [autoMonths, setAutoMonths] = React2__namespace.useState(1);
|
|
1613
|
+
const [target, setTarget] = React2__namespace.useState("period");
|
|
1614
|
+
const [today, setToday] = React2__namespace.useState(() => /* @__PURE__ */ new Date());
|
|
1615
|
+
const visibleMonths = months === "auto" ? autoMonths : months;
|
|
1616
|
+
const showRange = (range2, at = today) => {
|
|
1617
|
+
const next = months === "auto" ? spansTwoMonths(range2) ? 2 : 1 : months;
|
|
1618
|
+
setAutoMonths(next);
|
|
1619
|
+
setMonth(anchorMonth(range2, next, at));
|
|
1592
1620
|
};
|
|
1593
1621
|
const openPanel = () => {
|
|
1622
|
+
const now = /* @__PURE__ */ new Date();
|
|
1623
|
+
setToday(now);
|
|
1594
1624
|
setDraft(draftOf(value));
|
|
1595
|
-
|
|
1625
|
+
setTarget("period");
|
|
1626
|
+
showRange(value.range, now);
|
|
1596
1627
|
setOpen(true);
|
|
1597
1628
|
};
|
|
1598
|
-
const
|
|
1599
|
-
|
|
1600
|
-
|
|
1629
|
+
const range = rangeOf(draft);
|
|
1630
|
+
const compareRange = previewCompare(draft);
|
|
1631
|
+
const compareEditable = comparable && activeCompare(draft) === "custom";
|
|
1632
|
+
const activeTarget = compareEditable ? target : "period";
|
|
1633
|
+
const periodBand = bandOf(draft.from, draft.to);
|
|
1634
|
+
const compareBand = compareBandOf(draft);
|
|
1635
|
+
const emit = (candidate) => {
|
|
1636
|
+
const complete = rangeOf(candidate);
|
|
1637
|
+
if (!complete) return false;
|
|
1638
|
+
onChange(
|
|
1639
|
+
makePeriod(candidate.preset, complete, activeCompare(candidate), customCompareOf(candidate))
|
|
1640
|
+
);
|
|
1641
|
+
setOpen(false);
|
|
1642
|
+
return true;
|
|
1643
|
+
};
|
|
1644
|
+
const apply = () => emit(draft);
|
|
1645
|
+
const pickPreset = (preset, commit) => {
|
|
1646
|
+
const resolved = periodFromPreset(preset, today, activeCompare(draft));
|
|
1647
|
+
const next = {
|
|
1601
1648
|
...draftOf(resolved),
|
|
1602
1649
|
// The rail changes the period, not the comparison: the mode the user chose
|
|
1603
1650
|
// survives, and `activeCompare` decides whether it can apply here.
|
|
1604
1651
|
compare: draft.compare,
|
|
1605
1652
|
compareFrom: draft.compareFrom,
|
|
1606
1653
|
compareTo: draft.compareTo
|
|
1607
|
-
}
|
|
1654
|
+
};
|
|
1655
|
+
setDraft(next);
|
|
1656
|
+
setTarget("period");
|
|
1608
1657
|
showRange(resolved.range);
|
|
1658
|
+
if (!comparable && commit) emit(next);
|
|
1609
1659
|
};
|
|
1610
1660
|
const pickDays = (selected) => {
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
}
|
|
1661
|
+
const from = selected?.from ? toDay(selected.from) : void 0;
|
|
1662
|
+
const to = selected?.to ? toDay(selected.to) : void 0;
|
|
1663
|
+
if (activeTarget === "compare") {
|
|
1664
|
+
setDraft({ ...draft, compare: "custom", compareFrom: from, compareTo: to });
|
|
1665
|
+
return;
|
|
1666
|
+
}
|
|
1667
|
+
setDraft({ ...draft, preset: "custom", from, to });
|
|
1617
1668
|
};
|
|
1618
|
-
const
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1669
|
+
const chooseCompare = (mode) => {
|
|
1670
|
+
const next = { ...draft, compare: mode };
|
|
1671
|
+
setDraft(next);
|
|
1672
|
+
setTarget(mode === "custom" ? "compare" : "period");
|
|
1673
|
+
const shown = mode === "custom" ? customCompareOf(next) : range;
|
|
1674
|
+
if (shown) showRange(shown);
|
|
1675
|
+
};
|
|
1676
|
+
const focusTarget = (next) => {
|
|
1677
|
+
setTarget(next);
|
|
1678
|
+
const shown = next === "compare" ? customCompareOf(draft) : range;
|
|
1679
|
+
if (shown) showRange(shown);
|
|
1624
1680
|
};
|
|
1625
|
-
const
|
|
1681
|
+
const footer = activeTarget === "compare" ? compareRange ? formatRange(compareRange) : "P\xE9riode de comparaison \xE0 choisir" : range ? `${formatRange(range)}${compareRange ? ` vs ${formatRange(compareRange)}` : ""}` : "Date de fin \xE0 choisir";
|
|
1626
1682
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1627
1683
|
Popover,
|
|
1628
1684
|
{
|
|
@@ -1630,42 +1686,81 @@ function DateRangeCompare({
|
|
|
1630
1686
|
onOpenChange: (next) => next ? openPanel() : setOpen(false),
|
|
1631
1687
|
align,
|
|
1632
1688
|
className: cn("w-auto p-0", className),
|
|
1633
|
-
trigger: /* @__PURE__ */ jsxRuntime.
|
|
1634
|
-
|
|
1635
|
-
|
|
1689
|
+
trigger: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "outline", disabled, children: [
|
|
1690
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconCalendar, { className: "size-4 text-muted-foreground" }),
|
|
1691
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatPeriod(value) }),
|
|
1692
|
+
value.compare !== "none" && value.compareRange !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "rounded-md bg-chart-2/15 px-1.5 py-0.5 text-xs font-medium text-chart-2", children: [
|
|
1693
|
+
"vs ",
|
|
1694
|
+
COMPARE_SHORT_LABELS[value.compare]
|
|
1695
|
+
] }),
|
|
1696
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconChevronDown, { className: "size-4 text-muted-foreground" })
|
|
1697
|
+
] }),
|
|
1698
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex max-h-[80vh] items-stretch", children: [
|
|
1699
|
+
(presets.length > 0 || comparable) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-48 shrink-0 flex-col border-r", children: [
|
|
1700
|
+
presets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1701
|
+
PresetRail,
|
|
1702
|
+
{
|
|
1703
|
+
presets,
|
|
1704
|
+
selected: draft.preset,
|
|
1705
|
+
onSelect: pickPreset,
|
|
1706
|
+
className: "min-h-0 flex-1 overflow-y-auto p-2"
|
|
1707
|
+
}
|
|
1708
|
+
),
|
|
1709
|
+
comparable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1710
|
+
CompareSection,
|
|
1711
|
+
{
|
|
1712
|
+
draft,
|
|
1713
|
+
compareRange,
|
|
1714
|
+
onModeChange: chooseCompare
|
|
1715
|
+
}
|
|
1716
|
+
)
|
|
1717
|
+
] }),
|
|
1636
1718
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
1719
|
+
comparable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1720
|
+
TargetPills,
|
|
1721
|
+
{
|
|
1722
|
+
target: activeTarget,
|
|
1723
|
+
onSelect: focusTarget,
|
|
1724
|
+
compareEditable
|
|
1725
|
+
}
|
|
1726
|
+
),
|
|
1637
1727
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative p-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1638
1728
|
reactDayPicker.DayPicker,
|
|
1639
1729
|
{
|
|
1640
1730
|
mode: "range",
|
|
1641
1731
|
locale: fr.fr,
|
|
1642
1732
|
weekStartsOn: 1,
|
|
1643
|
-
numberOfMonths:
|
|
1733
|
+
numberOfMonths: visibleMonths,
|
|
1644
1734
|
month,
|
|
1645
1735
|
onMonthChange: setMonth,
|
|
1646
|
-
|
|
1736
|
+
today,
|
|
1737
|
+
disabled: { after: today },
|
|
1738
|
+
fixedWeeks: true,
|
|
1739
|
+
showOutsideDays: visibleMonths === 1,
|
|
1740
|
+
selected: activeTarget === "compare" ? selectionOf(draft.compareFrom, draft.compareTo) : selectionOf(draft.from, draft.to),
|
|
1647
1741
|
onSelect: pickDays,
|
|
1648
1742
|
modifiers: {
|
|
1649
|
-
|
|
1743
|
+
period_middle: periodBand ? [{ from: periodBand.from, to: periodBand.to }] : [],
|
|
1744
|
+
period_start: periodBand ? [periodBand.from] : [],
|
|
1745
|
+
period_end: periodBand ? [periodBand.to] : [],
|
|
1746
|
+
// The period wins any cell both ranges claim.
|
|
1747
|
+
compare_middle: (date) => inBand(compareBand, date) && !inBand(periodBand, date),
|
|
1748
|
+
compare_start: (date) => isBound(date, compareBand?.from) && !inBand(periodBand, date),
|
|
1749
|
+
compare_end: (date) => isBound(date, compareBand?.to) && !inBand(periodBand, date)
|
|
1650
1750
|
},
|
|
1651
|
-
modifiersClassNames:
|
|
1652
|
-
classNames: DAY_PICKER_CLASS_NAMES
|
|
1751
|
+
modifiersClassNames: DAY_MODIFIER_CLASS_NAMES,
|
|
1752
|
+
classNames: DAY_PICKER_CLASS_NAMES,
|
|
1753
|
+
"aria-label": activeTarget === "compare" ? "Calendrier \u2014 s\xE9lection de la comparaison" : "Calendrier \u2014 s\xE9lection de la p\xE9riode",
|
|
1754
|
+
labels: {
|
|
1755
|
+
// Suffixed rather than replaced: which range a click lands in is
|
|
1756
|
+
// the one thing a screen reader cannot get from the grid, and the
|
|
1757
|
+
// default label still carries the date and its state.
|
|
1758
|
+
labelDayButton: (date, modifiers, options, dateLib) => `${reactDayPicker.labelDayButton(date, modifiers, options, dateLib)} \u2014 ${activeTarget === "compare" ? "comparaison" : "p\xE9riode"}`
|
|
1759
|
+
}
|
|
1653
1760
|
}
|
|
1654
1761
|
) }),
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
{
|
|
1658
|
-
draft,
|
|
1659
|
-
compareRange,
|
|
1660
|
-
onModeChange: (compare2) => setDraft({ ...draft, compare: compare2 }),
|
|
1661
|
-
onCustomChange: (from, to) => setDraft({ ...draft, compareFrom: from, compareTo: to })
|
|
1662
|
-
}
|
|
1663
|
-
),
|
|
1664
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-4 border-t px-3 py-2", children: [
|
|
1665
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
1666
|
-
range ? formatRange(range) : "Choisissez une date de fin",
|
|
1667
|
-
compareRange && ` vs ${formatRange(compareRange)}`
|
|
1668
|
-
] }),
|
|
1762
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-auto flex items-center justify-between gap-4 border-t px-3 py-2", children: [
|
|
1763
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", "aria-live": "polite", className: "text-xs text-muted-foreground", children: footer }),
|
|
1669
1764
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
1670
1765
|
/* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", onClick: () => setOpen(false), children: "Annuler" }),
|
|
1671
1766
|
/* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", onClick: apply, disabled: !range, children: "Appliquer" })
|
|
@@ -1686,6 +1781,7 @@ function DateRangePicker({ value, onChange, className, disabled }) {
|
|
|
1686
1781
|
},
|
|
1687
1782
|
comparable: false,
|
|
1688
1783
|
presets: [],
|
|
1784
|
+
months: "auto",
|
|
1689
1785
|
disabled,
|
|
1690
1786
|
className
|
|
1691
1787
|
}
|
|
@@ -1694,7 +1790,8 @@ function DateRangePicker({ value, onChange, className, disabled }) {
|
|
|
1694
1790
|
function PresetRail({
|
|
1695
1791
|
presets,
|
|
1696
1792
|
selected,
|
|
1697
|
-
onSelect
|
|
1793
|
+
onSelect,
|
|
1794
|
+
className
|
|
1698
1795
|
}) {
|
|
1699
1796
|
const refs = React2__namespace.useRef([]);
|
|
1700
1797
|
const activeIndex = Math.max(
|
|
@@ -1704,7 +1801,7 @@ function PresetRail({
|
|
|
1704
1801
|
const moveTo = (index) => {
|
|
1705
1802
|
const next = (index + presets.length) % presets.length;
|
|
1706
1803
|
refs.current[next]?.focus();
|
|
1707
|
-
onSelect(presets[next].key);
|
|
1804
|
+
onSelect(presets[next].key, false);
|
|
1708
1805
|
};
|
|
1709
1806
|
const onKeyDown = (event, index) => {
|
|
1710
1807
|
const step = { ArrowDown: 1, ArrowRight: 1, ArrowUp: -1, ArrowLeft: -1 }[event.key];
|
|
@@ -1723,7 +1820,7 @@ function PresetRail({
|
|
|
1723
1820
|
{
|
|
1724
1821
|
role: "radiogroup",
|
|
1725
1822
|
"aria-label": "P\xE9riode pr\xE9d\xE9finie",
|
|
1726
|
-
className: "flex
|
|
1823
|
+
className: cn("flex flex-col gap-0.5", className),
|
|
1727
1824
|
children: presets.map((preset, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1728
1825
|
"button",
|
|
1729
1826
|
{
|
|
@@ -1735,9 +1832,9 @@ function PresetRail({
|
|
|
1735
1832
|
"aria-checked": preset.key === selected,
|
|
1736
1833
|
tabIndex: index === activeIndex ? 0 : -1,
|
|
1737
1834
|
onKeyDown: (event) => onKeyDown(event, index),
|
|
1738
|
-
onClick: () => onSelect(preset.key),
|
|
1835
|
+
onClick: () => onSelect(preset.key, true),
|
|
1739
1836
|
className: cn(
|
|
1740
|
-
"rounded px-3 py-1.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1837
|
+
"shrink-0 rounded px-3 py-1.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1741
1838
|
preset.key === selected ? "bg-muted font-medium text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"
|
|
1742
1839
|
),
|
|
1743
1840
|
children: preset.label
|
|
@@ -1747,17 +1844,62 @@ function PresetRail({
|
|
|
1747
1844
|
}
|
|
1748
1845
|
);
|
|
1749
1846
|
}
|
|
1847
|
+
var TARGETS = [
|
|
1848
|
+
{ key: "period", label: "P\xE9riode", swatch: "bg-primary" },
|
|
1849
|
+
{ key: "compare", label: "Comparaison", swatch: "ring-2 ring-inset ring-chart-2" }
|
|
1850
|
+
];
|
|
1851
|
+
function TargetPills({
|
|
1852
|
+
target,
|
|
1853
|
+
onSelect,
|
|
1854
|
+
compareEditable
|
|
1855
|
+
}) {
|
|
1856
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1857
|
+
"div",
|
|
1858
|
+
{
|
|
1859
|
+
role: "radiogroup",
|
|
1860
|
+
"aria-label": "Cible de la s\xE9lection",
|
|
1861
|
+
className: "flex items-center gap-1 border-b px-3 py-2",
|
|
1862
|
+
children: TARGETS.map((entry) => {
|
|
1863
|
+
const enabled = entry.key === "period" || compareEditable;
|
|
1864
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1865
|
+
"button",
|
|
1866
|
+
{
|
|
1867
|
+
type: "button",
|
|
1868
|
+
role: "radio",
|
|
1869
|
+
"aria-checked": target === entry.key,
|
|
1870
|
+
disabled: !enabled,
|
|
1871
|
+
tabIndex: target === entry.key ? 0 : -1,
|
|
1872
|
+
onKeyDown: (event) => {
|
|
1873
|
+
if (!["ArrowDown", "ArrowRight", "ArrowUp", "ArrowLeft"].includes(event.key)) return;
|
|
1874
|
+
event.preventDefault();
|
|
1875
|
+
if (compareEditable) onSelect(target === "period" ? "compare" : "period");
|
|
1876
|
+
},
|
|
1877
|
+
onClick: () => onSelect(entry.key),
|
|
1878
|
+
className: cn(
|
|
1879
|
+
"inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-40",
|
|
1880
|
+
target === entry.key ? "border-border bg-muted font-medium text-foreground" : "border-border text-muted-foreground hover:bg-muted hover:text-foreground"
|
|
1881
|
+
),
|
|
1882
|
+
children: [
|
|
1883
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: cn("size-2.5 rounded-sm", entry.swatch) }),
|
|
1884
|
+
entry.label
|
|
1885
|
+
]
|
|
1886
|
+
},
|
|
1887
|
+
entry.key
|
|
1888
|
+
);
|
|
1889
|
+
})
|
|
1890
|
+
}
|
|
1891
|
+
);
|
|
1892
|
+
}
|
|
1750
1893
|
function CompareSection({
|
|
1751
1894
|
draft,
|
|
1752
1895
|
compareRange,
|
|
1753
|
-
onModeChange
|
|
1754
|
-
onCustomChange
|
|
1896
|
+
onModeChange
|
|
1755
1897
|
}) {
|
|
1756
1898
|
const derivable = draft.preset !== "all";
|
|
1757
1899
|
const active = activeCompare(draft);
|
|
1758
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "
|
|
1759
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-muted-foreground", children: "Comparer \xE0" }),
|
|
1760
|
-
|
|
1900
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5 border-t p-2", children: [
|
|
1901
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-3 pb-1 text-xs font-medium text-muted-foreground", children: "Comparer \xE0" }),
|
|
1902
|
+
COMPARE_MODES.map((mode) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1761
1903
|
"button",
|
|
1762
1904
|
{
|
|
1763
1905
|
type: "button",
|
|
@@ -1765,44 +1907,53 @@ function CompareSection({
|
|
|
1765
1907
|
disabled: mode !== "none" && !derivable,
|
|
1766
1908
|
onClick: () => onModeChange(mode),
|
|
1767
1909
|
className: cn(
|
|
1768
|
-
"
|
|
1769
|
-
active === mode ? "
|
|
1910
|
+
"shrink-0 rounded px-3 py-1.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-40",
|
|
1911
|
+
active === mode ? "bg-muted font-medium text-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"
|
|
1770
1912
|
),
|
|
1771
1913
|
children: COMPARE_LABELS[mode]
|
|
1772
1914
|
},
|
|
1773
1915
|
mode
|
|
1774
|
-
))
|
|
1775
|
-
active
|
|
1776
|
-
// one grid and two ranges to fill, nothing on screen would say which one
|
|
1777
|
-
// a click is about to change.
|
|
1778
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1779
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1780
|
-
"input",
|
|
1781
|
-
{
|
|
1782
|
-
type: "date",
|
|
1783
|
-
"aria-label": "D\xE9but de la comparaison",
|
|
1784
|
-
value: draft.compareFrom ?? "",
|
|
1785
|
-
max: draft.compareTo,
|
|
1786
|
-
onChange: (event) => onCustomChange(event.target.value || void 0, draft.compareTo),
|
|
1787
|
-
className: "h-8 rounded-md border border-input bg-transparent px-2 text-sm"
|
|
1788
|
-
}
|
|
1789
|
-
),
|
|
1790
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "\u2192" }),
|
|
1791
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1792
|
-
"input",
|
|
1793
|
-
{
|
|
1794
|
-
type: "date",
|
|
1795
|
-
"aria-label": "Fin de la comparaison",
|
|
1796
|
-
value: draft.compareTo ?? "",
|
|
1797
|
-
min: draft.compareFrom,
|
|
1798
|
-
onChange: (event) => onCustomChange(draft.compareFrom, event.target.value || void 0),
|
|
1799
|
-
className: "h-8 rounded-md border border-input bg-transparent px-2 text-sm"
|
|
1800
|
-
}
|
|
1801
|
-
)
|
|
1802
|
-
] }),
|
|
1803
|
-
compareRange && active !== "custom" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: formatRange(compareRange) })
|
|
1916
|
+
)),
|
|
1917
|
+
compareRange && active !== "custom" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-3 pt-1 text-xs text-muted-foreground", children: formatRange(compareRange) })
|
|
1804
1918
|
] });
|
|
1805
1919
|
}
|
|
1920
|
+
function IconCalendar({ className }) {
|
|
1921
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1922
|
+
"svg",
|
|
1923
|
+
{
|
|
1924
|
+
className,
|
|
1925
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1926
|
+
viewBox: "0 0 24 24",
|
|
1927
|
+
fill: "none",
|
|
1928
|
+
stroke: "currentColor",
|
|
1929
|
+
strokeWidth: "2",
|
|
1930
|
+
strokeLinecap: "round",
|
|
1931
|
+
strokeLinejoin: "round",
|
|
1932
|
+
"aria-hidden": "true",
|
|
1933
|
+
children: [
|
|
1934
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 2v4M16 2v4M3 10h18" }),
|
|
1935
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { width: "18", height: "18", x: "3", y: "4", rx: "2" })
|
|
1936
|
+
]
|
|
1937
|
+
}
|
|
1938
|
+
);
|
|
1939
|
+
}
|
|
1940
|
+
function IconChevronDown({ className }) {
|
|
1941
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1942
|
+
"svg",
|
|
1943
|
+
{
|
|
1944
|
+
className,
|
|
1945
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1946
|
+
viewBox: "0 0 24 24",
|
|
1947
|
+
fill: "none",
|
|
1948
|
+
stroke: "currentColor",
|
|
1949
|
+
strokeWidth: "2",
|
|
1950
|
+
strokeLinecap: "round",
|
|
1951
|
+
strokeLinejoin: "round",
|
|
1952
|
+
"aria-hidden": "true",
|
|
1953
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 9 6 6 6-6" })
|
|
1954
|
+
}
|
|
1955
|
+
);
|
|
1956
|
+
}
|
|
1806
1957
|
var CHART_COLORS = [
|
|
1807
1958
|
"var(--chart-1)",
|
|
1808
1959
|
"var(--chart-2)",
|
|
@@ -2231,6 +2382,7 @@ exports.Badge = Badge;
|
|
|
2231
2382
|
exports.BarChart = BarChart;
|
|
2232
2383
|
exports.Button = Button;
|
|
2233
2384
|
exports.COMPARE_LABELS = COMPARE_LABELS;
|
|
2385
|
+
exports.COMPARE_SHORT_LABELS = COMPARE_SHORT_LABELS;
|
|
2234
2386
|
exports.Card = Card;
|
|
2235
2387
|
exports.CardContent = CardContent;
|
|
2236
2388
|
exports.CardDescription = CardDescription;
|