@flanksource/clicky-ui 0.2.12 → 0.2.14
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/components/Combobox.cjs +47 -33
- package/dist/components/Combobox.cjs.map +1 -1
- package/dist/components/Combobox.d.ts +12 -0
- package/dist/components/Combobox.d.ts.map +1 -1
- package/dist/components/Combobox.js +48 -34
- package/dist/components/Combobox.js.map +1 -1
- package/dist/components/IconButton.cjs +26 -0
- package/dist/components/IconButton.cjs.map +1 -0
- package/dist/components/IconButton.d.ts +25 -0
- package/dist/components/IconButton.d.ts.map +1 -0
- package/dist/components/IconButton.js +26 -0
- package/dist/components/IconButton.js.map +1 -0
- package/dist/components/SecretKeySelector.cjs +151 -0
- package/dist/components/SecretKeySelector.cjs.map +1 -0
- package/dist/components/SecretKeySelector.d.ts +51 -0
- package/dist/components/SecretKeySelector.d.ts.map +1 -0
- package/dist/components/SecretKeySelector.js +151 -0
- package/dist/components/SecretKeySelector.js.map +1 -0
- package/dist/components/WorkloadPicker.cjs +144 -0
- package/dist/components/WorkloadPicker.cjs.map +1 -0
- package/dist/components/WorkloadPicker.d.ts +52 -0
- package/dist/components/WorkloadPicker.d.ts.map +1 -0
- package/dist/components/WorkloadPicker.js +144 -0
- package/dist/components/WorkloadPicker.js.map +1 -0
- package/dist/components/icon-menu-picker.cjs +83 -112
- package/dist/components/icon-menu-picker.cjs.map +1 -1
- package/dist/components/icon-menu-picker.d.ts.map +1 -1
- package/dist/components/icon-menu-picker.js +85 -114
- package/dist/components/icon-menu-picker.js.map +1 -1
- package/dist/components.cjs +10 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +3 -0
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +11 -1
- package/dist/components.js.map +1 -1
- package/dist/data/Clicky.cjs +1 -1
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.js +1 -1
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/TimeseriesCoreBars.cjs +8 -1
- package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
- package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
- package/dist/data/TimeseriesCoreBars.js +8 -1
- package/dist/data/TimeseriesCoreBars.js.map +1 -1
- package/dist/data/Version.cjs +42 -0
- package/dist/data/Version.cjs.map +1 -0
- package/dist/data/Version.d.ts +36 -0
- package/dist/data/Version.d.ts.map +1 -0
- package/dist/data/Version.js +42 -0
- package/dist/data/Version.js.map +1 -0
- package/dist/data/test-runner/TestDetailPanel.cjs +165 -0
- package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -0
- package/dist/data/test-runner/TestDetailPanel.d.ts +7 -0
- package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -0
- package/dist/data/test-runner/TestDetailPanel.js +165 -0
- package/dist/data/test-runner/TestDetailPanel.js.map +1 -0
- package/dist/data/test-runner/TestFailureDetail.cjs +78 -0
- package/dist/data/test-runner/TestFailureDetail.cjs.map +1 -0
- package/dist/data/test-runner/TestFailureDetail.d.ts +14 -0
- package/dist/data/test-runner/TestFailureDetail.d.ts.map +1 -0
- package/dist/data/test-runner/TestFailureDetail.js +78 -0
- package/dist/data/test-runner/TestFailureDetail.js.map +1 -0
- package/dist/data/test-runner/TestFilterBar.cjs +108 -0
- package/dist/data/test-runner/TestFilterBar.cjs.map +1 -0
- package/dist/data/test-runner/TestFilterBar.d.ts +15 -0
- package/dist/data/test-runner/TestFilterBar.d.ts.map +1 -0
- package/dist/data/test-runner/TestFilterBar.js +108 -0
- package/dist/data/test-runner/TestFilterBar.js.map +1 -0
- package/dist/data/test-runner/TestRunSummary.cjs +81 -0
- package/dist/data/test-runner/TestRunSummary.cjs.map +1 -0
- package/dist/data/test-runner/TestRunSummary.d.ts +19 -0
- package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -0
- package/dist/data/test-runner/TestRunSummary.js +81 -0
- package/dist/data/test-runner/TestRunSummary.js.map +1 -0
- package/dist/data/test-runner/TestRunner.cjs +143 -0
- package/dist/data/test-runner/TestRunner.cjs.map +1 -0
- package/dist/data/test-runner/TestRunner.d.ts +42 -0
- package/dist/data/test-runner/TestRunner.d.ts.map +1 -0
- package/dist/data/test-runner/TestRunner.fixtures.d.ts +26 -0
- package/dist/data/test-runner/TestRunner.fixtures.d.ts.map +1 -0
- package/dist/data/test-runner/TestRunner.js +143 -0
- package/dist/data/test-runner/TestRunner.js.map +1 -0
- package/dist/data/test-runner/TestTree.cjs +42 -0
- package/dist/data/test-runner/TestTree.cjs.map +1 -0
- package/dist/data/test-runner/TestTree.d.ts +9 -0
- package/dist/data/test-runner/TestTree.d.ts.map +1 -0
- package/dist/data/test-runner/TestTree.js +42 -0
- package/dist/data/test-runner/TestTree.js.map +1 -0
- package/dist/data/test-runner/TestTreeNode.cjs +99 -0
- package/dist/data/test-runner/TestTreeNode.cjs.map +1 -0
- package/dist/data/test-runner/TestTreeNode.d.ts +12 -0
- package/dist/data/test-runner/TestTreeNode.d.ts.map +1 -0
- package/dist/data/test-runner/TestTreeNode.js +99 -0
- package/dist/data/test-runner/TestTreeNode.js.map +1 -0
- package/dist/data/test-runner/adapter.cjs +57 -0
- package/dist/data/test-runner/adapter.cjs.map +1 -0
- package/dist/data/test-runner/adapter.d.ts +60 -0
- package/dist/data/test-runner/adapter.d.ts.map +1 -0
- package/dist/data/test-runner/adapter.js +57 -0
- package/dist/data/test-runner/adapter.js.map +1 -0
- package/dist/data/test-runner/context.cjs +15 -0
- package/dist/data/test-runner/context.cjs.map +1 -0
- package/dist/data/test-runner/context.d.ts +40 -0
- package/dist/data/test-runner/context.d.ts.map +1 -0
- package/dist/data/test-runner/context.js +15 -0
- package/dist/data/test-runner/context.js.map +1 -0
- package/dist/data/test-runner/filterState.cjs +47 -0
- package/dist/data/test-runner/filterState.cjs.map +1 -0
- package/dist/data/test-runner/filterState.d.ts +14 -0
- package/dist/data/test-runner/filterState.d.ts.map +1 -0
- package/dist/data/test-runner/filterState.js +47 -0
- package/dist/data/test-runner/filterState.js.map +1 -0
- package/dist/data/test-runner/frameworkIcon.cjs +27 -0
- package/dist/data/test-runner/frameworkIcon.cjs.map +1 -0
- package/dist/data/test-runner/frameworkIcon.d.ts +3 -0
- package/dist/data/test-runner/frameworkIcon.d.ts.map +1 -0
- package/dist/data/test-runner/frameworkIcon.js +27 -0
- package/dist/data/test-runner/frameworkIcon.js.map +1 -0
- package/dist/data/test-runner/index.d.ts +14 -0
- package/dist/data/test-runner/index.d.ts.map +1 -0
- package/dist/data/test-runner/status.cjs +234 -0
- package/dist/data/test-runner/status.cjs.map +1 -0
- package/dist/data/test-runner/status.d.ts +52 -0
- package/dist/data/test-runner/status.d.ts.map +1 -0
- package/dist/data/test-runner/status.js +234 -0
- package/dist/data/test-runner/status.js.map +1 -0
- package/dist/data/test-runner/types.d.ts +148 -0
- package/dist/data/test-runner/types.d.ts.map +1 -0
- package/dist/data/version-info.cjs +26 -0
- package/dist/data/version-info.cjs.map +1 -0
- package/dist/data/version-info.d.ts +11 -0
- package/dist/data/version-info.d.ts.map +1 -0
- package/dist/data/version-info.js +26 -0
- package/dist/data/version-info.js.map +1 -0
- package/dist/data.cjs +49 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +3 -0
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +50 -1
- package/dist/data.js.map +1 -1
- package/dist/index.cjs +59 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +60 -1
- package/dist/index.js.map +1 -1
- package/dist/overlay/DropdownMenu.cjs +57 -30
- package/dist/overlay/DropdownMenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenu.d.ts.map +1 -1
- package/dist/overlay/DropdownMenu.js +57 -30
- package/dist/overlay/DropdownMenu.js.map +1 -1
- package/dist/overlay/Modal.cjs +62 -6
- package/dist/overlay/Modal.cjs.map +1 -1
- package/dist/overlay/Modal.d.ts +19 -1
- package/dist/overlay/Modal.d.ts.map +1 -1
- package/dist/overlay/Modal.js +62 -6
- package/dist/overlay/Modal.js.map +1 -1
- package/dist/rpc/CommandForm.cjs +2 -2
- package/dist/rpc/CommandForm.cjs.map +1 -1
- package/dist/rpc/CommandForm.d.ts.map +1 -1
- package/dist/rpc/CommandForm.js +3 -3
- package/dist/rpc/CommandForm.js.map +1 -1
- package/dist/rpc/formMetadata.cjs +5 -4
- package/dist/rpc/formMetadata.cjs.map +1 -1
- package/dist/rpc/formMetadata.d.ts.map +1 -1
- package/dist/rpc/formMetadata.js +6 -5
- package/dist/rpc/formMetadata.js.map +1 -1
- package/dist/rpc/types.cjs +4 -0
- package/dist/rpc/types.cjs.map +1 -1
- package/dist/rpc/types.d.ts +10 -0
- package/dist/rpc/types.d.ts.map +1 -1
- package/dist/rpc/types.js +5 -1
- package/dist/rpc/types.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { useSort } from "./hooks/use-sort.js";
|
|
|
8
8
|
import { useHistoryRoute } from "./hooks/use-history-route.js";
|
|
9
9
|
import { useTaskRun, useTaskRuns } from "./hooks/use-task-run.js";
|
|
10
10
|
import { Button, buttonVariants } from "./components/button.js";
|
|
11
|
+
import { IconButton } from "./components/IconButton.js";
|
|
11
12
|
import { SplitButton } from "./components/SplitButton.js";
|
|
12
13
|
import { CLICKY_FORMAT_OPTIONS, FormatOptionsDropdown } from "./components/FormatOptionsDropdown.js";
|
|
13
14
|
import { DateField } from "./components/DateField.js";
|
|
@@ -19,6 +20,8 @@ import { FilterBar } from "./components/FilterBar.js";
|
|
|
19
20
|
import { MultiSelect } from "./components/MultiSelect.js";
|
|
20
21
|
import { Select } from "./components/select.js";
|
|
21
22
|
import { Combobox } from "./components/Combobox.js";
|
|
23
|
+
import { WorkloadPicker, kindForValue, loadedWorkloads, parseWorkloadKey, workloadKey } from "./components/WorkloadPicker.js";
|
|
24
|
+
import { SecretKeySelector } from "./components/SecretKeySelector.js";
|
|
22
25
|
import { ThemeSwitcher } from "./components/theme-switcher.js";
|
|
23
26
|
import { DensitySwitcher } from "./components/density-switcher.js";
|
|
24
27
|
import { IconMenuPicker } from "./components/icon-menu-picker.js";
|
|
@@ -60,6 +63,8 @@ import { TimeseriesPanel, resolveBreakdown, resolveSeries } from "./data/Timeser
|
|
|
60
63
|
import { TimeseriesGauge } from "./data/TimeseriesGauge.js";
|
|
61
64
|
import { TimeseriesCoreBars, deriveCoreBars } from "./data/TimeseriesCoreBars.js";
|
|
62
65
|
import { StackedStatusBar, StatusRows, segment } from "./data/StatusBreakdown.js";
|
|
66
|
+
import { Version } from "./data/Version.js";
|
|
67
|
+
import { getVersionInfo } from "./data/version-info.js";
|
|
63
68
|
import { Tree } from "./data/Tree.js";
|
|
64
69
|
import { TreeNode } from "./data/TreeNode.js";
|
|
65
70
|
import { TreeGroupHeader } from "./data/TreeGroupHeader.js";
|
|
@@ -95,6 +100,15 @@ import { useOpenAPI, useOperationById, useOperations } from "./rpc/useOperations
|
|
|
95
100
|
import { OperationsApiClientError, createOperationsApiClient } from "./rpc/apiClient.js";
|
|
96
101
|
import { filterOperationsByDomain, findDetailEndpoint, findListEndpoint, normalizeRows, parseJsonBody } from "./rpc/classify.js";
|
|
97
102
|
import { isPositionalParam } from "./rpc/types.js";
|
|
103
|
+
import { TestAttempts, TestFailureDetail, TestOutput } from "./data/test-runner/TestFailureDetail.js";
|
|
104
|
+
import { TestDetailPanel } from "./data/test-runner/TestDetailPanel.js";
|
|
105
|
+
import { TestFilterBar } from "./data/test-runner/TestFilterBar.js";
|
|
106
|
+
import { TestNodeAdapterRegistry, createTestRunnerRegistry } from "./data/test-runner/adapter.js";
|
|
107
|
+
import { TestRunSummary } from "./data/test-runner/TestRunSummary.js";
|
|
108
|
+
import { TestRunner } from "./data/test-runner/TestRunner.js";
|
|
109
|
+
import { TestRunnerProvider, useTestRunner } from "./data/test-runner/context.js";
|
|
110
|
+
import { TestTree } from "./data/test-runner/TestTree.js";
|
|
111
|
+
import { TestTreeNode } from "./data/test-runner/TestTreeNode.js";
|
|
98
112
|
import { UiActivity } from "./icons/components/UiActivity.js";
|
|
99
113
|
import { UiAdd, UiAddFilled } from "./icons/components/UiAdd.js";
|
|
100
114
|
import { UiArchive, UiArchiveFilled } from "./icons/components/UiArchive.js";
|
|
@@ -355,6 +369,9 @@ import { UiZap, UiZapFilled } from "./icons/components/UiZap.js";
|
|
|
355
369
|
import { UiZoomIn, UiZoomInFilled } from "./icons/components/UiZoomIn.js";
|
|
356
370
|
import { UiZoomOut, UiZoomOutFilled } from "./icons/components/UiZoomOut.js";
|
|
357
371
|
import { changeIconAliases, getChangeIcon } from "./icons/changeIconAliases.js";
|
|
372
|
+
import { collapseSingleChildChains, collectFrameworks, filterTests, formatCount, formatTestDuration, hasFailed, hasPending, humanizeName, statusIconFor, statusToneFor, sum, sumNonTaskTests, testStatus, totalDuration } from "./data/test-runner/status.js";
|
|
373
|
+
import { cycleFilterState, decodeFilterState, emptyTestFilters, encodeFilterState, matchesFilterState } from "./data/test-runner/filterState.js";
|
|
374
|
+
import { frameworkIcon } from "./data/test-runner/frameworkIcon.js";
|
|
358
375
|
export {
|
|
359
376
|
ACCEPT_OPTIONS,
|
|
360
377
|
AVATAR_PALETTE,
|
|
@@ -398,6 +415,7 @@ export {
|
|
|
398
415
|
HarPanel,
|
|
399
416
|
HoverCard,
|
|
400
417
|
Icon,
|
|
418
|
+
IconButton,
|
|
401
419
|
IconMenuPicker,
|
|
402
420
|
InlineError,
|
|
403
421
|
JsonSchemaForm,
|
|
@@ -424,6 +442,7 @@ export {
|
|
|
424
442
|
RangeSlider,
|
|
425
443
|
SIZE_TOKENS,
|
|
426
444
|
STATUS_TOKEN_GROUPS,
|
|
445
|
+
SecretKeySelector,
|
|
427
446
|
Section,
|
|
428
447
|
Select,
|
|
429
448
|
SignedDeltaBar,
|
|
@@ -439,6 +458,17 @@ export {
|
|
|
439
458
|
TagList,
|
|
440
459
|
TaskManager,
|
|
441
460
|
TaskProgress,
|
|
461
|
+
TestAttempts,
|
|
462
|
+
TestDetailPanel,
|
|
463
|
+
TestFailureDetail,
|
|
464
|
+
TestFilterBar,
|
|
465
|
+
TestNodeAdapterRegistry,
|
|
466
|
+
TestOutput,
|
|
467
|
+
TestRunSummary,
|
|
468
|
+
TestRunner,
|
|
469
|
+
TestRunnerProvider,
|
|
470
|
+
TestTree,
|
|
471
|
+
TestTreeNode,
|
|
442
472
|
ThemeProvider,
|
|
443
473
|
ThemeSwitcher,
|
|
444
474
|
TimeRange,
|
|
@@ -939,6 +969,8 @@ export {
|
|
|
939
969
|
UiZoomOut,
|
|
940
970
|
UiZoomOutFilled,
|
|
941
971
|
VIEW_OPTIONS,
|
|
972
|
+
Version,
|
|
973
|
+
WorkloadPicker,
|
|
942
974
|
allGroupsTerminal,
|
|
943
975
|
badgeVariants,
|
|
944
976
|
bucketTasks,
|
|
@@ -946,37 +978,55 @@ export {
|
|
|
946
978
|
changeIconAliases,
|
|
947
979
|
chooseTimestampFormat,
|
|
948
980
|
cn,
|
|
981
|
+
collapseSingleChildChains,
|
|
982
|
+
collectFrameworks,
|
|
949
983
|
compactStackPath,
|
|
950
984
|
countGoroutinesByState,
|
|
951
985
|
countProcesses,
|
|
952
986
|
countStackByState,
|
|
953
987
|
countThreadsByState,
|
|
954
988
|
createOperationsApiClient,
|
|
989
|
+
createTestRunnerRegistry,
|
|
990
|
+
cycleFilterState,
|
|
991
|
+
decodeFilterState,
|
|
955
992
|
deriveCoreBars,
|
|
956
993
|
detectDumpFormat,
|
|
957
994
|
effectiveProperties,
|
|
995
|
+
emptyTestFilters,
|
|
996
|
+
encodeFilterState,
|
|
958
997
|
filterOperationsByDomain,
|
|
998
|
+
filterTests,
|
|
959
999
|
findDetailEndpoint,
|
|
960
1000
|
findListEndpoint,
|
|
961
1001
|
findProcessByPID,
|
|
962
1002
|
fnv1a32,
|
|
963
1003
|
formatBytes,
|
|
964
1004
|
formatBytesPerSecond,
|
|
1005
|
+
formatCount,
|
|
965
1006
|
formatDateTimeRelative,
|
|
966
1007
|
formatDuration,
|
|
967
1008
|
formatPropertyLabel,
|
|
968
1009
|
formatRelativeTime,
|
|
969
1010
|
formatShort,
|
|
1011
|
+
formatTestDuration,
|
|
970
1012
|
formatTimestamp,
|
|
971
1013
|
formatUnit,
|
|
972
1014
|
frameHasSource,
|
|
1015
|
+
frameworkIcon,
|
|
973
1016
|
getChangeIcon,
|
|
1017
|
+
getVersionInfo,
|
|
1018
|
+
hasFailed,
|
|
1019
|
+
hasPending,
|
|
1020
|
+
humanizeName,
|
|
974
1021
|
inferColumns,
|
|
975
1022
|
isApplicationStackFrame,
|
|
976
1023
|
isOpenStringMap,
|
|
977
1024
|
isPositionalParam,
|
|
978
1025
|
isTerminalStatus,
|
|
1026
|
+
kindForValue,
|
|
1027
|
+
loadedWorkloads,
|
|
979
1028
|
logLevelColor,
|
|
1029
|
+
matchesFilterState,
|
|
980
1030
|
matchesIf,
|
|
981
1031
|
modeToFormat,
|
|
982
1032
|
normalizeErrorDiagnostics,
|
|
@@ -993,6 +1043,7 @@ export {
|
|
|
993
1043
|
parseJvmThreadDump,
|
|
994
1044
|
parseStackDump,
|
|
995
1045
|
parseTimestamp,
|
|
1046
|
+
parseWorkloadKey,
|
|
996
1047
|
processLabel,
|
|
997
1048
|
processStateColor,
|
|
998
1049
|
processStateIcon,
|
|
@@ -1003,12 +1054,18 @@ export {
|
|
|
1003
1054
|
segment,
|
|
1004
1055
|
setFallbackIconProvider,
|
|
1005
1056
|
splitTagToken,
|
|
1057
|
+
statusIconFor,
|
|
1058
|
+
statusToneFor,
|
|
1059
|
+
sum,
|
|
1060
|
+
sumNonTaskTests,
|
|
1006
1061
|
tagActionsFromRecord,
|
|
1007
1062
|
tagFilterTokens,
|
|
1008
1063
|
taskSegments,
|
|
1009
1064
|
taskStatusBg,
|
|
1010
1065
|
taskStatusColor,
|
|
1011
1066
|
taskStatusIcon,
|
|
1067
|
+
testStatus,
|
|
1068
|
+
totalDuration,
|
|
1012
1069
|
useDensity,
|
|
1013
1070
|
useDensityValue,
|
|
1014
1071
|
useHistoryRoute,
|
|
@@ -1022,6 +1079,8 @@ export {
|
|
|
1022
1079
|
useTagActionsValue,
|
|
1023
1080
|
useTaskRun,
|
|
1024
1081
|
useTaskRuns,
|
|
1025
|
-
|
|
1082
|
+
useTestRunner,
|
|
1083
|
+
useTheme,
|
|
1084
|
+
workloadKey
|
|
1026
1085
|
};
|
|
1027
1086
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const react = require("react");
|
|
5
|
+
const react$1 = require("@floating-ui/react");
|
|
5
6
|
const utils = require("../lib/utils.cjs");
|
|
6
7
|
const button = require("../components/button.cjs");
|
|
7
8
|
const Icon = require("../data/Icon.cjs");
|
|
@@ -22,50 +23,61 @@ function DropdownMenu({
|
|
|
22
23
|
menuClassName
|
|
23
24
|
}) {
|
|
24
25
|
const [open, setOpen] = react.useState(false);
|
|
25
|
-
const
|
|
26
|
+
const [activeIndex, setActiveIndex] = react.useState(null);
|
|
27
|
+
const listRef = react.useRef([]);
|
|
26
28
|
const onOpenChangeRef = react.useRef(onOpenChange);
|
|
27
29
|
onOpenChangeRef.current = onOpenChange;
|
|
28
30
|
react.useEffect(() => {
|
|
29
31
|
var _a;
|
|
30
32
|
(_a = onOpenChangeRef.current) == null ? void 0 : _a.call(onOpenChangeRef, open);
|
|
31
33
|
}, [open]);
|
|
32
|
-
react.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
34
|
+
const { refs, floatingStyles, context } = react$1.useFloating({
|
|
35
|
+
open,
|
|
36
|
+
onOpenChange: setOpen,
|
|
37
|
+
// bottom-end / bottom-start reproduce the previous right/left alignment.
|
|
38
|
+
placement: align === "right" ? "bottom-end" : "bottom-start",
|
|
39
|
+
whileElementsMounted: react$1.autoUpdate,
|
|
40
|
+
// offset(4) ≈ the previous mt-1; flip opens upward at the bottom edge and
|
|
41
|
+
// shift slides the menu back on-screen at the horizontal edges.
|
|
42
|
+
middleware: [react$1.offset(4), react$1.flip({ padding: 8 }), react$1.shift({ padding: 8 })]
|
|
43
|
+
});
|
|
44
|
+
const click = react$1.useClick(context);
|
|
45
|
+
const dismiss = react$1.useDismiss(context);
|
|
46
|
+
const role = react$1.useRole(context, { role: "menu" });
|
|
47
|
+
const listNav = react$1.useListNavigation(context, {
|
|
48
|
+
listRef,
|
|
49
|
+
activeIndex,
|
|
50
|
+
onNavigate: setActiveIndex,
|
|
51
|
+
loop: true
|
|
52
|
+
});
|
|
53
|
+
const { getReferenceProps, getFloatingProps, getItemProps } = react$1.useInteractions([
|
|
54
|
+
click,
|
|
55
|
+
dismiss,
|
|
56
|
+
role,
|
|
57
|
+
listNav
|
|
58
|
+
]);
|
|
48
59
|
const closeMenu = () => setOpen(false);
|
|
49
|
-
|
|
50
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn("relative inline-flex", className), ref: wrapperRef, children: [
|
|
60
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn("relative inline-flex", className), children: [
|
|
51
61
|
trigger ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
52
62
|
"span",
|
|
53
63
|
{
|
|
54
|
-
|
|
55
|
-
|
|
64
|
+
ref: refs.setReference,
|
|
65
|
+
className: "inline-flex",
|
|
56
66
|
"aria-haspopup": "menu",
|
|
57
67
|
"aria-expanded": open,
|
|
68
|
+
...getReferenceProps(),
|
|
58
69
|
children: trigger
|
|
59
70
|
}
|
|
60
71
|
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
61
72
|
button.Button,
|
|
62
73
|
{
|
|
74
|
+
ref: refs.setReference,
|
|
63
75
|
variant,
|
|
64
76
|
size,
|
|
65
|
-
onClick: toggle,
|
|
66
77
|
title,
|
|
67
78
|
"aria-haspopup": "menu",
|
|
68
79
|
"aria-expanded": open,
|
|
80
|
+
...getReferenceProps(),
|
|
69
81
|
children: [
|
|
70
82
|
icon && /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { ...typeof icon === "string" ? { name: icon } : { icon } }),
|
|
71
83
|
label,
|
|
@@ -73,27 +85,42 @@ function DropdownMenu({
|
|
|
73
85
|
]
|
|
74
86
|
}
|
|
75
87
|
),
|
|
76
|
-
open && /* @__PURE__ */ jsxRuntime.jsx(
|
|
88
|
+
open && /* @__PURE__ */ jsxRuntime.jsx(react$1.FloatingPortal, { children: /* @__PURE__ */ jsxRuntime.jsx(react$1.FloatingFocusManager, { context, modal: false, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
77
89
|
"div",
|
|
78
90
|
{
|
|
91
|
+
ref: refs.setFloating,
|
|
79
92
|
role: "menu",
|
|
93
|
+
style: floatingStyles,
|
|
80
94
|
className: utils.cn(
|
|
81
|
-
"
|
|
82
|
-
align === "right" ? "right-0" : "left-0",
|
|
95
|
+
"z-[9999] min-w-[8rem] rounded-md border border-border bg-popover py-1 shadow-md",
|
|
83
96
|
menuClassName
|
|
84
97
|
),
|
|
98
|
+
...getFloatingProps(),
|
|
85
99
|
children: children ? children(closeMenu) : items == null ? void 0 : items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
86
100
|
"button",
|
|
87
101
|
{
|
|
102
|
+
ref: (node) => {
|
|
103
|
+
listRef.current[i] = node;
|
|
104
|
+
},
|
|
88
105
|
type: "button",
|
|
89
106
|
role: "menuitem",
|
|
107
|
+
tabIndex: i === activeIndex ? 0 : -1,
|
|
90
108
|
disabled: item.disabled,
|
|
91
109
|
title: item.title,
|
|
92
|
-
onClick: () => {
|
|
93
|
-
item.onSelect();
|
|
94
|
-
closeMenu();
|
|
95
|
-
},
|
|
96
110
|
className: "flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50",
|
|
111
|
+
...getItemProps({
|
|
112
|
+
onClick: () => {
|
|
113
|
+
item.onSelect();
|
|
114
|
+
closeMenu();
|
|
115
|
+
},
|
|
116
|
+
onKeyDown: (event) => {
|
|
117
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
118
|
+
event.preventDefault();
|
|
119
|
+
item.onSelect();
|
|
120
|
+
closeMenu();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}),
|
|
97
124
|
children: [
|
|
98
125
|
item.icon && /* @__PURE__ */ jsxRuntime.jsx(
|
|
99
126
|
Icon.Icon,
|
|
@@ -107,7 +134,7 @@ function DropdownMenu({
|
|
|
107
134
|
i
|
|
108
135
|
))
|
|
109
136
|
}
|
|
110
|
-
)
|
|
137
|
+
) }) })
|
|
111
138
|
] });
|
|
112
139
|
}
|
|
113
140
|
exports.DropdownMenu = DropdownMenu;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownMenu.cjs","sources":["../../src/overlay/DropdownMenu.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Button, type ButtonProps } from \"../components/button\";\nimport { Icon, type StaticIconComponent } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\n\nexport type DropdownMenuItem = {\n /** Visible label. */\n label: ReactNode;\n /** Called when the item is chosen. */\n onSelect: () => void;\n /** Iconify name or imported icon component rendered before the label. */\n icon?: string | StaticIconComponent;\n /** Browser tooltip for the item. */\n title?: string;\n /** Disable selection. */\n disabled?: boolean;\n};\n\nexport type DropdownMenuProps = {\n /** Trigger label. Ignored when `trigger` is provided. */\n label?: ReactNode;\n /** Icon shown before the trigger label. Ignored when `trigger` is provided. */\n icon?: string | StaticIconComponent;\n /** Hide the trailing chevron on the default trigger. */\n hideChevron?: boolean;\n /** Variant forwarded to the default Button trigger. */\n variant?: ButtonProps[\"variant\"];\n /** Size forwarded to the default Button trigger. */\n size?: ButtonProps[\"size\"];\n /** Fully custom trigger. Receives no props; the menu wraps it with open state. */\n trigger?: ReactNode;\n /** Declarative menu items. Provide this or `children`, not both. */\n items?: DropdownMenuItem[];\n /** Custom menu content. Use `closeMenu` to dismiss after a selection. */\n children?: (closeMenu: () => void) => ReactNode;\n /** Horizontal alignment of the menu relative to the trigger. */\n align?: \"left\" | \"right\";\n /** Notified whenever the menu opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /** Browser tooltip / accessible label for the default trigger. */\n title?: string;\n /** Classes applied to the wrapper. */\n className?: string;\n /** Classes applied to the floating menu. */\n menuClassName?: string;\n};\n\nexport function DropdownMenu({\n label,\n icon,\n hideChevron = false,\n variant = \"outline\",\n size = \"sm\",\n trigger,\n items,\n children,\n align = \"right\",\n onOpenChange,\n title,\n className,\n menuClassName,\n}: DropdownMenuProps) {\n const [open, setOpen] = useState(false);\n const
|
|
1
|
+
{"version":3,"file":"DropdownMenu.cjs","sources":["../../src/overlay/DropdownMenu.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingPortal,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useInteractions,\n useListNavigation,\n useRole,\n} from \"@floating-ui/react\";\nimport { cn } from \"../lib/utils\";\nimport { Button, type ButtonProps } from \"../components/button\";\nimport { Icon, type StaticIconComponent } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\n\nexport type DropdownMenuItem = {\n /** Visible label. */\n label: ReactNode;\n /** Called when the item is chosen. */\n onSelect: () => void;\n /** Iconify name or imported icon component rendered before the label. */\n icon?: string | StaticIconComponent;\n /** Browser tooltip for the item. */\n title?: string;\n /** Disable selection. */\n disabled?: boolean;\n};\n\nexport type DropdownMenuProps = {\n /** Trigger label. Ignored when `trigger` is provided. */\n label?: ReactNode;\n /** Icon shown before the trigger label. Ignored when `trigger` is provided. */\n icon?: string | StaticIconComponent;\n /** Hide the trailing chevron on the default trigger. */\n hideChevron?: boolean;\n /** Variant forwarded to the default Button trigger. */\n variant?: ButtonProps[\"variant\"];\n /** Size forwarded to the default Button trigger. */\n size?: ButtonProps[\"size\"];\n /** Fully custom trigger. Receives no props; the menu wraps it with open state. */\n trigger?: ReactNode;\n /** Declarative menu items. Provide this or `children`, not both. */\n items?: DropdownMenuItem[];\n /** Custom menu content. Use `closeMenu` to dismiss after a selection. */\n children?: (closeMenu: () => void) => ReactNode;\n /** Horizontal alignment of the menu relative to the trigger. */\n align?: \"left\" | \"right\";\n /** Notified whenever the menu opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /** Browser tooltip / accessible label for the default trigger. */\n title?: string;\n /** Classes applied to the wrapper. */\n className?: string;\n /** Classes applied to the floating menu. */\n menuClassName?: string;\n};\n\nexport function DropdownMenu({\n label,\n icon,\n hideChevron = false,\n variant = \"outline\",\n size = \"sm\",\n trigger,\n items,\n children,\n align = \"right\",\n onOpenChange,\n title,\n className,\n menuClassName,\n}: DropdownMenuProps) {\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const listRef = useRef<(HTMLElement | null)[]>([]);\n\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n useEffect(() => {\n onOpenChangeRef.current?.(open);\n }, [open]);\n\n const { refs, floatingStyles, context } = useFloating<HTMLDivElement>({\n open,\n onOpenChange: setOpen,\n // bottom-end / bottom-start reproduce the previous right/left alignment.\n placement: align === \"right\" ? \"bottom-end\" : \"bottom-start\",\n whileElementsMounted: autoUpdate,\n // offset(4) ≈ the previous mt-1; flip opens upward at the bottom edge and\n // shift slides the menu back on-screen at the horizontal edges.\n middleware: [offset(4), flip({ padding: 8 }), shift({ padding: 8 })],\n });\n\n const click = useClick(context);\n const dismiss = useDismiss(context);\n const role = useRole(context, { role: \"menu\" });\n const listNav = useListNavigation(context, {\n listRef,\n activeIndex,\n onNavigate: setActiveIndex,\n loop: true,\n });\n\n const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([\n click,\n dismiss,\n role,\n listNav,\n ]);\n\n const closeMenu = () => setOpen(false);\n\n return (\n <div className={cn(\"relative inline-flex\", className)}>\n {trigger ? (\n <span\n ref={refs.setReference}\n className=\"inline-flex\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {trigger}\n </span>\n ) : (\n <Button\n ref={refs.setReference as React.Ref<HTMLButtonElement>}\n variant={variant}\n size={size}\n title={title}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {icon && <Icon {...(typeof icon === \"string\" ? { name: icon } : { icon })} />}\n {label}\n {!hideChevron && <Icon icon={UiChevronDown} />}\n </Button>\n )}\n {open && (\n <FloatingPortal>\n <FloatingFocusManager context={context} modal={false}>\n <div\n ref={refs.setFloating}\n role=\"menu\"\n style={floatingStyles}\n className={cn(\n \"z-[9999] min-w-[8rem] rounded-md border border-border bg-popover py-1 shadow-md\",\n menuClassName,\n )}\n {...getFloatingProps()}\n >\n {children\n ? children(closeMenu)\n : items?.map((item, i) => (\n <button\n key={i}\n ref={(node) => {\n listRef.current[i] = node;\n }}\n type=\"button\"\n role=\"menuitem\"\n tabIndex={i === activeIndex ? 0 : -1}\n disabled={item.disabled}\n title={item.title}\n className=\"flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n {...getItemProps({\n onClick: () => {\n item.onSelect();\n closeMenu();\n },\n onKeyDown: (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n item.onSelect();\n closeMenu();\n }\n },\n })}\n >\n {item.icon && (\n <Icon\n {...(typeof item.icon === \"string\"\n ? { name: item.icon }\n : { icon: item.icon })}\n />\n )}\n {item.label}\n </button>\n ))}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </div>\n );\n}\n"],"names":["useState","useRef","useEffect","useFloating","autoUpdate","offset","flip","shift","useClick","useDismiss","useRole","useListNavigation","useInteractions","cn","jsx","jsxs","Button","Icon","UiChevronDown","FloatingPortal","FloatingFocusManager"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/overlay/DropdownMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/overlay/DropdownMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAgBpE,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAQ,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAG9D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qBAAqB;IACrB,KAAK,EAAE,SAAS,CAAC;IACjB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAAC;IACpC,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,yDAAyD;IACzD,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAAC;IACpC,wDAAwD;IACxD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uDAAuD;IACvD,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACjC,oDAAoD;IACpD,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,kFAAkF;IAClF,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,oEAAoE;IACpE,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,IAAI,KAAK,SAAS,CAAC;IAChD,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,kDAAkD;IAClD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,IAAI,EACJ,WAAmB,EACnB,OAAmB,EACnB,IAAW,EACX,OAAO,EACP,KAAK,EACL,QAAQ,EACR,KAAe,EACf,YAAY,EACZ,KAAK,EACL,SAAS,EACT,aAAa,GACd,EAAE,iBAAiB,2CA6HnB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useRef, useEffect } from "react";
|
|
3
|
+
import { useFloating, autoUpdate, offset, flip, shift, useClick, useDismiss, useRole, useListNavigation, useInteractions, FloatingPortal, FloatingFocusManager } from "@floating-ui/react";
|
|
3
4
|
import { cn } from "../lib/utils.js";
|
|
4
5
|
import { Button } from "../components/button.js";
|
|
5
6
|
import { Icon } from "../data/Icon.js";
|
|
@@ -20,50 +21,61 @@ function DropdownMenu({
|
|
|
20
21
|
menuClassName
|
|
21
22
|
}) {
|
|
22
23
|
const [open, setOpen] = useState(false);
|
|
23
|
-
const
|
|
24
|
+
const [activeIndex, setActiveIndex] = useState(null);
|
|
25
|
+
const listRef = useRef([]);
|
|
24
26
|
const onOpenChangeRef = useRef(onOpenChange);
|
|
25
27
|
onOpenChangeRef.current = onOpenChange;
|
|
26
28
|
useEffect(() => {
|
|
27
29
|
var _a;
|
|
28
30
|
(_a = onOpenChangeRef.current) == null ? void 0 : _a.call(onOpenChangeRef, open);
|
|
29
31
|
}, [open]);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
32
|
+
const { refs, floatingStyles, context } = useFloating({
|
|
33
|
+
open,
|
|
34
|
+
onOpenChange: setOpen,
|
|
35
|
+
// bottom-end / bottom-start reproduce the previous right/left alignment.
|
|
36
|
+
placement: align === "right" ? "bottom-end" : "bottom-start",
|
|
37
|
+
whileElementsMounted: autoUpdate,
|
|
38
|
+
// offset(4) ≈ the previous mt-1; flip opens upward at the bottom edge and
|
|
39
|
+
// shift slides the menu back on-screen at the horizontal edges.
|
|
40
|
+
middleware: [offset(4), flip({ padding: 8 }), shift({ padding: 8 })]
|
|
41
|
+
});
|
|
42
|
+
const click = useClick(context);
|
|
43
|
+
const dismiss = useDismiss(context);
|
|
44
|
+
const role = useRole(context, { role: "menu" });
|
|
45
|
+
const listNav = useListNavigation(context, {
|
|
46
|
+
listRef,
|
|
47
|
+
activeIndex,
|
|
48
|
+
onNavigate: setActiveIndex,
|
|
49
|
+
loop: true
|
|
50
|
+
});
|
|
51
|
+
const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([
|
|
52
|
+
click,
|
|
53
|
+
dismiss,
|
|
54
|
+
role,
|
|
55
|
+
listNav
|
|
56
|
+
]);
|
|
46
57
|
const closeMenu = () => setOpen(false);
|
|
47
|
-
|
|
48
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("relative inline-flex", className), ref: wrapperRef, children: [
|
|
58
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative inline-flex", className), children: [
|
|
49
59
|
trigger ? /* @__PURE__ */ jsx(
|
|
50
60
|
"span",
|
|
51
61
|
{
|
|
52
|
-
|
|
53
|
-
|
|
62
|
+
ref: refs.setReference,
|
|
63
|
+
className: "inline-flex",
|
|
54
64
|
"aria-haspopup": "menu",
|
|
55
65
|
"aria-expanded": open,
|
|
66
|
+
...getReferenceProps(),
|
|
56
67
|
children: trigger
|
|
57
68
|
}
|
|
58
69
|
) : /* @__PURE__ */ jsxs(
|
|
59
70
|
Button,
|
|
60
71
|
{
|
|
72
|
+
ref: refs.setReference,
|
|
61
73
|
variant,
|
|
62
74
|
size,
|
|
63
|
-
onClick: toggle,
|
|
64
75
|
title,
|
|
65
76
|
"aria-haspopup": "menu",
|
|
66
77
|
"aria-expanded": open,
|
|
78
|
+
...getReferenceProps(),
|
|
67
79
|
children: [
|
|
68
80
|
icon && /* @__PURE__ */ jsx(Icon, { ...typeof icon === "string" ? { name: icon } : { icon } }),
|
|
69
81
|
label,
|
|
@@ -71,27 +83,42 @@ function DropdownMenu({
|
|
|
71
83
|
]
|
|
72
84
|
}
|
|
73
85
|
),
|
|
74
|
-
open && /* @__PURE__ */ jsx(
|
|
86
|
+
open && /* @__PURE__ */ jsx(FloatingPortal, { children: /* @__PURE__ */ jsx(FloatingFocusManager, { context, modal: false, children: /* @__PURE__ */ jsx(
|
|
75
87
|
"div",
|
|
76
88
|
{
|
|
89
|
+
ref: refs.setFloating,
|
|
77
90
|
role: "menu",
|
|
91
|
+
style: floatingStyles,
|
|
78
92
|
className: cn(
|
|
79
|
-
"
|
|
80
|
-
align === "right" ? "right-0" : "left-0",
|
|
93
|
+
"z-[9999] min-w-[8rem] rounded-md border border-border bg-popover py-1 shadow-md",
|
|
81
94
|
menuClassName
|
|
82
95
|
),
|
|
96
|
+
...getFloatingProps(),
|
|
83
97
|
children: children ? children(closeMenu) : items == null ? void 0 : items.map((item, i) => /* @__PURE__ */ jsxs(
|
|
84
98
|
"button",
|
|
85
99
|
{
|
|
100
|
+
ref: (node) => {
|
|
101
|
+
listRef.current[i] = node;
|
|
102
|
+
},
|
|
86
103
|
type: "button",
|
|
87
104
|
role: "menuitem",
|
|
105
|
+
tabIndex: i === activeIndex ? 0 : -1,
|
|
88
106
|
disabled: item.disabled,
|
|
89
107
|
title: item.title,
|
|
90
|
-
onClick: () => {
|
|
91
|
-
item.onSelect();
|
|
92
|
-
closeMenu();
|
|
93
|
-
},
|
|
94
108
|
className: "flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50",
|
|
109
|
+
...getItemProps({
|
|
110
|
+
onClick: () => {
|
|
111
|
+
item.onSelect();
|
|
112
|
+
closeMenu();
|
|
113
|
+
},
|
|
114
|
+
onKeyDown: (event) => {
|
|
115
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
116
|
+
event.preventDefault();
|
|
117
|
+
item.onSelect();
|
|
118
|
+
closeMenu();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}),
|
|
95
122
|
children: [
|
|
96
123
|
item.icon && /* @__PURE__ */ jsx(
|
|
97
124
|
Icon,
|
|
@@ -105,7 +132,7 @@ function DropdownMenu({
|
|
|
105
132
|
i
|
|
106
133
|
))
|
|
107
134
|
}
|
|
108
|
-
)
|
|
135
|
+
) }) })
|
|
109
136
|
] });
|
|
110
137
|
}
|
|
111
138
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownMenu.js","sources":["../../src/overlay/DropdownMenu.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Button, type ButtonProps } from \"../components/button\";\nimport { Icon, type StaticIconComponent } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\n\nexport type DropdownMenuItem = {\n /** Visible label. */\n label: ReactNode;\n /** Called when the item is chosen. */\n onSelect: () => void;\n /** Iconify name or imported icon component rendered before the label. */\n icon?: string | StaticIconComponent;\n /** Browser tooltip for the item. */\n title?: string;\n /** Disable selection. */\n disabled?: boolean;\n};\n\nexport type DropdownMenuProps = {\n /** Trigger label. Ignored when `trigger` is provided. */\n label?: ReactNode;\n /** Icon shown before the trigger label. Ignored when `trigger` is provided. */\n icon?: string | StaticIconComponent;\n /** Hide the trailing chevron on the default trigger. */\n hideChevron?: boolean;\n /** Variant forwarded to the default Button trigger. */\n variant?: ButtonProps[\"variant\"];\n /** Size forwarded to the default Button trigger. */\n size?: ButtonProps[\"size\"];\n /** Fully custom trigger. Receives no props; the menu wraps it with open state. */\n trigger?: ReactNode;\n /** Declarative menu items. Provide this or `children`, not both. */\n items?: DropdownMenuItem[];\n /** Custom menu content. Use `closeMenu` to dismiss after a selection. */\n children?: (closeMenu: () => void) => ReactNode;\n /** Horizontal alignment of the menu relative to the trigger. */\n align?: \"left\" | \"right\";\n /** Notified whenever the menu opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /** Browser tooltip / accessible label for the default trigger. */\n title?: string;\n /** Classes applied to the wrapper. */\n className?: string;\n /** Classes applied to the floating menu. */\n menuClassName?: string;\n};\n\nexport function DropdownMenu({\n label,\n icon,\n hideChevron = false,\n variant = \"outline\",\n size = \"sm\",\n trigger,\n items,\n children,\n align = \"right\",\n onOpenChange,\n title,\n className,\n menuClassName,\n}: DropdownMenuProps) {\n const [open, setOpen] = useState(false);\n const
|
|
1
|
+
{"version":3,"file":"DropdownMenu.js","sources":["../../src/overlay/DropdownMenu.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingPortal,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useInteractions,\n useListNavigation,\n useRole,\n} from \"@floating-ui/react\";\nimport { cn } from \"../lib/utils\";\nimport { Button, type ButtonProps } from \"../components/button\";\nimport { Icon, type StaticIconComponent } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\n\nexport type DropdownMenuItem = {\n /** Visible label. */\n label: ReactNode;\n /** Called when the item is chosen. */\n onSelect: () => void;\n /** Iconify name or imported icon component rendered before the label. */\n icon?: string | StaticIconComponent;\n /** Browser tooltip for the item. */\n title?: string;\n /** Disable selection. */\n disabled?: boolean;\n};\n\nexport type DropdownMenuProps = {\n /** Trigger label. Ignored when `trigger` is provided. */\n label?: ReactNode;\n /** Icon shown before the trigger label. Ignored when `trigger` is provided. */\n icon?: string | StaticIconComponent;\n /** Hide the trailing chevron on the default trigger. */\n hideChevron?: boolean;\n /** Variant forwarded to the default Button trigger. */\n variant?: ButtonProps[\"variant\"];\n /** Size forwarded to the default Button trigger. */\n size?: ButtonProps[\"size\"];\n /** Fully custom trigger. Receives no props; the menu wraps it with open state. */\n trigger?: ReactNode;\n /** Declarative menu items. Provide this or `children`, not both. */\n items?: DropdownMenuItem[];\n /** Custom menu content. Use `closeMenu` to dismiss after a selection. */\n children?: (closeMenu: () => void) => ReactNode;\n /** Horizontal alignment of the menu relative to the trigger. */\n align?: \"left\" | \"right\";\n /** Notified whenever the menu opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /** Browser tooltip / accessible label for the default trigger. */\n title?: string;\n /** Classes applied to the wrapper. */\n className?: string;\n /** Classes applied to the floating menu. */\n menuClassName?: string;\n};\n\nexport function DropdownMenu({\n label,\n icon,\n hideChevron = false,\n variant = \"outline\",\n size = \"sm\",\n trigger,\n items,\n children,\n align = \"right\",\n onOpenChange,\n title,\n className,\n menuClassName,\n}: DropdownMenuProps) {\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const listRef = useRef<(HTMLElement | null)[]>([]);\n\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n useEffect(() => {\n onOpenChangeRef.current?.(open);\n }, [open]);\n\n const { refs, floatingStyles, context } = useFloating<HTMLDivElement>({\n open,\n onOpenChange: setOpen,\n // bottom-end / bottom-start reproduce the previous right/left alignment.\n placement: align === \"right\" ? \"bottom-end\" : \"bottom-start\",\n whileElementsMounted: autoUpdate,\n // offset(4) ≈ the previous mt-1; flip opens upward at the bottom edge and\n // shift slides the menu back on-screen at the horizontal edges.\n middleware: [offset(4), flip({ padding: 8 }), shift({ padding: 8 })],\n });\n\n const click = useClick(context);\n const dismiss = useDismiss(context);\n const role = useRole(context, { role: \"menu\" });\n const listNav = useListNavigation(context, {\n listRef,\n activeIndex,\n onNavigate: setActiveIndex,\n loop: true,\n });\n\n const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([\n click,\n dismiss,\n role,\n listNav,\n ]);\n\n const closeMenu = () => setOpen(false);\n\n return (\n <div className={cn(\"relative inline-flex\", className)}>\n {trigger ? (\n <span\n ref={refs.setReference}\n className=\"inline-flex\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {trigger}\n </span>\n ) : (\n <Button\n ref={refs.setReference as React.Ref<HTMLButtonElement>}\n variant={variant}\n size={size}\n title={title}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {icon && <Icon {...(typeof icon === \"string\" ? { name: icon } : { icon })} />}\n {label}\n {!hideChevron && <Icon icon={UiChevronDown} />}\n </Button>\n )}\n {open && (\n <FloatingPortal>\n <FloatingFocusManager context={context} modal={false}>\n <div\n ref={refs.setFloating}\n role=\"menu\"\n style={floatingStyles}\n className={cn(\n \"z-[9999] min-w-[8rem] rounded-md border border-border bg-popover py-1 shadow-md\",\n menuClassName,\n )}\n {...getFloatingProps()}\n >\n {children\n ? children(closeMenu)\n : items?.map((item, i) => (\n <button\n key={i}\n ref={(node) => {\n listRef.current[i] = node;\n }}\n type=\"button\"\n role=\"menuitem\"\n tabIndex={i === activeIndex ? 0 : -1}\n disabled={item.disabled}\n title={item.title}\n className=\"flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n {...getItemProps({\n onClick: () => {\n item.onSelect();\n closeMenu();\n },\n onKeyDown: (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n item.onSelect();\n closeMenu();\n }\n },\n })}\n >\n {item.icon && (\n <Icon\n {...(typeof item.icon === \"string\"\n ? { name: item.icon }\n : { icon: item.icon })}\n />\n )}\n {item.label}\n </button>\n ))}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|