@enigmax/primitives 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-3BQVOOAM.js +388 -0
- package/dist/{chunk-QQFNAKMY.js → chunk-45UHLZYT.js} +1 -1
- package/dist/chunk-4VUHQFAT.js +130 -0
- package/dist/{chunk-D5A2ZMAG.js → chunk-4ZPMP47J.js} +6 -1
- package/dist/chunk-DSBYVA7V.js +713 -0
- package/dist/{chunk-FWVWX67R.js → chunk-FGBIZDV2.js} +3 -3
- package/dist/{chunk-R4ZAEE7V.js → chunk-KEVZ5XQV.js} +1 -1
- package/dist/chunk-N6PDHMAX.js +213 -0
- package/dist/chunk-NONGREXC.js +248 -0
- package/dist/chunk-VKL3DEIQ.js +804 -0
- package/dist/chunk-WSQC3PCC.js +466 -0
- package/dist/context-menu-D3FtTn7v.d.ts +174 -0
- package/dist/{index-BHpOZncw.d.ts → index-DQNnohoo.d.ts} +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +8 -4
- package/dist/keys-D2zJs1uB.d.ts +100 -0
- package/dist/next/index.d.ts +9 -2
- package/dist/next/index.js +20 -13
- package/dist/react/context-menu.d.ts +202 -0
- package/dist/react/context-menu.js +6 -0
- package/dist/react/index.d.ts +10 -3
- package/dist/react/index.js +19 -12
- package/dist/react/input.d.ts +2 -2
- package/dist/react/input.js +1 -1
- package/dist/react/palette.d.ts +1 -1
- package/dist/react/palette.js +3 -3
- package/dist/react/search.d.ts +1 -1
- package/dist/react/search.js +2 -2
- package/dist/react/select.d.ts +217 -0
- package/dist/react/select.js +7 -0
- package/dist/react/selection.d.ts +104 -0
- package/dist/react/selection.js +4 -0
- package/dist/react-router/index.d.ts +9 -2
- package/dist/react-router/index.js +20 -13
- package/dist/search/index.d.ts +2 -2
- package/dist/search/index.js +1 -1
- package/dist/{search-BD9-5O5U.d.ts → search-DYgqRp37.d.ts} +13 -1
- package/dist/{search-UQEXAPQB.js → search-PBZORZ7P.js} +1 -1
- package/dist/select-ClSy-J1f.d.ts +100 -0
- package/dist/selection-B_pmzHpy.d.ts +150 -0
- package/package.json +21 -2
- package/recipes/context-menu/styles.css +177 -0
- package/recipes/input/styles.css +9 -0
- package/recipes/palette/styles.css +3 -0
- package/recipes/search/tailwind.tsx +3 -2
- package/recipes/select/styles.css +230 -0
- package/recipes/toast/styles.css +1 -1
- package/registry.json +358 -1
- package/src/core/context-menu.ts +694 -0
- package/src/core/keys.ts +264 -0
- package/src/core/search.ts +19 -0
- package/src/core/select.ts +404 -0
- package/src/core/selection.ts +648 -0
- package/src/index.ts +60 -1
- package/src/react/context-menu/context.ts +57 -0
- package/src/react/context-menu/index.tsx +94 -0
- package/src/react/context-menu/root.tsx +846 -0
- package/src/react/context-menu/styles.ts +186 -0
- package/src/react/index.ts +68 -1
- package/src/react/palette/root.tsx +2 -2
- package/src/react/select/context.ts +56 -0
- package/src/react/select/index.tsx +96 -0
- package/src/react/select/root.tsx +839 -0
- package/src/react/select/styles.ts +238 -0
- package/src/react/selection/index.tsx +115 -0
- package/src/react/selection/use-selection.ts +260 -0
- /package/dist/{chunk-U3V4EHOB.js → chunk-3HDEZ2E7.js} +0 -0
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { createMarquee, type MarqueeOptions, type MarqueeInstance, type MarqueeHover } from "@/core/marquee";
|
|
2
2
|
export { createInput, type InputOptions, type InputInstance, type InputAction, type InputIcon, type InputActionState } from "@/core/input";
|
|
3
|
-
export { createSearch, subsequenceMatcher, type SearchOptions, type SearchInstance, type SearchMatch, type FuseConstructor, type FuseLike } from "@/core/search";
|
|
3
|
+
export { createSearch, subsequenceMatcher, shortenQuery, type SearchOptions, type SearchInstance, type SearchMatch, type FuseConstructor, type FuseLike } from "@/core/search";
|
|
4
4
|
export { createButton, type ButtonOptions, type ButtonInstance, type ButtonState, type ButtonElement, type ButtonCooldown } from "@/core/button";
|
|
5
5
|
export { INPUT_ICON_PATHS, iconMarkup } from "@/core/input";
|
|
6
6
|
export {
|
|
@@ -61,3 +61,62 @@ export {
|
|
|
61
61
|
type PositionedRow,
|
|
62
62
|
type PaletteKey
|
|
63
63
|
} from "@/core/palette";
|
|
64
|
+
// The select's non-rendering half, for the same reason as the palette's: the selection
|
|
65
|
+
// rules, the filter and the highlight are arithmetic, not React.
|
|
66
|
+
export {
|
|
67
|
+
createSelect,
|
|
68
|
+
SELECT_SEARCH_KEYS,
|
|
69
|
+
type SelectOption,
|
|
70
|
+
type SelectOptions,
|
|
71
|
+
type SelectInstance,
|
|
72
|
+
type SelectState,
|
|
73
|
+
type SelectMoveKey
|
|
74
|
+
} from "@/core/select";
|
|
75
|
+
// The context menu's non-rendering half: the tree, the highlight, the filter and the cache
|
|
76
|
+
// of a fetched submenu are arithmetic, so a renderer that is not React only has to draw.
|
|
77
|
+
export {
|
|
78
|
+
createContextMenu,
|
|
79
|
+
isAction,
|
|
80
|
+
CONTEXT_MENU_SEARCH_KEYS,
|
|
81
|
+
type ContextMenuEntry,
|
|
82
|
+
type ContextMenuAction,
|
|
83
|
+
type ContextMenuSeparator,
|
|
84
|
+
type ContextMenuLabel,
|
|
85
|
+
type ContextMenuOptions,
|
|
86
|
+
type ContextMenuInstance,
|
|
87
|
+
type ContextMenuState,
|
|
88
|
+
type ContextMenuLevel,
|
|
89
|
+
type ContextMenuPoint,
|
|
90
|
+
type ContextMenuMoveKey
|
|
91
|
+
} from "@/core/context-menu";
|
|
92
|
+
// The selection model, for the same reason: what a Ctrl+click does to a set is not React.
|
|
93
|
+
export {
|
|
94
|
+
createSelection,
|
|
95
|
+
DEFAULT_SELECTION_SHORTCUTS,
|
|
96
|
+
type SelectionCommand,
|
|
97
|
+
type SelectionCommandName,
|
|
98
|
+
type SelectionCommandEvent,
|
|
99
|
+
type SelectionShortcuts,
|
|
100
|
+
type SelectionOptions,
|
|
101
|
+
type SelectionInstance,
|
|
102
|
+
type SelectionState,
|
|
103
|
+
type SelectionClickModifiers
|
|
104
|
+
} from "@/core/selection";
|
|
105
|
+
// Shortcuts as data, shared by the two above: the menu PRINTS what the list LISTENS for, and
|
|
106
|
+
// a menu whose label says Ctrl+A over a list bound to Cmd+A is the defect that splitting them
|
|
107
|
+
// produces.
|
|
108
|
+
export {
|
|
109
|
+
parseShortcut,
|
|
110
|
+
matchesShortcut,
|
|
111
|
+
shortcutTokens,
|
|
112
|
+
shortcutText,
|
|
113
|
+
shortcutList,
|
|
114
|
+
isApplePlatform,
|
|
115
|
+
typeaheadStep,
|
|
116
|
+
TYPEAHEAD_MS,
|
|
117
|
+
type Shortcut,
|
|
118
|
+
type ShortcutSpec,
|
|
119
|
+
type ShortcutEvent,
|
|
120
|
+
type TypeaheadState,
|
|
121
|
+
type TypeaheadStep
|
|
122
|
+
} from "@/core/keys";
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext } from "react";
|
|
4
|
+
import type { ReactNode, RefObject } from "react";
|
|
5
|
+
import type { ContextMenuAction, ContextMenuEntry, ContextMenuInstance, ContextMenuPoint, ContextMenuState } from "@/core/context-menu";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* One row, as React draws it. The core carries `icon` as `unknown` because it cannot know
|
|
9
|
+
* what a node is; here it is one.
|
|
10
|
+
*/
|
|
11
|
+
export interface ContextMenuItem extends Omit<ContextMenuAction, "icon" | "items"> {
|
|
12
|
+
icon?: ReactNode;
|
|
13
|
+
items?: readonly ContextMenuNode[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Anything that can appear in a menu, with React's icon type. */
|
|
17
|
+
export type ContextMenuNode = ContextMenuItem | Exclude<ContextMenuEntry, ContextMenuAction>;
|
|
18
|
+
|
|
19
|
+
export interface ContextMenuContextValue {
|
|
20
|
+
instance: ContextMenuInstance;
|
|
21
|
+
state: ContextMenuState;
|
|
22
|
+
/** Open at a point. False when there was nothing to show, so the press is left alone. */
|
|
23
|
+
open: (point: ContextMenuPoint) => boolean;
|
|
24
|
+
close: () => void;
|
|
25
|
+
/** ids the parts need to point at each other. */
|
|
26
|
+
ids: { trigger: string; };
|
|
27
|
+
panelId: (level: number) => string;
|
|
28
|
+
itemId: (level: number, index: number) => string;
|
|
29
|
+
triggerRef: RefObject<HTMLElement | null>;
|
|
30
|
+
/** Which panel the keyboard is in. Always the deepest open one. */
|
|
31
|
+
onMenuKeyDown: (event: React.KeyboardEvent) => void;
|
|
32
|
+
/** How long the pointer must rest on a row before its submenu opens, and before one closes. */
|
|
33
|
+
delays: { open: number; close: number; };
|
|
34
|
+
/** Drop the pending close, wherever it was scheduled. Called wherever the pointer lands. */
|
|
35
|
+
cancelClose: () => void;
|
|
36
|
+
/** Close everything below `level`, after the beat - replacing any close already waiting. */
|
|
37
|
+
scheduleClose: (level: number) => void;
|
|
38
|
+
/** Draw a row instead of the default icon / label / shortcut. */
|
|
39
|
+
renderItem?: (item: ContextMenuItem, level: number, index: number) => ReactNode;
|
|
40
|
+
/** Shown while a fetched submenu has not answered. */
|
|
41
|
+
loadingLabel: ReactNode;
|
|
42
|
+
/** Shown when a filter matched nothing, or a fetched submenu came back with nothing. */
|
|
43
|
+
emptyLabel: ReactNode;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Null rather than a default: a part rendered outside its Root is a mistake with an obvious
|
|
48
|
+
* fix, and a silent default would leave it half-working - a trigger that opens nothing, a row
|
|
49
|
+
* that invokes into the void.
|
|
50
|
+
*/
|
|
51
|
+
export const ContextMenuContext = createContext<ContextMenuContextValue | null>(null);
|
|
52
|
+
|
|
53
|
+
export function useContextMenuContext(part: string): ContextMenuContextValue {
|
|
54
|
+
const value = useContext(ContextMenuContext);
|
|
55
|
+
if (!value) throw new Error(`<${part}> must be rendered inside <ContextMenu.Root>.`);
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { ReactNode } from "react";
|
|
4
|
+
import * as parts from "@/react/context-menu/root";
|
|
5
|
+
import { useContextMenuContext } from "@/react/context-menu/context";
|
|
6
|
+
import type { ContextMenuRootProps, ContextMenuTriggerProps, ContextMenuContentProps } from "@/react/context-menu/root";
|
|
7
|
+
|
|
8
|
+
export type ContextMenuProps = ContextMenuRootProps & {
|
|
9
|
+
/** How many rows to put in the document at once. `Infinity` renders the lot. */
|
|
10
|
+
chunk?: ContextMenuContentProps["chunk"];
|
|
11
|
+
/** Open on a long press as well, which is what a right-click is on a touch screen. */
|
|
12
|
+
longPress?: boolean;
|
|
13
|
+
triggerProps?: ContextMenuTriggerProps;
|
|
14
|
+
contentProps?: ContextMenuContentProps;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The context menu, assembled.
|
|
19
|
+
*
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <ContextMenu
|
|
22
|
+
* title={file.name}
|
|
23
|
+
* items={[
|
|
24
|
+
* { id: "rename", label: "Rename", shortcut: "F2", icon: <Pencil /> },
|
|
25
|
+
* { type: "separator" },
|
|
26
|
+
* { id: "delete", label: "Delete", shortcut: "Delete", destructive: true }
|
|
27
|
+
* ]}
|
|
28
|
+
* onSelect={(item) => run(item.id)}
|
|
29
|
+
* >
|
|
30
|
+
* <FileRow file={file} />
|
|
31
|
+
* </ContextMenu>
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* Everything it renders is a part you can render yourself instead - see `ContextMenu.Root`
|
|
35
|
+
* for the anatomy. This is those parts in the order they belong in, not a different
|
|
36
|
+
* component: the children become the area a right-click opens the menu over.
|
|
37
|
+
*
|
|
38
|
+
* A menu with no rows to show does not open, and the press falls through to the browser's own
|
|
39
|
+
* menu - an empty box at the pointer tells the reader nothing, and swallowing the press to
|
|
40
|
+
* show one tells them less.
|
|
41
|
+
*/
|
|
42
|
+
export function ContextMenu(props: ContextMenuProps): ReactNode {
|
|
43
|
+
const { chunk, longPress, triggerProps, contentProps, children, ...rest } = props;
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<parts.ContextMenuRoot {...rest}>
|
|
47
|
+
<parts.ContextMenuTrigger longPress={longPress} {...triggerProps}>{children}</parts.ContextMenuTrigger>
|
|
48
|
+
<parts.ContextMenuContent chunk={chunk} {...contentProps} />
|
|
49
|
+
</parts.ContextMenuRoot>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
ContextMenu.Root = parts.ContextMenuRoot;
|
|
54
|
+
ContextMenu.Trigger = parts.ContextMenuTrigger;
|
|
55
|
+
ContextMenu.Content = parts.ContextMenuContent;
|
|
56
|
+
ContextMenu.Panel = parts.ContextMenuPanel;
|
|
57
|
+
ContextMenu.Search = parts.ContextMenuSearch;
|
|
58
|
+
ContextMenu.List = parts.ContextMenuList;
|
|
59
|
+
ContextMenu.Item = parts.ContextMenuRow;
|
|
60
|
+
|
|
61
|
+
export {
|
|
62
|
+
ContextMenuRoot,
|
|
63
|
+
ContextMenuTrigger,
|
|
64
|
+
ContextMenuContent,
|
|
65
|
+
ContextMenuPanel,
|
|
66
|
+
ContextMenuSearch,
|
|
67
|
+
ContextMenuList,
|
|
68
|
+
ContextMenuRow,
|
|
69
|
+
type ContextMenuRootProps,
|
|
70
|
+
type ContextMenuTriggerProps,
|
|
71
|
+
type ContextMenuContentProps,
|
|
72
|
+
type ContextMenuPanelProps,
|
|
73
|
+
type ContextMenuSearchProps,
|
|
74
|
+
type ContextMenuListProps,
|
|
75
|
+
type ContextMenuRowProps
|
|
76
|
+
} from "@/react/context-menu/root";
|
|
77
|
+
export { useContextMenuContext, type ContextMenuItem, type ContextMenuNode, type ContextMenuContextValue } from "@/react/context-menu/context";
|
|
78
|
+
export {
|
|
79
|
+
createContextMenu,
|
|
80
|
+
isAction,
|
|
81
|
+
CONTEXT_MENU_SEARCH_KEYS,
|
|
82
|
+
type ContextMenuEntry,
|
|
83
|
+
type ContextMenuAction,
|
|
84
|
+
type ContextMenuSeparator,
|
|
85
|
+
type ContextMenuLabel,
|
|
86
|
+
type ContextMenuOptions,
|
|
87
|
+
type ContextMenuInstance,
|
|
88
|
+
type ContextMenuState,
|
|
89
|
+
type ContextMenuLevel,
|
|
90
|
+
type ContextMenuPoint,
|
|
91
|
+
type ContextMenuMoveKey
|
|
92
|
+
} from "@/core/context-menu";
|
|
93
|
+
export { CONTEXT_MENU_STYLES } from "@/react/context-menu/styles";
|
|
94
|
+
export { shortcutTokens, shortcutText, parseShortcut, matchesShortcut, type Shortcut, type ShortcutSpec } from "@/core/keys";
|