@xenide-io/the-old-ui-theme 0.7.1 → 0.9.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 +9 -10
- package/dist/{Chip-Cq3AiAji.d.mts → Chip-BzuNgJIa.d.mts} +81 -23
- package/dist/{Chip-Cq3AiAji.d.ts → Chip-BzuNgJIa.d.ts} +81 -23
- package/dist/{ai-message-blocknote-WABTHFY7.mjs → ai-message-blocknote-D4Z6DUCJ.mjs} +9 -3
- package/dist/{chunk-YB4TBWHV.mjs → chunk-2EO5VCXP.mjs} +688 -388
- package/dist/chunk-APKRZQRO.mjs +251 -0
- package/dist/chunk-BS7BZI5W.mjs +19 -0
- package/dist/chunk-IULORI3A.mjs +8 -0
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +997 -576
- package/dist/index.mjs +7 -1
- package/dist/suite.d.mts +136 -57
- package/dist/suite.d.ts +136 -57
- package/dist/suite.js +3115 -882
- package/dist/suite.mjs +2566 -661
- package/dist/theme-boot-P-oqKVZF.d.mts +74 -0
- package/dist/theme-boot-P-oqKVZF.d.ts +74 -0
- package/dist/theme-boot.d.mts +2 -0
- package/dist/theme-boot.d.ts +2 -0
- package/dist/theme-boot.js +44 -0
- package/dist/theme-boot.mjs +8 -0
- package/dist/ui.d.mts +5 -29
- package/dist/ui.d.ts +5 -29
- package/dist/ui.js +647 -352
- package/dist/ui.mjs +1 -1
- package/docs/README.md +34 -0
- package/docs/ai-quick-reference.md +56 -0
- package/docs/component-library-improvement-plan.md +751 -0
- package/docs/component-reference.md +81 -0
- package/docs/components.md +48 -0
- package/docs/demos.md +19 -0
- package/docs/installation.md +117 -0
- package/docs/suite-audit.md +34 -0
- package/docs/theme-token-reference.md +67 -0
- package/docs/themes.md +164 -0
- package/package.json +22 -21
- package/public/fonts/OpenRunde-Bold.woff2 +0 -0
- package/public/fonts/OpenRunde-Medium.woff2 +0 -0
- package/public/fonts/OpenRunde-Regular.woff2 +0 -0
- package/public/fonts/OpenRunde-Semibold.woff2 +0 -0
- package/scripts/package-smoke.mjs +43 -0
- package/src/app/globals.css +2 -1
- package/src/components/ui/Accordion.tsx +20 -6
- package/src/components/ui/Avatar.tsx +5 -3
- package/src/components/ui/Calendar.tsx +187 -63
- package/src/components/ui/Card.test.tsx +38 -0
- package/src/components/ui/Card.tsx +77 -14
- package/src/components/ui/CollapsibleSection.tsx +12 -4
- package/src/components/ui/CommandPalette.test.tsx +91 -4
- package/src/components/ui/CommandPalette.tsx +138 -128
- package/src/components/ui/EmptyState.tsx +2 -2
- package/src/components/ui/FormField.tsx +1 -1
- package/src/components/ui/Input.tsx +42 -18
- package/src/components/ui/Kbd.tsx +18 -3
- package/src/components/ui/Modal.tsx +3 -1
- package/src/components/ui/Progress.tsx +14 -5
- package/src/components/ui/SegmentedControl.tsx +2 -2
- package/src/components/ui/SettingsLayout.tsx +1 -1
- package/src/components/ui/Stat.tsx +3 -2
- package/src/components/ui/Table.tsx +8 -3
- package/src/components/ui/Tooltip.test.tsx +70 -1
- package/src/components/ui/Tooltip.tsx +53 -29
- package/src/components/ui/Typography.tsx +103 -49
- package/src/components/ui/avatar-stat.test.tsx +23 -0
- package/src/components/ui/calendar.test.tsx +88 -0
- package/src/components/ui/disclosure.test.tsx +39 -0
- package/src/components/ui/index.ts +44 -6
- package/src/components/ui/progress.test.tsx +15 -0
- package/src/components/ui/typography.test.tsx +26 -1
- package/src/styles/suite-skin.css +8 -2
- package/src/styles/themes.css +184 -68
- package/src/suite/components/ai-message-blocknote.tsx +13 -2
- package/src/suite/components/ai-panel.tsx +41 -10
- package/src/suite/components/app-switcher.test.tsx +21 -6
- package/src/suite/components/app-switcher.tsx +7 -11
- package/src/suite/components/suite-app-layout.tsx +12 -3
- package/src/suite/components/suite-bottom-nav.tsx +0 -1
- package/src/suite/components/suite-clients-projects-directory.test.tsx +71 -0
- package/src/suite/components/suite-clients-projects-directory.tsx +943 -0
- package/src/suite/components/suite-integration-picker.test.tsx +224 -0
- package/src/suite/components/suite-integration-picker.tsx +889 -18
- package/src/suite/components/suite-integration-rules.test.tsx +157 -0
- package/src/suite/components/suite-integration-rules.tsx +471 -0
- package/src/suite/components/suite-mobile-drawer.test.tsx +18 -2
- package/src/suite/components/suite-mobile-drawer.tsx +65 -98
- package/src/suite/components/suite-notification-bell.tsx +29 -4
- package/src/suite/components/suite-sidebar.tsx +25 -25
- package/src/suite/components/suite-skeleton.tsx +2 -2
- package/src/suite/components/suite-user-menu.tsx +9 -8
- package/src/suite/components/theme-provider.test.tsx +87 -3
- package/src/suite/components/theme-provider.tsx +144 -23
- package/src/suite/components/today-ui.tsx +79 -68
- package/src/suite/components/workspace-switcher.test.tsx +56 -0
- package/src/suite/components/workspace-switcher.tsx +3 -3
- package/src/suite/icons/app-accents.ts +12 -12
- package/src/suite/icons/glyphs.ts +6 -12
- package/src/suite/index.ts +22 -0
- package/src/suite/lib/apps.test.ts +9 -1
- package/src/suite/lib/apps.ts +14 -8
- package/src/suite/lib/cookies.ts +53 -0
- package/src/suite/lib/theme-boot.ts +32 -0
- package/src/suite/lib/theme-cookie.ts +7 -0
- package/src/suite/lib/use-sidebar-width.ts +5 -51
- package/dist/chunk-NOI42JNZ.mjs +0 -151
- package/src/suite/lib/use-lock-mobile-page-zoom.test.tsx +0 -65
- package/src/suite/lib/use-lock-mobile-page-zoom.ts +0 -51
package/dist/ui.js
CHANGED
|
@@ -914,7 +914,12 @@ var Card = (0, import_react7.forwardRef)(function Card2(_a, ref) {
|
|
|
914
914
|
className,
|
|
915
915
|
bodyClassName,
|
|
916
916
|
interactive = false,
|
|
917
|
-
|
|
917
|
+
href,
|
|
918
|
+
onClick,
|
|
919
|
+
target,
|
|
920
|
+
rel,
|
|
921
|
+
type,
|
|
922
|
+
titleAs: Title3 = "h3"
|
|
918
923
|
} = _b, props = __objRest(_b, [
|
|
919
924
|
"children",
|
|
920
925
|
"title",
|
|
@@ -926,31 +931,60 @@ var Card = (0, import_react7.forwardRef)(function Card2(_a, ref) {
|
|
|
926
931
|
"className",
|
|
927
932
|
"bodyClassName",
|
|
928
933
|
"interactive",
|
|
934
|
+
"href",
|
|
935
|
+
"onClick",
|
|
936
|
+
"target",
|
|
937
|
+
"rel",
|
|
938
|
+
"type",
|
|
929
939
|
"titleAs"
|
|
930
940
|
]);
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
interactive && "ph-card-interactive",
|
|
939
|
-
className
|
|
940
|
-
)
|
|
941
|
-
}, props), {
|
|
942
|
-
children: [
|
|
943
|
-
media && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "ph-card-media", children: media }),
|
|
944
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: cn("ph-card-body", bodyClassName), children: [
|
|
945
|
-
title && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Title2, { className: "ph-card-title", children: title }),
|
|
946
|
-
description && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-ph-subtle", children: description }),
|
|
947
|
-
children,
|
|
948
|
-
actions && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "ph-card-actions", children: actions })
|
|
949
|
-
] }),
|
|
950
|
-
footer && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "border-t border-ph-border px-6 py-4 text-xs text-ph-subtle", children: footer })
|
|
951
|
-
]
|
|
952
|
-
})
|
|
941
|
+
const isLink = href !== void 0;
|
|
942
|
+
const isButton = onClick !== void 0 && !isLink;
|
|
943
|
+
const cardClassName = cn(
|
|
944
|
+
"ph-card",
|
|
945
|
+
variantMap2[variant],
|
|
946
|
+
(interactive || isLink || isButton) && "ph-card-interactive",
|
|
947
|
+
className
|
|
953
948
|
);
|
|
949
|
+
const cardContent = /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
950
|
+
media && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "ph-card-media", children: media }),
|
|
951
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: cn("ph-card-body", bodyClassName), children: [
|
|
952
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Title3, { className: "ph-card-title", children: title }),
|
|
953
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-ph-subtle", children: description }),
|
|
954
|
+
children,
|
|
955
|
+
actions && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "ph-card-actions", children: actions })
|
|
956
|
+
] }),
|
|
957
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "border-t border-ph-border px-6 py-4 text-xs text-ph-subtle", children: footer })
|
|
958
|
+
] });
|
|
959
|
+
if (isLink) {
|
|
960
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
961
|
+
"a",
|
|
962
|
+
__spreadProps(__spreadValues({
|
|
963
|
+
ref,
|
|
964
|
+
className: cardClassName,
|
|
965
|
+
href,
|
|
966
|
+
target,
|
|
967
|
+
rel,
|
|
968
|
+
onClick
|
|
969
|
+
}, props), {
|
|
970
|
+
children: cardContent
|
|
971
|
+
})
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
if (isButton) {
|
|
975
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
976
|
+
"button",
|
|
977
|
+
__spreadProps(__spreadValues({
|
|
978
|
+
ref,
|
|
979
|
+
type: type != null ? type : "button",
|
|
980
|
+
className: cardClassName,
|
|
981
|
+
onClick
|
|
982
|
+
}, props), {
|
|
983
|
+
children: cardContent
|
|
984
|
+
})
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", __spreadProps(__spreadValues({ ref, className: cardClassName }, props), { children: cardContent }));
|
|
954
988
|
});
|
|
955
989
|
Card.displayName = "Card";
|
|
956
990
|
|
|
@@ -1014,18 +1048,45 @@ function Kbd(_a) {
|
|
|
1014
1048
|
"aria-label"
|
|
1015
1049
|
]);
|
|
1016
1050
|
if (variant === "token") {
|
|
1017
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1051
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1052
|
+
"code",
|
|
1053
|
+
__spreadProps(__spreadValues({
|
|
1054
|
+
className: cn("ph-code-token ph-kbd", className),
|
|
1055
|
+
role: ariaLabel ? "img" : void 0,
|
|
1056
|
+
"aria-label": ariaLabel
|
|
1057
|
+
}, props), {
|
|
1058
|
+
children
|
|
1059
|
+
})
|
|
1060
|
+
);
|
|
1018
1061
|
}
|
|
1019
1062
|
const sourceKeys = (keys == null ? void 0 : keys.length) ? keys : children != null ? [children] : [];
|
|
1020
1063
|
const displayKeys = sourceKeys.map((key) => formatKey(key, platform));
|
|
1021
1064
|
const accessibleLabel = ariaLabel != null ? ariaLabel : getShortcutLabel(displayKeys);
|
|
1022
1065
|
if (variant === "key") {
|
|
1023
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1066
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1067
|
+
"kbd",
|
|
1068
|
+
__spreadProps(__spreadValues({
|
|
1069
|
+
className: cn("ph-keycap", className),
|
|
1070
|
+
role: accessibleLabel ? "img" : void 0,
|
|
1071
|
+
"aria-label": accessibleLabel
|
|
1072
|
+
}, props), {
|
|
1073
|
+
children: displayKeys[0]
|
|
1074
|
+
})
|
|
1075
|
+
);
|
|
1024
1076
|
}
|
|
1025
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1077
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1078
|
+
"kbd",
|
|
1079
|
+
__spreadProps(__spreadValues({
|
|
1080
|
+
className: cn("ph-shortcut-group ph-keycap", className),
|
|
1081
|
+
role: accessibleLabel ? "img" : void 0,
|
|
1082
|
+
"aria-label": accessibleLabel
|
|
1083
|
+
}, props), {
|
|
1084
|
+
children: displayKeys.map((key, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "contents", children: [
|
|
1085
|
+
index > 0 && separator != null ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ph-shortcut-separator", "aria-hidden": "true", children: separator }) : null,
|
|
1086
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ph-shortcut-key", "aria-hidden": accessibleLabel ? true : void 0, children: key })
|
|
1087
|
+
] }, index))
|
|
1088
|
+
})
|
|
1089
|
+
);
|
|
1029
1090
|
}
|
|
1030
1091
|
function formatKey(key, platform) {
|
|
1031
1092
|
var _a;
|
|
@@ -1159,7 +1220,7 @@ var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
|
1159
1220
|
function SettingsNav(_a) {
|
|
1160
1221
|
var _b = _a, { groups, className } = _b, props = __objRest(_b, ["groups", "className"]);
|
|
1161
1222
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", __spreadProps(__spreadValues({ className: cn("ph-settings-nav", className) }, props), { children: groups.map((group, index) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ph-settings-nav__group", children: [
|
|
1162
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("
|
|
1223
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "ph-settings-nav__heading", children: group.label }),
|
|
1163
1224
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ph-settings-nav__items", children: group.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1164
1225
|
"a",
|
|
1165
1226
|
{
|
|
@@ -1491,6 +1552,7 @@ function DropdownRadioItem(_a) {
|
|
|
1491
1552
|
|
|
1492
1553
|
// src/components/ui/Input.tsx
|
|
1493
1554
|
var import_react10 = require("react");
|
|
1555
|
+
var import_iconoir_react = require("iconoir-react");
|
|
1494
1556
|
|
|
1495
1557
|
// src/components/ui/FormField.tsx
|
|
1496
1558
|
var import_react9 = require("react");
|
|
@@ -1523,7 +1585,7 @@ function FormField(_a) {
|
|
|
1523
1585
|
const errorId = error ? `${id}-error` : void 0;
|
|
1524
1586
|
const controlProps = {
|
|
1525
1587
|
id,
|
|
1526
|
-
"aria-describedby": descriptionId,
|
|
1588
|
+
"aria-describedby": errorId != null ? errorId : descriptionId,
|
|
1527
1589
|
"aria-errormessage": errorId,
|
|
1528
1590
|
"aria-invalid": error ? true : void 0
|
|
1529
1591
|
};
|
|
@@ -1565,6 +1627,7 @@ var Input = (0, import_react10.forwardRef)(function Input2(_a, ref) {
|
|
|
1565
1627
|
helperText,
|
|
1566
1628
|
size = "md",
|
|
1567
1629
|
variant = "default",
|
|
1630
|
+
type = "text",
|
|
1568
1631
|
className,
|
|
1569
1632
|
wrapperClassName,
|
|
1570
1633
|
disabled,
|
|
@@ -1578,6 +1641,7 @@ var Input = (0, import_react10.forwardRef)(function Input2(_a, ref) {
|
|
|
1578
1641
|
"helperText",
|
|
1579
1642
|
"size",
|
|
1580
1643
|
"variant",
|
|
1644
|
+
"type",
|
|
1581
1645
|
"className",
|
|
1582
1646
|
"wrapperClassName",
|
|
1583
1647
|
"disabled",
|
|
@@ -1587,6 +1651,8 @@ var Input = (0, import_react10.forwardRef)(function Input2(_a, ref) {
|
|
|
1587
1651
|
const autoId = (0, import_react10.useId)();
|
|
1588
1652
|
const id = idProp != null ? idProp : autoId;
|
|
1589
1653
|
const hasError = Boolean(error);
|
|
1654
|
+
const isPassword = type === "password";
|
|
1655
|
+
const [revealed, setRevealed] = (0, import_react10.useState)(false);
|
|
1590
1656
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1591
1657
|
FormField,
|
|
1592
1658
|
{
|
|
@@ -1598,23 +1664,39 @@ var Input = (0, import_react10.forwardRef)(function Input2(_a, ref) {
|
|
|
1598
1664
|
required,
|
|
1599
1665
|
disabled,
|
|
1600
1666
|
className: wrapperClassName,
|
|
1601
|
-
children: (fieldProps) => /* @__PURE__ */ (0, import_jsx_runtime15.
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
"
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1667
|
+
children: (fieldProps) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "relative", children: [
|
|
1668
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1669
|
+
"input",
|
|
1670
|
+
__spreadValues(__spreadProps(__spreadValues({}, fieldProps), {
|
|
1671
|
+
ref,
|
|
1672
|
+
type: isPassword && revealed ? "text" : type,
|
|
1673
|
+
disabled,
|
|
1674
|
+
required,
|
|
1675
|
+
"aria-describedby": joinIds(ariaDescribedBy, fieldProps["aria-describedby"]),
|
|
1676
|
+
className: cn(
|
|
1677
|
+
"ph-input w-full",
|
|
1678
|
+
isPassword && "pr-10",
|
|
1679
|
+
sizeMap2[size],
|
|
1680
|
+
variant === "ghost" && "ph-input-ghost",
|
|
1681
|
+
hasError && "ph-input-error",
|
|
1682
|
+
disabled && "cursor-not-allowed opacity-60",
|
|
1683
|
+
className
|
|
1684
|
+
)
|
|
1685
|
+
}), props)
|
|
1686
|
+
),
|
|
1687
|
+
isPassword ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1688
|
+
"button",
|
|
1689
|
+
{
|
|
1690
|
+
type: "button",
|
|
1691
|
+
onClick: () => setRevealed((current) => !current),
|
|
1692
|
+
"aria-label": revealed ? "Hide password" : "Show password",
|
|
1693
|
+
"aria-pressed": revealed,
|
|
1694
|
+
disabled,
|
|
1695
|
+
className: "absolute inset-y-0 right-0 flex w-10 items-center justify-center rounded-r-[var(--ph-radius-control)] text-ph-mutedtext transition-colors hover:text-ph-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ph-focus disabled:opacity-40",
|
|
1696
|
+
children: revealed ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_iconoir_react.EyeClosed, { className: "h-4 w-4", "aria-hidden": true }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_iconoir_react.Eye, { className: "h-4 w-4", "aria-hidden": true })
|
|
1697
|
+
}
|
|
1698
|
+
) : null
|
|
1699
|
+
] })
|
|
1618
1700
|
}
|
|
1619
1701
|
);
|
|
1620
1702
|
});
|
|
@@ -1752,7 +1834,7 @@ var Checkbox = (0, import_react10.forwardRef)(function Checkbox2(_a, ref) {
|
|
|
1752
1834
|
type: "checkbox",
|
|
1753
1835
|
disabled,
|
|
1754
1836
|
"aria-invalid": hasError || void 0,
|
|
1755
|
-
"aria-describedby": joinIds(ariaDescribedBy, descriptionId),
|
|
1837
|
+
"aria-describedby": joinIds(ariaDescribedBy, descriptionId, errorId),
|
|
1756
1838
|
"aria-errormessage": errorId,
|
|
1757
1839
|
className: cn(
|
|
1758
1840
|
"ph-checkbox",
|
|
@@ -1912,6 +1994,7 @@ function Modal({
|
|
|
1912
1994
|
footer,
|
|
1913
1995
|
size = "md",
|
|
1914
1996
|
className,
|
|
1997
|
+
bodyClassName,
|
|
1915
1998
|
customLayout = false,
|
|
1916
1999
|
showCloseButton = true,
|
|
1917
2000
|
closeOnOutsideClick = true,
|
|
@@ -1984,7 +2067,7 @@ function Modal({
|
|
|
1984
2067
|
}
|
|
1985
2068
|
) }) : null
|
|
1986
2069
|
] }) : null,
|
|
1987
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "ph-modal-body", children }),
|
|
2070
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: cn("ph-modal-body", bodyClassName), children }),
|
|
1988
2071
|
footer ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "ph-modal-footer", children: footer }) : null
|
|
1989
2072
|
] })
|
|
1990
2073
|
})
|
|
@@ -2112,14 +2195,25 @@ function Table({
|
|
|
2112
2195
|
compact = false,
|
|
2113
2196
|
ribbon = false,
|
|
2114
2197
|
getRowStyle,
|
|
2198
|
+
getRowKey,
|
|
2115
2199
|
className,
|
|
2116
2200
|
caption
|
|
2117
2201
|
}) {
|
|
2118
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2202
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2203
|
+
"div",
|
|
2204
|
+
{
|
|
2205
|
+
className: cn("ph-table-wrap", compact && "ph-table-compact", className),
|
|
2206
|
+
tabIndex: 0,
|
|
2207
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("table", { className: cn("ph-table", zebra && "ph-table-zebra", ribbon && "ph-table--ribbon"), children: [
|
|
2208
|
+
caption && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("caption", { className: "sr-only", children: caption }),
|
|
2209
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("tr", { children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("th", { className: col.className, children: col.header }, col.key)) }) }),
|
|
2210
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("tbody", { children: data.map((row, i) => {
|
|
2211
|
+
var _a;
|
|
2212
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("tr", { style: getRowStyle == null ? void 0 : getRowStyle(row), children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("td", { className: col.className, children: col.cell(row) }, col.key)) }, (_a = getRowKey == null ? void 0 : getRowKey(row, i)) != null ? _a : i);
|
|
2213
|
+
}) })
|
|
2214
|
+
] })
|
|
2215
|
+
}
|
|
2216
|
+
);
|
|
2123
2217
|
}
|
|
2124
2218
|
|
|
2125
2219
|
// src/components/ui/Stat.tsx
|
|
@@ -2129,14 +2223,14 @@ var toneMap = {
|
|
|
2129
2223
|
brand: "text-ph-brand",
|
|
2130
2224
|
blue: "text-ph-blue",
|
|
2131
2225
|
purple: "text-ph-purple",
|
|
2132
|
-
warning: "text-
|
|
2226
|
+
warning: "text-ph-warning"
|
|
2133
2227
|
};
|
|
2134
2228
|
var statMap = {
|
|
2135
2229
|
default: "",
|
|
2136
2230
|
brand: "",
|
|
2137
2231
|
blue: "",
|
|
2138
2232
|
purple: "",
|
|
2139
|
-
warning: "border-
|
|
2233
|
+
warning: "border-[color:color-mix(in_srgb,var(--ph-warning)_30%,var(--ph-border))] bg-[color:color-mix(in_srgb,var(--ph-warning)_10%,var(--ph-surface))]"
|
|
2140
2234
|
};
|
|
2141
2235
|
function Stat(_a) {
|
|
2142
2236
|
var _b = _a, { icon, label, value, footer, tone = "default", className } = _b, props = __objRest(_b, ["icon", "label", "value", "footer", "tone", "className"]);
|
|
@@ -2156,17 +2250,17 @@ var DEFAULT_THEME_ID = "hedgehog-light";
|
|
|
2156
2250
|
var THEMES = [
|
|
2157
2251
|
{
|
|
2158
2252
|
id: "hedgehog-light",
|
|
2159
|
-
name: "
|
|
2253
|
+
name: "Hedgehog Light",
|
|
2160
2254
|
description: "Default Quill warm greys and orange Lemon chrome.",
|
|
2161
2255
|
colorScheme: "light",
|
|
2162
|
-
group: "
|
|
2256
|
+
group: "Hedgehog"
|
|
2163
2257
|
},
|
|
2164
2258
|
{
|
|
2165
2259
|
id: "hedgehog-dark",
|
|
2166
|
-
name: "
|
|
2260
|
+
name: "Hedgehog Dark",
|
|
2167
2261
|
description: "Dark app shell with HedgeHog orange accents.",
|
|
2168
2262
|
colorScheme: "dark",
|
|
2169
|
-
group: "
|
|
2263
|
+
group: "Hedgehog"
|
|
2170
2264
|
},
|
|
2171
2265
|
{
|
|
2172
2266
|
id: "note",
|
|
@@ -2251,6 +2345,20 @@ var THEMES = [
|
|
|
2251
2345
|
description: "Deep plum command deck with hot pink, lime, cyan, and sunset signals.",
|
|
2252
2346
|
colorScheme: "dark",
|
|
2253
2347
|
group: "Malibu"
|
|
2348
|
+
},
|
|
2349
|
+
{
|
|
2350
|
+
id: "microsoft-light",
|
|
2351
|
+
name: "Microsoft Light",
|
|
2352
|
+
description: "Office Fluent light neutrals on white with the signature brand blue.",
|
|
2353
|
+
colorScheme: "light",
|
|
2354
|
+
group: "Microsoft"
|
|
2355
|
+
},
|
|
2356
|
+
{
|
|
2357
|
+
id: "microsoft-dark",
|
|
2358
|
+
name: "Microsoft Dark",
|
|
2359
|
+
description: "Office Fluent dark chrome with a bright brand-blue accent.",
|
|
2360
|
+
colorScheme: "dark",
|
|
2361
|
+
group: "Microsoft"
|
|
2254
2362
|
}
|
|
2255
2363
|
];
|
|
2256
2364
|
var THEME_GROUPS = Array.from(
|
|
@@ -2329,6 +2437,7 @@ function Accordion({
|
|
|
2329
2437
|
className
|
|
2330
2438
|
}) {
|
|
2331
2439
|
const [openItems, setOpenItems] = (0, import_react15.useState)(new Set(defaultOpen));
|
|
2440
|
+
const idPrefix = (0, import_react15.useId)();
|
|
2332
2441
|
const toggleItem = (id) => {
|
|
2333
2442
|
setOpenItems((prev) => {
|
|
2334
2443
|
const next = new Set(prev);
|
|
@@ -2343,41 +2452,58 @@ function Accordion({
|
|
|
2343
2452
|
return next;
|
|
2344
2453
|
});
|
|
2345
2454
|
};
|
|
2346
|
-
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
"
|
|
2351
|
-
|
|
2352
|
-
type: "button",
|
|
2353
|
-
onClick: () => toggleItem(item.id),
|
|
2354
|
-
className: "flex w-full items-center justify-between px-5 py-4 text-left transition hover:bg-ph-muted",
|
|
2355
|
-
children: [
|
|
2356
|
-
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "font-semibold text-ph-ink", children: item.title }),
|
|
2357
|
-
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2358
|
-
IconChevronDown,
|
|
2359
|
-
{
|
|
2360
|
-
className: cn(
|
|
2361
|
-
"h-5 w-5 text-ph-mutedtext transition-transform duration-200",
|
|
2362
|
-
isOpen && "rotate-180"
|
|
2363
|
-
)
|
|
2364
|
-
}
|
|
2365
|
-
)
|
|
2366
|
-
]
|
|
2367
|
-
}
|
|
2455
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2456
|
+
"div",
|
|
2457
|
+
{
|
|
2458
|
+
className: cn(
|
|
2459
|
+
"divide-y divide-ph-border rounded-xl border border-ph-border bg-ph-surface",
|
|
2460
|
+
className
|
|
2368
2461
|
),
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
{
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2462
|
+
children: items.map((item) => {
|
|
2463
|
+
const isOpen = openItems.has(item.id);
|
|
2464
|
+
const contentId = `accordion-${idPrefix}-${item.id}-content`;
|
|
2465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "first:rounded-t-xl last:rounded-b-xl", children: [
|
|
2466
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
2467
|
+
"button",
|
|
2468
|
+
{
|
|
2469
|
+
type: "button",
|
|
2470
|
+
onClick: () => toggleItem(item.id),
|
|
2471
|
+
"aria-expanded": isOpen,
|
|
2472
|
+
"aria-controls": contentId,
|
|
2473
|
+
className: "flex w-full items-center justify-between px-5 py-4 text-left transition hover:bg-ph-muted",
|
|
2474
|
+
children: [
|
|
2475
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "font-semibold text-ph-ink", children: item.title }),
|
|
2476
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2477
|
+
IconChevronDown,
|
|
2478
|
+
{
|
|
2479
|
+
className: cn(
|
|
2480
|
+
"h-5 w-5 text-ph-mutedtext transition-transform duration-200",
|
|
2481
|
+
isOpen && "rotate-180"
|
|
2482
|
+
)
|
|
2483
|
+
}
|
|
2484
|
+
)
|
|
2485
|
+
]
|
|
2486
|
+
}
|
|
2375
2487
|
),
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2488
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2489
|
+
"div",
|
|
2490
|
+
{
|
|
2491
|
+
id: contentId,
|
|
2492
|
+
"aria-hidden": !isOpen,
|
|
2493
|
+
ref: (node) => {
|
|
2494
|
+
if (node) node.toggleAttribute("inert", !isOpen);
|
|
2495
|
+
},
|
|
2496
|
+
className: cn(
|
|
2497
|
+
"grid transition-all duration-200",
|
|
2498
|
+
isOpen ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
|
|
2499
|
+
),
|
|
2500
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "px-5 pb-4 text-ph-subtle", children: item.content }) })
|
|
2501
|
+
}
|
|
2502
|
+
)
|
|
2503
|
+
] }, item.id);
|
|
2504
|
+
})
|
|
2505
|
+
}
|
|
2506
|
+
);
|
|
2381
2507
|
}
|
|
2382
2508
|
|
|
2383
2509
|
// src/components/ui/SegmentedControl.tsx
|
|
@@ -2413,6 +2539,7 @@ function SegmentedControl({ options, value, onChange, className }) {
|
|
|
2413
2539
|
|
|
2414
2540
|
// src/components/ui/CommandPalette.tsx
|
|
2415
2541
|
var import_react16 = require("react");
|
|
2542
|
+
var Dialog2 = __toESM(require("@radix-ui/react-dialog"));
|
|
2416
2543
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2417
2544
|
function CommandPalette({
|
|
2418
2545
|
items,
|
|
@@ -2428,136 +2555,143 @@ function CommandPalette({
|
|
|
2428
2555
|
const [query, setQuery] = (0, import_react16.useState)("");
|
|
2429
2556
|
const [selectedIndex, setSelectedIndex] = (0, import_react16.useState)(0);
|
|
2430
2557
|
const inputRef = (0, import_react16.useRef)(null);
|
|
2431
|
-
const
|
|
2432
|
-
const
|
|
2558
|
+
const listboxRef = (0, import_react16.useRef)(null);
|
|
2559
|
+
const restoreFocusRef = (0, import_react16.useRef)(null);
|
|
2560
|
+
const generatedId = (0, import_react16.useId)();
|
|
2561
|
+
const listboxId = `${id != null ? id : `command-palette-${generatedId}`}-listbox`;
|
|
2433
2562
|
const filtered = items.filter(
|
|
2434
2563
|
(item) => item.label.toLowerCase().includes(query.toLowerCase())
|
|
2435
2564
|
);
|
|
2565
|
+
const activeIndex = filtered.length ? Math.min(selectedIndex, filtered.length - 1) : 0;
|
|
2566
|
+
const activeItem = filtered[activeIndex];
|
|
2436
2567
|
(0, import_react16.useEffect)(() => {
|
|
2437
|
-
var _a;
|
|
2438
2568
|
if (!isOpen) return;
|
|
2439
|
-
previousFocusRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
2440
2569
|
setQuery("");
|
|
2441
2570
|
setSelectedIndex(0);
|
|
2442
|
-
(_a = inputRef.current) == null ? void 0 : _a.focus();
|
|
2443
|
-
return () => {
|
|
2444
|
-
var _a2;
|
|
2445
|
-
return (_a2 = previousFocusRef.current) == null ? void 0 : _a2.focus();
|
|
2446
|
-
};
|
|
2447
2571
|
}, [isOpen]);
|
|
2448
2572
|
(0, import_react16.useEffect)(() => {
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
last.focus();
|
|
2481
|
-
} else if (!e.shiftKey && document.activeElement === last) {
|
|
2482
|
-
e.preventDefault();
|
|
2483
|
-
first.focus();
|
|
2484
|
-
}
|
|
2485
|
-
break;
|
|
2486
|
-
}
|
|
2487
|
-
}
|
|
2488
|
-
};
|
|
2489
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
2490
|
-
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
2491
|
-
}, [isOpen, filtered, selectedIndex, onClose]);
|
|
2492
|
-
if (!isOpen) return null;
|
|
2573
|
+
setSelectedIndex((current) => Math.min(current, Math.max(filtered.length - 1, 0)));
|
|
2574
|
+
}, [filtered.length]);
|
|
2575
|
+
(0, import_react16.useEffect)(() => {
|
|
2576
|
+
var _a, _b;
|
|
2577
|
+
if (!isOpen || !activeItem) return;
|
|
2578
|
+
(_b = (_a = listboxRef.current) == null ? void 0 : _a.querySelectorAll('[role="option"]')[activeIndex]) == null ? void 0 : _b.scrollIntoView({ block: "nearest" });
|
|
2579
|
+
}, [activeIndex, activeItem, isOpen]);
|
|
2580
|
+
const handleInputKeyDown = (event) => {
|
|
2581
|
+
switch (event.key) {
|
|
2582
|
+
case "ArrowDown":
|
|
2583
|
+
if (!filtered.length) return;
|
|
2584
|
+
event.preventDefault();
|
|
2585
|
+
setSelectedIndex((current) => (current + 1) % filtered.length);
|
|
2586
|
+
return;
|
|
2587
|
+
case "ArrowUp":
|
|
2588
|
+
if (!filtered.length) return;
|
|
2589
|
+
event.preventDefault();
|
|
2590
|
+
setSelectedIndex(
|
|
2591
|
+
(current) => (current - 1 + filtered.length) % filtered.length
|
|
2592
|
+
);
|
|
2593
|
+
return;
|
|
2594
|
+
case "Enter":
|
|
2595
|
+
if (!activeItem) return;
|
|
2596
|
+
event.preventDefault();
|
|
2597
|
+
activeItem.onSelect();
|
|
2598
|
+
onClose();
|
|
2599
|
+
return;
|
|
2600
|
+
default:
|
|
2601
|
+
return;
|
|
2602
|
+
}
|
|
2603
|
+
};
|
|
2493
2604
|
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2494
|
-
|
|
2605
|
+
Dialog2.Root,
|
|
2495
2606
|
{
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
onMouseDown: (event) => {
|
|
2500
|
-
if (event.target === event.currentTarget) onClose();
|
|
2607
|
+
open: isOpen,
|
|
2608
|
+
onOpenChange: (nextOpen) => {
|
|
2609
|
+
if (!nextOpen) onClose();
|
|
2501
2610
|
},
|
|
2502
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2611
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(Dialog2.Portal, { children: [
|
|
2612
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2613
|
+
Dialog2.Overlay,
|
|
2614
|
+
{
|
|
2615
|
+
id,
|
|
2616
|
+
"data-test": dataTest,
|
|
2617
|
+
className: "fixed inset-0 z-50 bg-black/40 backdrop-blur-sm"
|
|
2618
|
+
}
|
|
2619
|
+
),
|
|
2620
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
2621
|
+
Dialog2.Content,
|
|
2622
|
+
{
|
|
2623
|
+
className: cn(
|
|
2624
|
+
"fixed left-1/2 top-[20vh] z-50 w-full max-w-xl -translate-x-1/2 overflow-hidden rounded-xl border border-ph-border bg-ph-surface shadow-ph-md",
|
|
2625
|
+
className
|
|
2626
|
+
),
|
|
2627
|
+
onOpenAutoFocus: (event) => {
|
|
2628
|
+
var _a;
|
|
2629
|
+
restoreFocusRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
2630
|
+
event.preventDefault();
|
|
2631
|
+
(_a = inputRef.current) == null ? void 0 : _a.focus();
|
|
2632
|
+
},
|
|
2633
|
+
onCloseAutoFocus: (event) => {
|
|
2634
|
+
var _a;
|
|
2635
|
+
event.preventDefault();
|
|
2636
|
+
(_a = restoreFocusRef.current) == null ? void 0 : _a.focus();
|
|
2637
|
+
},
|
|
2638
|
+
children: [
|
|
2639
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Dialog2.Title, { className: "sr-only", children: "Command palette" }),
|
|
2640
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-3 border-b border-ph-border px-4 py-3", children: [
|
|
2641
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IconSearch, { className: "h-5 w-5 text-ph-mutedtext" }),
|
|
2642
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2643
|
+
"input",
|
|
2644
|
+
{
|
|
2645
|
+
ref: inputRef,
|
|
2646
|
+
id: inputId,
|
|
2647
|
+
"data-test": inputDataTest,
|
|
2648
|
+
type: "text",
|
|
2649
|
+
role: "combobox",
|
|
2650
|
+
"aria-label": "Search commands",
|
|
2651
|
+
"aria-autocomplete": "list",
|
|
2652
|
+
"aria-controls": listboxId,
|
|
2653
|
+
"aria-expanded": "true",
|
|
2654
|
+
"aria-activedescendant": activeItem ? `command-${activeItem.id}` : void 0,
|
|
2655
|
+
value: query,
|
|
2656
|
+
onChange: (event) => {
|
|
2657
|
+
setQuery(event.target.value);
|
|
2658
|
+
setSelectedIndex(0);
|
|
2659
|
+
},
|
|
2660
|
+
onKeyDown: handleInputKeyDown,
|
|
2661
|
+
placeholder,
|
|
2662
|
+
className: "flex-1 bg-transparent text-ph-ink outline-none placeholder:text-ph-mutedtext"
|
|
2663
|
+
}
|
|
2664
|
+
),
|
|
2665
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("kbd", { "aria-hidden": "true", className: "rounded border border-ph-border bg-ph-muted px-1.5 py-0.5 text-xs text-ph-mutedtext", children: "ESC" })
|
|
2666
|
+
] }),
|
|
2667
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: listboxRef, id: listboxId, role: "listbox", "aria-label": "Commands", className: "max-h-[50vh] overflow-y-auto py-2", children: filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { role: "status", className: "px-4 py-8 text-center text-sm text-ph-mutedtext", children: "No results found." }) : filtered.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
2668
|
+
"div",
|
|
2518
2669
|
{
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
"
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
setQuery(e.target.value);
|
|
2527
|
-
setSelectedIndex(0);
|
|
2670
|
+
id: `command-${item.id}`,
|
|
2671
|
+
"data-test": `command-${item.id}`,
|
|
2672
|
+
role: "option",
|
|
2673
|
+
"aria-selected": index === activeIndex,
|
|
2674
|
+
onClick: () => {
|
|
2675
|
+
item.onSelect();
|
|
2676
|
+
onClose();
|
|
2528
2677
|
},
|
|
2529
|
-
|
|
2530
|
-
className:
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
id: `command-${item.id}`,
|
|
2540
|
-
"data-test": `command-${item.id}`,
|
|
2541
|
-
onClick: () => {
|
|
2542
|
-
item.onSelect();
|
|
2543
|
-
onClose();
|
|
2678
|
+
onMouseEnter: () => setSelectedIndex(index),
|
|
2679
|
+
className: cn(
|
|
2680
|
+
"flex w-full cursor-pointer items-center gap-3 px-4 py-2.5 text-left text-sm transition-colors",
|
|
2681
|
+
index === activeIndex ? "bg-ph-muted text-ph-ink" : "text-ph-subtle"
|
|
2682
|
+
),
|
|
2683
|
+
children: [
|
|
2684
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { "aria-hidden": "true", className: "h-5 w-5", children: item.icon }),
|
|
2685
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "flex-1", children: item.label }),
|
|
2686
|
+
item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("kbd", { "aria-hidden": "true", className: "rounded border border-ph-border bg-ph-surface px-1.5 py-0.5 text-xs text-ph-mutedtext", children: item.shortcut })
|
|
2687
|
+
]
|
|
2544
2688
|
},
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
item.icon && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "h-5 w-5", children: item.icon }),
|
|
2552
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "flex-1", children: item.label }),
|
|
2553
|
-
item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("kbd", { className: "rounded border border-ph-border bg-ph-surface px-1.5 py-0.5 text-xs text-ph-mutedtext", children: item.shortcut })
|
|
2554
|
-
]
|
|
2555
|
-
},
|
|
2556
|
-
item.id
|
|
2557
|
-
)) })
|
|
2558
|
-
]
|
|
2559
|
-
}
|
|
2560
|
-
)
|
|
2689
|
+
item.id
|
|
2690
|
+
)) })
|
|
2691
|
+
]
|
|
2692
|
+
}
|
|
2693
|
+
)
|
|
2694
|
+
] })
|
|
2561
2695
|
}
|
|
2562
2696
|
);
|
|
2563
2697
|
}
|
|
@@ -2565,46 +2699,142 @@ function CommandPalette({
|
|
|
2565
2699
|
// src/components/ui/Calendar.tsx
|
|
2566
2700
|
var import_react17 = require("react");
|
|
2567
2701
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2702
|
+
var monthNames = [
|
|
2703
|
+
"January",
|
|
2704
|
+
"February",
|
|
2705
|
+
"March",
|
|
2706
|
+
"April",
|
|
2707
|
+
"May",
|
|
2708
|
+
"June",
|
|
2709
|
+
"July",
|
|
2710
|
+
"August",
|
|
2711
|
+
"September",
|
|
2712
|
+
"October",
|
|
2713
|
+
"November",
|
|
2714
|
+
"December"
|
|
2715
|
+
];
|
|
2716
|
+
var weekDays = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
2717
|
+
var fullWeekDays = [
|
|
2718
|
+
"Sunday",
|
|
2719
|
+
"Monday",
|
|
2720
|
+
"Tuesday",
|
|
2721
|
+
"Wednesday",
|
|
2722
|
+
"Thursday",
|
|
2723
|
+
"Friday",
|
|
2724
|
+
"Saturday"
|
|
2725
|
+
];
|
|
2726
|
+
function startOfDay(date) {
|
|
2727
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
2728
|
+
}
|
|
2729
|
+
function startOfMonth(date) {
|
|
2730
|
+
return new Date(date.getFullYear(), date.getMonth(), 1);
|
|
2731
|
+
}
|
|
2732
|
+
function isSameDay(first, second) {
|
|
2733
|
+
return first.getFullYear() === second.getFullYear() && first.getMonth() === second.getMonth() && first.getDate() === second.getDate();
|
|
2734
|
+
}
|
|
2735
|
+
function addDays(date, amount) {
|
|
2736
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + amount);
|
|
2737
|
+
}
|
|
2738
|
+
function addMonths(date, amount) {
|
|
2739
|
+
const targetMonth = new Date(date.getFullYear(), date.getMonth() + amount, 1);
|
|
2740
|
+
const lastDay = new Date(
|
|
2741
|
+
targetMonth.getFullYear(),
|
|
2742
|
+
targetMonth.getMonth() + 1,
|
|
2743
|
+
0
|
|
2744
|
+
).getDate();
|
|
2745
|
+
return new Date(
|
|
2746
|
+
targetMonth.getFullYear(),
|
|
2747
|
+
targetMonth.getMonth(),
|
|
2748
|
+
Math.min(date.getDate(), lastDay)
|
|
2749
|
+
);
|
|
2750
|
+
}
|
|
2751
|
+
function dateKey(date) {
|
|
2752
|
+
return `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;
|
|
2753
|
+
}
|
|
2754
|
+
function dateLabel(date) {
|
|
2755
|
+
return `${fullWeekDays[date.getDay()]}, ${date.getDate()} ${monthNames[date.getMonth()]} ${date.getFullYear()}`;
|
|
2756
|
+
}
|
|
2568
2757
|
function Calendar({ value, onChange, className }) {
|
|
2569
|
-
const [currentMonth, setCurrentMonth] = (0, import_react17.useState)(value
|
|
2570
|
-
const
|
|
2758
|
+
const [currentMonth, setCurrentMonth] = (0, import_react17.useState)(() => startOfMonth(value != null ? value : /* @__PURE__ */ new Date()));
|
|
2759
|
+
const [focusedDate, setFocusedDate] = (0, import_react17.useState)(() => startOfDay(value != null ? value : /* @__PURE__ */ new Date()));
|
|
2760
|
+
const gridRef = (0, import_react17.useRef)(null);
|
|
2761
|
+
const shouldFocusDateRef = (0, import_react17.useRef)(false);
|
|
2762
|
+
const monthLabelId = (0, import_react17.useId)();
|
|
2763
|
+
const today = startOfDay(/* @__PURE__ */ new Date());
|
|
2764
|
+
(0, import_react17.useEffect)(() => {
|
|
2765
|
+
if (!value) return;
|
|
2766
|
+
const nextDate = startOfDay(value);
|
|
2767
|
+
setCurrentMonth(startOfMonth(nextDate));
|
|
2768
|
+
setFocusedDate(nextDate);
|
|
2769
|
+
}, [value]);
|
|
2770
|
+
(0, import_react17.useEffect)(() => {
|
|
2771
|
+
var _a, _b;
|
|
2772
|
+
if (!shouldFocusDateRef.current) return;
|
|
2773
|
+
(_b = (_a = gridRef.current) == null ? void 0 : _a.querySelector(`[data-date="${dateKey(focusedDate)}"]`)) == null ? void 0 : _b.focus();
|
|
2774
|
+
shouldFocusDateRef.current = false;
|
|
2775
|
+
}, [currentMonth, focusedDate]);
|
|
2571
2776
|
const year = currentMonth.getFullYear();
|
|
2572
2777
|
const month = currentMonth.getMonth();
|
|
2573
|
-
const
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
const monthNames = [
|
|
2578
|
-
"January",
|
|
2579
|
-
"February",
|
|
2580
|
-
"March",
|
|
2581
|
-
"April",
|
|
2582
|
-
"May",
|
|
2583
|
-
"June",
|
|
2584
|
-
"July",
|
|
2585
|
-
"August",
|
|
2586
|
-
"September",
|
|
2587
|
-
"October",
|
|
2588
|
-
"November",
|
|
2589
|
-
"December"
|
|
2590
|
-
];
|
|
2591
|
-
const weekDays = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
2592
|
-
const isSelected = (day) => {
|
|
2593
|
-
if (!value) return false;
|
|
2594
|
-
return value.getDate() === day && value.getMonth() === month && value.getFullYear() === year;
|
|
2778
|
+
const changeMonth = (amount) => {
|
|
2779
|
+
const nextDate = addMonths(focusedDate, amount);
|
|
2780
|
+
setFocusedDate(nextDate);
|
|
2781
|
+
setCurrentMonth(startOfMonth(nextDate));
|
|
2595
2782
|
};
|
|
2596
|
-
const
|
|
2597
|
-
|
|
2783
|
+
const moveFocus = (nextDate) => {
|
|
2784
|
+
shouldFocusDateRef.current = true;
|
|
2785
|
+
setFocusedDate(nextDate);
|
|
2786
|
+
setCurrentMonth(startOfMonth(nextDate));
|
|
2598
2787
|
};
|
|
2599
|
-
const handleSelect = (
|
|
2600
|
-
|
|
2788
|
+
const handleSelect = (date) => {
|
|
2789
|
+
setFocusedDate(date);
|
|
2790
|
+
onChange == null ? void 0 : onChange(startOfDay(date));
|
|
2601
2791
|
};
|
|
2602
|
-
const
|
|
2603
|
-
|
|
2604
|
-
|
|
2792
|
+
const handleDayKeyDown = (event, date) => {
|
|
2793
|
+
let nextDate;
|
|
2794
|
+
switch (event.key) {
|
|
2795
|
+
case "ArrowLeft":
|
|
2796
|
+
nextDate = addDays(date, -1);
|
|
2797
|
+
break;
|
|
2798
|
+
case "ArrowRight":
|
|
2799
|
+
nextDate = addDays(date, 1);
|
|
2800
|
+
break;
|
|
2801
|
+
case "ArrowUp":
|
|
2802
|
+
nextDate = addDays(date, -7);
|
|
2803
|
+
break;
|
|
2804
|
+
case "ArrowDown":
|
|
2805
|
+
nextDate = addDays(date, 7);
|
|
2806
|
+
break;
|
|
2807
|
+
case "Home":
|
|
2808
|
+
nextDate = addDays(date, -date.getDay());
|
|
2809
|
+
break;
|
|
2810
|
+
case "End":
|
|
2811
|
+
nextDate = addDays(date, 6 - date.getDay());
|
|
2812
|
+
break;
|
|
2813
|
+
case "PageUp":
|
|
2814
|
+
nextDate = addMonths(date, event.shiftKey ? -12 : -1);
|
|
2815
|
+
break;
|
|
2816
|
+
case "PageDown":
|
|
2817
|
+
nextDate = addMonths(date, event.shiftKey ? 12 : 1);
|
|
2818
|
+
break;
|
|
2819
|
+
case "Enter":
|
|
2820
|
+
case " ":
|
|
2821
|
+
event.preventDefault();
|
|
2822
|
+
handleSelect(date);
|
|
2823
|
+
return;
|
|
2824
|
+
default:
|
|
2825
|
+
return;
|
|
2826
|
+
}
|
|
2827
|
+
event.preventDefault();
|
|
2828
|
+
moveFocus(nextDate);
|
|
2829
|
+
};
|
|
2830
|
+
const firstDay = new Date(year, month, 1).getDay();
|
|
2831
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
2832
|
+
const days = Array.from({ length: firstDay }, () => null);
|
|
2833
|
+
for (let day = 1; day <= daysInMonth; day++) {
|
|
2834
|
+
days.push(new Date(year, month, day));
|
|
2605
2835
|
}
|
|
2606
|
-
|
|
2607
|
-
days.push(
|
|
2836
|
+
while (days.length < 42) {
|
|
2837
|
+
days.push(null);
|
|
2608
2838
|
}
|
|
2609
2839
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn("w-[280px] rounded-xl border border-ph-border bg-ph-surface p-4 shadow-ph", className), children: [
|
|
2610
2840
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "mb-4 flex items-center justify-between", children: [
|
|
@@ -2612,13 +2842,13 @@ function Calendar({ value, onChange, className }) {
|
|
|
2612
2842
|
"button",
|
|
2613
2843
|
{
|
|
2614
2844
|
type: "button",
|
|
2615
|
-
onClick:
|
|
2845
|
+
onClick: () => changeMonth(-1),
|
|
2616
2846
|
"aria-label": "Previous month",
|
|
2617
2847
|
className: "rounded-lg p-1 text-ph-subtle transition hover:bg-ph-muted hover:text-ph-ink",
|
|
2618
2848
|
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(IconChevronLeft, { className: "h-5 w-5", "aria-hidden": true })
|
|
2619
2849
|
}
|
|
2620
2850
|
),
|
|
2621
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "text-sm font-semibold text-ph-ink", children: [
|
|
2851
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { id: monthLabelId, "aria-live": "polite", className: "text-sm font-semibold text-ph-ink", children: [
|
|
2622
2852
|
monthNames[month],
|
|
2623
2853
|
" ",
|
|
2624
2854
|
year
|
|
@@ -2627,27 +2857,56 @@ function Calendar({ value, onChange, className }) {
|
|
|
2627
2857
|
"button",
|
|
2628
2858
|
{
|
|
2629
2859
|
type: "button",
|
|
2630
|
-
onClick:
|
|
2860
|
+
onClick: () => changeMonth(1),
|
|
2631
2861
|
"aria-label": "Next month",
|
|
2632
2862
|
className: "rounded-lg p-1 text-ph-subtle transition hover:bg-ph-muted hover:text-ph-ink",
|
|
2633
2863
|
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(IconChevronRight, { className: "h-5 w-5", "aria-hidden": true })
|
|
2634
2864
|
}
|
|
2635
2865
|
)
|
|
2636
2866
|
] }),
|
|
2637
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", {
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
"button",
|
|
2867
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { ref: gridRef, role: "grid", "aria-labelledby": monthLabelId, children: [
|
|
2868
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { role: "row", className: "grid grid-cols-7 gap-1", children: weekDays.map((day, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2869
|
+
"div",
|
|
2641
2870
|
{
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
className:
|
|
2645
|
-
"flex h-full w-full items-center justify-center rounded-lg text-sm transition-colors",
|
|
2646
|
-
isSelected(day) ? "bg-ph-brand font-semibold text-[var(--ph-on-accent)] shadow-ph" : isToday(day) ? "bg-ph-muted font-semibold text-ph-brand ring-1 ring-ph-brand/30" : "text-ph-ink hover:bg-ph-muted"
|
|
2647
|
-
),
|
|
2871
|
+
role: "columnheader",
|
|
2872
|
+
"aria-label": fullWeekDays[index],
|
|
2873
|
+
className: "py-1 text-center text-xs font-medium text-ph-mutedtext",
|
|
2648
2874
|
children: day
|
|
2649
|
-
}
|
|
2650
|
-
|
|
2875
|
+
},
|
|
2876
|
+
day
|
|
2877
|
+
)) }),
|
|
2878
|
+
Array.from({ length: 6 }, (_, week) => {
|
|
2879
|
+
const weekDates = days.slice(week * 7, week * 7 + 7);
|
|
2880
|
+
if (weekDates.length === 0 || weekDates.every((date) => !date)) return null;
|
|
2881
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { role: "row", className: "grid grid-cols-7 gap-1", children: weekDates.map(
|
|
2882
|
+
(date, day) => date ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2883
|
+
"div",
|
|
2884
|
+
{
|
|
2885
|
+
role: "gridcell",
|
|
2886
|
+
"aria-selected": value ? isSameDay(value, date) : false,
|
|
2887
|
+
className: "aspect-square",
|
|
2888
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2889
|
+
"button",
|
|
2890
|
+
{
|
|
2891
|
+
type: "button",
|
|
2892
|
+
"data-date": dateKey(date),
|
|
2893
|
+
"aria-label": dateLabel(date),
|
|
2894
|
+
"aria-current": isSameDay(today, date) ? "date" : void 0,
|
|
2895
|
+
tabIndex: isSameDay(focusedDate, date) ? 0 : -1,
|
|
2896
|
+
onClick: () => handleSelect(date),
|
|
2897
|
+
onKeyDown: (event) => handleDayKeyDown(event, date),
|
|
2898
|
+
className: cn(
|
|
2899
|
+
"flex h-full w-full items-center justify-center rounded-lg text-sm transition-colors",
|
|
2900
|
+
value && isSameDay(value, date) ? "bg-ph-brand font-semibold text-[var(--ph-on-accent)] shadow-ph" : isSameDay(today, date) ? "bg-ph-muted font-semibold text-ph-brand ring-1 ring-ph-brand/30" : "text-ph-ink hover:bg-ph-muted"
|
|
2901
|
+
),
|
|
2902
|
+
children: date.getDate()
|
|
2903
|
+
}
|
|
2904
|
+
)
|
|
2905
|
+
},
|
|
2906
|
+
dateKey(date)
|
|
2907
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { role: "gridcell", "aria-hidden": "true", className: "aspect-square" }, `empty-${week}-${day}`)
|
|
2908
|
+
) }, week);
|
|
2909
|
+
})
|
|
2651
2910
|
] })
|
|
2652
2911
|
] });
|
|
2653
2912
|
}
|
|
@@ -2663,31 +2922,15 @@ function TooltipProvider({
|
|
|
2663
2922
|
}) {
|
|
2664
2923
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TooltipDelayContext.Provider, { value: delayDuration, children });
|
|
2665
2924
|
}
|
|
2666
|
-
function tooltipPosition(trigger, side, align, offset) {
|
|
2925
|
+
function tooltipPosition(trigger, content, side, align, offset, collisionPadding) {
|
|
2667
2926
|
const horizontal = align === "start" ? trigger.left : align === "end" ? trigger.right : trigger.left + trigger.width / 2;
|
|
2668
2927
|
const vertical = align === "start" ? trigger.top : align === "end" ? trigger.bottom : trigger.top + trigger.height / 2;
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
top: trigger.top - offset,
|
|
2673
|
-
transform: "translate(-50%, -100%)"
|
|
2674
|
-
};
|
|
2675
|
-
if (side === "bottom")
|
|
2676
|
-
return {
|
|
2677
|
-
left: horizontal,
|
|
2678
|
-
top: trigger.bottom + offset,
|
|
2679
|
-
transform: "translate(-50%, 0)"
|
|
2680
|
-
};
|
|
2681
|
-
if (side === "left")
|
|
2682
|
-
return {
|
|
2683
|
-
left: trigger.left - offset,
|
|
2684
|
-
top: vertical,
|
|
2685
|
-
transform: "translate(-100%, -50%)"
|
|
2686
|
-
};
|
|
2928
|
+
const position = side === "top" ? { left: horizontal - content.width / 2, top: trigger.top - offset - content.height } : side === "bottom" ? { left: horizontal - content.width / 2, top: trigger.bottom + offset } : side === "left" ? { left: trigger.left - offset - content.width, top: vertical - content.height / 2 } : { left: trigger.right + offset, top: vertical - content.height / 2 };
|
|
2929
|
+
const maxLeft = Math.max(collisionPadding, window.innerWidth - content.width - collisionPadding);
|
|
2930
|
+
const maxTop = Math.max(collisionPadding, window.innerHeight - content.height - collisionPadding);
|
|
2687
2931
|
return {
|
|
2688
|
-
left:
|
|
2689
|
-
top:
|
|
2690
|
-
transform: "translate(0, -50%)"
|
|
2932
|
+
left: Math.min(Math.max(position.left, collisionPadding), maxLeft),
|
|
2933
|
+
top: Math.min(Math.max(position.top, collisionPadding), maxTop)
|
|
2691
2934
|
};
|
|
2692
2935
|
}
|
|
2693
2936
|
function Tooltip({
|
|
@@ -2696,15 +2939,18 @@ function Tooltip({
|
|
|
2696
2939
|
side = "top",
|
|
2697
2940
|
align = "center",
|
|
2698
2941
|
sideOffset = 7,
|
|
2942
|
+
collisionPadding = 8,
|
|
2699
2943
|
className,
|
|
2700
2944
|
open,
|
|
2701
2945
|
defaultOpen = false,
|
|
2702
2946
|
onOpenChange,
|
|
2703
|
-
delayDuration
|
|
2947
|
+
delayDuration,
|
|
2948
|
+
disableHoverableContent = false
|
|
2704
2949
|
}) {
|
|
2705
2950
|
const providerDelay = (0, import_react18.useContext)(TooltipDelayContext);
|
|
2706
2951
|
const generatedId = (0, import_react18.useId)().replace(/:/g, "");
|
|
2707
2952
|
const triggerRef = (0, import_react18.useRef)(null);
|
|
2953
|
+
const contentRef = (0, import_react18.useRef)(null);
|
|
2708
2954
|
const timerRef = (0, import_react18.useRef)(null);
|
|
2709
2955
|
const [internalOpen, setInternalOpen] = (0, import_react18.useState)(defaultOpen);
|
|
2710
2956
|
const [position, setPosition] = (0, import_react18.useState)(null);
|
|
@@ -2719,17 +2965,19 @@ function Tooltip({
|
|
|
2719
2965
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
2720
2966
|
timerRef.current = null;
|
|
2721
2967
|
}
|
|
2722
|
-
|
|
2723
|
-
if (!triggerRef.current) return;
|
|
2968
|
+
const updatePosition = (0, import_react18.useCallback)(() => {
|
|
2969
|
+
if (!triggerRef.current || !contentRef.current) return;
|
|
2724
2970
|
setPosition(
|
|
2725
2971
|
tooltipPosition(
|
|
2726
2972
|
triggerRef.current.getBoundingClientRect(),
|
|
2973
|
+
contentRef.current.getBoundingClientRect(),
|
|
2727
2974
|
side,
|
|
2728
2975
|
align,
|
|
2729
|
-
sideOffset
|
|
2976
|
+
sideOffset,
|
|
2977
|
+
collisionPadding
|
|
2730
2978
|
)
|
|
2731
2979
|
);
|
|
2732
|
-
}
|
|
2980
|
+
}, [align, collisionPadding, side, sideOffset]);
|
|
2733
2981
|
function show(immediate) {
|
|
2734
2982
|
clearTimer();
|
|
2735
2983
|
updatePosition();
|
|
@@ -2741,6 +2989,17 @@ function Tooltip({
|
|
|
2741
2989
|
clearTimer();
|
|
2742
2990
|
setOpen(false);
|
|
2743
2991
|
}
|
|
2992
|
+
function hideFromTrigger() {
|
|
2993
|
+
if (disableHoverableContent) {
|
|
2994
|
+
hide();
|
|
2995
|
+
return;
|
|
2996
|
+
}
|
|
2997
|
+
clearTimer();
|
|
2998
|
+
timerRef.current = setTimeout(() => setOpen(false), 100);
|
|
2999
|
+
}
|
|
3000
|
+
(0, import_react18.useLayoutEffect)(() => {
|
|
3001
|
+
if (isOpen) updatePosition();
|
|
3002
|
+
}, [isOpen, updatePosition]);
|
|
2744
3003
|
(0, import_react18.useEffect)(() => {
|
|
2745
3004
|
if (!isOpen) return;
|
|
2746
3005
|
const reposition = () => updatePosition();
|
|
@@ -2750,7 +3009,7 @@ function Tooltip({
|
|
|
2750
3009
|
window.removeEventListener("resize", reposition);
|
|
2751
3010
|
window.removeEventListener("scroll", reposition, true);
|
|
2752
3011
|
};
|
|
2753
|
-
});
|
|
3012
|
+
}, [isOpen, updatePosition]);
|
|
2754
3013
|
(0, import_react18.useEffect)(() => () => clearTimer(), []);
|
|
2755
3014
|
const describedBy = [children.props["aria-describedby"], tooltipId].filter(Boolean).join(" ");
|
|
2756
3015
|
const trigger = (0, import_react18.cloneElement)(children, { "aria-describedby": describedBy });
|
|
@@ -2761,7 +3020,7 @@ function Tooltip({
|
|
|
2761
3020
|
ref: triggerRef,
|
|
2762
3021
|
className: "inline-flex",
|
|
2763
3022
|
onMouseEnter: () => show(false),
|
|
2764
|
-
onMouseLeave:
|
|
3023
|
+
onMouseLeave: hideFromTrigger,
|
|
2765
3024
|
onFocusCapture: () => show(true),
|
|
2766
3025
|
onBlurCapture: hide,
|
|
2767
3026
|
onKeyDown: (event) => {
|
|
@@ -2770,19 +3029,26 @@ function Tooltip({
|
|
|
2770
3029
|
children: trigger
|
|
2771
3030
|
}
|
|
2772
3031
|
),
|
|
2773
|
-
isOpen &&
|
|
3032
|
+
isOpen && typeof document !== "undefined" ? (0, import_react_dom.createPortal)(
|
|
2774
3033
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2775
3034
|
"span",
|
|
2776
3035
|
{
|
|
2777
|
-
style: __spreadValues({ position: "fixed" }, position),
|
|
3036
|
+
style: __spreadProps(__spreadValues({ position: "fixed" }, position), { visibility: position ? void 0 : "hidden" }),
|
|
2778
3037
|
className: "pointer-events-none z-[200]",
|
|
2779
3038
|
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2780
3039
|
"span",
|
|
2781
3040
|
{
|
|
3041
|
+
ref: contentRef,
|
|
2782
3042
|
id: tooltipId,
|
|
2783
3043
|
role: "tooltip",
|
|
2784
3044
|
"data-side": side,
|
|
2785
|
-
className: cn(
|
|
3045
|
+
className: cn(
|
|
3046
|
+
"ph-tooltip-content",
|
|
3047
|
+
!disableHoverableContent && "pointer-events-auto",
|
|
3048
|
+
className
|
|
3049
|
+
),
|
|
3050
|
+
onMouseEnter: disableHoverableContent ? void 0 : clearTimer,
|
|
3051
|
+
onMouseLeave: disableHoverableContent ? void 0 : hide,
|
|
2786
3052
|
children: content
|
|
2787
3053
|
}
|
|
2788
3054
|
)
|
|
@@ -2805,7 +3071,7 @@ function EmptyState({ icon, title, description, action, className }) {
|
|
|
2805
3071
|
),
|
|
2806
3072
|
children: [
|
|
2807
3073
|
icon && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mb-4 flex h-14 w-14 items-center justify-center rounded-full bg-ph-muted text-ph-mutedtext", children: icon }),
|
|
2808
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("
|
|
3074
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h2", { className: "text-base font-semibold text-ph-ink", children: title }),
|
|
2809
3075
|
description && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "mt-1 max-w-sm text-sm text-ph-subtle", children: description }),
|
|
2810
3076
|
action && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mt-4", children: action })
|
|
2811
3077
|
]
|
|
@@ -3174,7 +3440,12 @@ var titleIdMap = {
|
|
|
3174
3440
|
// src/components/ui/CollapsibleSection.tsx
|
|
3175
3441
|
var import_react21 = require("react");
|
|
3176
3442
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
3177
|
-
function CollapsibleSection({
|
|
3443
|
+
function CollapsibleSection({
|
|
3444
|
+
title,
|
|
3445
|
+
children,
|
|
3446
|
+
defaultOpen = true,
|
|
3447
|
+
id
|
|
3448
|
+
}) {
|
|
3178
3449
|
const [isOpen, setIsOpen] = (0, import_react21.useState)(defaultOpen);
|
|
3179
3450
|
const generatedId = (0, import_react21.useId)();
|
|
3180
3451
|
const contentId = `${id != null ? id : generatedId}-content`;
|
|
@@ -3207,6 +3478,9 @@ function CollapsibleSection({ title, children, defaultOpen = true, id }) {
|
|
|
3207
3478
|
{
|
|
3208
3479
|
id: contentId,
|
|
3209
3480
|
"aria-hidden": !isOpen,
|
|
3481
|
+
ref: (node) => {
|
|
3482
|
+
if (node) node.toggleAttribute("inert", !isOpen);
|
|
3483
|
+
},
|
|
3210
3484
|
className: cn(
|
|
3211
3485
|
"overflow-hidden transition-all duration-300",
|
|
3212
3486
|
isOpen ? "max-h-[50000px] opacity-100" : "max-h-0 opacity-0"
|
|
@@ -3218,6 +3492,7 @@ function CollapsibleSection({ title, children, defaultOpen = true, id }) {
|
|
|
3218
3492
|
}
|
|
3219
3493
|
|
|
3220
3494
|
// src/components/ui/Typography.tsx
|
|
3495
|
+
var import_react22 = require("react");
|
|
3221
3496
|
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
3222
3497
|
var toneMap2 = {
|
|
3223
3498
|
default: "text-ph-ink",
|
|
@@ -3240,54 +3515,62 @@ var weightMap = {
|
|
|
3240
3515
|
function textClass(base, tone, weight, truncate, className) {
|
|
3241
3516
|
return cn(base, toneMap2[tone], weight && weightMap[weight], truncate && "truncate", className);
|
|
3242
3517
|
}
|
|
3243
|
-
|
|
3244
|
-
children,
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
className
|
|
3249
|
-
}) {
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("
|
|
3254
|
-
}
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
}
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
}
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h4", { className: textClass("text-lg font-semibold", tone, weight, truncate, className), children });
|
|
3266
|
-
}
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
}
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
}
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: textClass("text-
|
|
3278
|
-
}
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
}
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
}
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("
|
|
3290
|
-
}
|
|
3518
|
+
var Display = (0, import_react22.forwardRef)(function Display2(_a, ref) {
|
|
3519
|
+
var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3520
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h1", __spreadProps(__spreadValues({ ref }, props), { className: textClass("ph-hero-title", tone, weight, truncate, className), children }));
|
|
3521
|
+
});
|
|
3522
|
+
var SectionTitle = (0, import_react22.forwardRef)(function SectionTitle2(_a, ref) {
|
|
3523
|
+
var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3524
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h2", __spreadProps(__spreadValues({ ref }, props), { className: textClass("ph-section-title", tone, weight, truncate, className), children }));
|
|
3525
|
+
});
|
|
3526
|
+
var H1 = (0, import_react22.forwardRef)(function H12(_a, ref) {
|
|
3527
|
+
var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3528
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h1", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-3xl font-bold tracking-tight md:text-4xl", tone, weight, truncate, className), children }));
|
|
3529
|
+
});
|
|
3530
|
+
var H2 = (0, import_react22.forwardRef)(function H22(_a, ref) {
|
|
3531
|
+
var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3532
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h2", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-2xl font-bold tracking-tight", tone, weight, truncate, className), children }));
|
|
3533
|
+
});
|
|
3534
|
+
var H3 = (0, import_react22.forwardRef)(function H32(_a, ref) {
|
|
3535
|
+
var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h3", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-xl font-semibold", tone, weight, truncate, className), children }));
|
|
3537
|
+
});
|
|
3538
|
+
var H4 = (0, import_react22.forwardRef)(function H42(_a, ref) {
|
|
3539
|
+
var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3540
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h4", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-lg font-semibold", tone, weight, truncate, className), children }));
|
|
3541
|
+
});
|
|
3542
|
+
var H5 = (0, import_react22.forwardRef)(function H52(_a, ref) {
|
|
3543
|
+
var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3544
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h5", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-base font-semibold", tone, weight, truncate, className), children }));
|
|
3545
|
+
});
|
|
3546
|
+
var P = (0, import_react22.forwardRef)(function P2(_a, ref) {
|
|
3547
|
+
var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3548
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-base leading-relaxed", tone, weight, truncate, className), children }));
|
|
3549
|
+
});
|
|
3550
|
+
var Small = (0, import_react22.forwardRef)(function Small2(_a, ref) {
|
|
3551
|
+
var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3552
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-sm leading-relaxed", tone, weight, truncate, className), children }));
|
|
3553
|
+
});
|
|
3554
|
+
var Caption = (0, import_react22.forwardRef)(function Caption2(_a, ref) {
|
|
3555
|
+
var _b = _a, { children, tone = "muted", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3556
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-[11px] font-medium uppercase tracking-wider", tone, weight, truncate, className), children }));
|
|
3557
|
+
});
|
|
3558
|
+
var Overline = (0, import_react22.forwardRef)(function Overline2(_a, ref) {
|
|
3559
|
+
var _b = _a, { children, tone = "muted", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3560
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-[10px] font-bold uppercase tracking-[0.15em]", tone, weight, truncate, className), children }));
|
|
3561
|
+
});
|
|
3562
|
+
var Lead = (0, import_react22.forwardRef)(function Lead2(_a, ref) {
|
|
3563
|
+
var _b = _a, { children, tone = "subtle", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3564
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", __spreadProps(__spreadValues({ ref }, props), { className: textClass("ph-lead", tone, weight, truncate, className), children }));
|
|
3565
|
+
});
|
|
3566
|
+
var Mono = (0, import_react22.forwardRef)(function Mono2(_a, ref) {
|
|
3567
|
+
var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3568
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("code", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-sm font-mono leading-relaxed", tone, weight, truncate, className), children }));
|
|
3569
|
+
});
|
|
3570
|
+
var Label = (0, import_react22.forwardRef)(function Label2(_a, ref) {
|
|
3571
|
+
var _b = _a, { children, tone = "default", weight, truncate, className } = _b, props = __objRest(_b, ["children", "tone", "weight", "truncate", "className"]);
|
|
3572
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("label", __spreadProps(__spreadValues({ ref }, props), { className: textClass("text-sm font-medium", tone, weight, truncate, className), children }));
|
|
3573
|
+
});
|
|
3291
3574
|
|
|
3292
3575
|
// src/components/ui/Avatar.tsx
|
|
3293
3576
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
@@ -3299,9 +3582,9 @@ var sizeMap4 = {
|
|
|
3299
3582
|
xl: "h-24 w-24 text-3xl"
|
|
3300
3583
|
};
|
|
3301
3584
|
var statusMap = {
|
|
3302
|
-
online: "bg-
|
|
3585
|
+
online: "bg-ph-success",
|
|
3303
3586
|
offline: "bg-ph-mutedtext",
|
|
3304
|
-
away: "bg-
|
|
3587
|
+
away: "bg-ph-warning",
|
|
3305
3588
|
busy: "bg-ph-danger"
|
|
3306
3589
|
};
|
|
3307
3590
|
function Avatar(_a) {
|
|
@@ -3337,8 +3620,10 @@ function Avatar(_a) {
|
|
|
3337
3620
|
status && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3338
3621
|
"span",
|
|
3339
3622
|
{
|
|
3623
|
+
role: "img",
|
|
3624
|
+
"aria-label": `${status} status`,
|
|
3340
3625
|
className: cn(
|
|
3341
|
-
"absolute bottom-0 right-1 h-2.5 w-2.5 rounded-full border-2 border-
|
|
3626
|
+
"absolute bottom-0 right-1 h-2.5 w-2.5 rounded-full border-2 border-ph-surface",
|
|
3342
3627
|
statusMap[status]
|
|
3343
3628
|
)
|
|
3344
3629
|
}
|
|
@@ -3365,6 +3650,7 @@ function AvatarGroup(_a) {
|
|
|
3365
3650
|
}
|
|
3366
3651
|
|
|
3367
3652
|
// src/components/ui/Progress.tsx
|
|
3653
|
+
var import_react23 = require("react");
|
|
3368
3654
|
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
3369
3655
|
var sizeMap5 = {
|
|
3370
3656
|
sm: "h-1",
|
|
@@ -3379,7 +3665,9 @@ function Progress(_a) {
|
|
|
3379
3665
|
label,
|
|
3380
3666
|
showPercentage = false,
|
|
3381
3667
|
size = "md",
|
|
3382
|
-
className
|
|
3668
|
+
className,
|
|
3669
|
+
"aria-label": ariaLabel,
|
|
3670
|
+
"aria-labelledby": ariaLabelledBy
|
|
3383
3671
|
} = _b, props = __objRest(_b, [
|
|
3384
3672
|
"value",
|
|
3385
3673
|
"max",
|
|
@@ -3387,12 +3675,17 @@ function Progress(_a) {
|
|
|
3387
3675
|
"label",
|
|
3388
3676
|
"showPercentage",
|
|
3389
3677
|
"size",
|
|
3390
|
-
"className"
|
|
3678
|
+
"className",
|
|
3679
|
+
"aria-label",
|
|
3680
|
+
"aria-labelledby"
|
|
3391
3681
|
]);
|
|
3392
|
-
const
|
|
3682
|
+
const labelId = (0, import_react23.useId)();
|
|
3683
|
+
const safeMax = Number.isFinite(max) && max > 0 ? max : 100;
|
|
3684
|
+
const safeValue = Number.isFinite(value) ? Math.min(safeMax, Math.max(0, value)) : 0;
|
|
3685
|
+
const percentage = safeValue / safeMax * 100;
|
|
3393
3686
|
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", __spreadProps(__spreadValues({ className: cn("w-full", className) }, props), { children: [
|
|
3394
3687
|
(label || showPercentage) && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "mb-1.5 flex justify-between text-sm text-ph-subtle", children: [
|
|
3395
|
-
label && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { children: label }),
|
|
3688
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { id: labelId, children: label }),
|
|
3396
3689
|
showPercentage && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "tabular-nums", children: [
|
|
3397
3690
|
Math.round(percentage),
|
|
3398
3691
|
"%"
|
|
@@ -3404,18 +3697,20 @@ function Progress(_a) {
|
|
|
3404
3697
|
className: cn("ph-progress-bar", color),
|
|
3405
3698
|
style: { width: `${percentage}%` },
|
|
3406
3699
|
role: "progressbar",
|
|
3407
|
-
"aria-valuenow":
|
|
3700
|
+
"aria-valuenow": safeValue,
|
|
3408
3701
|
"aria-valuemin": 0,
|
|
3409
|
-
"aria-valuemax":
|
|
3702
|
+
"aria-valuemax": safeMax,
|
|
3703
|
+
"aria-label": label ? void 0 : ariaLabel != null ? ariaLabel : "Progress",
|
|
3704
|
+
"aria-labelledby": label ? ariaLabelledBy != null ? ariaLabelledBy : labelId : ariaLabelledBy
|
|
3410
3705
|
}
|
|
3411
3706
|
) })
|
|
3412
3707
|
] }));
|
|
3413
3708
|
}
|
|
3414
3709
|
|
|
3415
3710
|
// src/components/ui/Link.tsx
|
|
3416
|
-
var
|
|
3711
|
+
var import_react24 = require("react");
|
|
3417
3712
|
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
3418
|
-
var Link = (0,
|
|
3713
|
+
var Link = (0, import_react24.forwardRef)(function Link2(_a, ref) {
|
|
3419
3714
|
var _b = _a, {
|
|
3420
3715
|
className,
|
|
3421
3716
|
disabled = false,
|
|
@@ -3495,9 +3790,9 @@ function Dot(_a) {
|
|
|
3495
3790
|
Dot.displayName = "Dot";
|
|
3496
3791
|
|
|
3497
3792
|
// src/components/ui/Chip.tsx
|
|
3498
|
-
var
|
|
3793
|
+
var import_react25 = require("react");
|
|
3499
3794
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
3500
|
-
var Chip = (0,
|
|
3795
|
+
var Chip = (0, import_react25.forwardRef)(function Chip2(_a, ref) {
|
|
3501
3796
|
var _b = _a, {
|
|
3502
3797
|
selected = false,
|
|
3503
3798
|
onRemove,
|