@enigmax/primitives 0.17.0 → 0.19.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/button-CaXaqG_K.d.ts +63 -0
- package/dist/chunk-2QFTRNAZ.js +88 -0
- package/dist/chunk-6BGBYUSZ.js +114 -0
- package/dist/chunk-AU3H5WIY.js +107 -0
- package/dist/{chunk-UZFEEFMF.js → chunk-D5A2ZMAG.js} +34 -1
- package/dist/chunk-DTWZDONY.js +99 -0
- package/dist/chunk-F25CGNQC.js +19 -0
- package/dist/chunk-FWVWX67R.js +462 -0
- package/dist/chunk-HC2ME5PU.js +168 -0
- package/dist/chunk-HS3X3XCW.js +43 -0
- package/dist/chunk-IXVMRVD4.js +96 -0
- package/dist/chunk-KJINGUQN.js +188 -0
- package/dist/chunk-MMQPZGSU.js +161 -0
- package/dist/chunk-OCMI7R6H.js +79 -0
- package/dist/chunk-QQFNAKMY.js +47 -0
- package/dist/chunk-QYMUIW5I.js +28 -0
- package/dist/chunk-R4ZAEE7V.js +249 -0
- package/dist/chunk-S653GLSF.js +17 -0
- package/dist/chunk-SNYUBXWQ.js +149 -0
- package/dist/chunk-U3V4EHOB.js +41 -0
- package/dist/chunk-UOSSNUSC.js +309 -0
- package/dist/chunk-XNNQRA35.js +31 -0
- package/dist/chunk-XQHCZAPJ.js +102 -0
- package/dist/chunk-ZCUFYBPB.js +154 -0
- package/dist/chunk-ZWR2EXHQ.js +55 -0
- package/dist/flags-BBJc9unY.d.ts +133 -0
- package/dist/index-dTdAbOWl.d.ts +144 -0
- package/dist/index.d.ts +18 -603
- package/dist/index.js +11 -2
- package/dist/input-BwXjFenq.d.ts +77 -0
- package/dist/marquee-CJ3Uwy3E.d.ts +81 -0
- package/dist/network-D2LsBG_k.d.ts +39 -0
- package/dist/next/index.d.ts +22 -4
- package/dist/next/index.js +25 -4
- package/dist/notifications-BpVV6sel.d.ts +70 -0
- package/dist/palette-D7iuQh_T.d.ts +86 -0
- package/dist/password-3DRQYAYQ.js +2 -0
- package/dist/password-C8lG4Zm9.d.ts +71 -0
- package/dist/password-FB2CUEKJ.js +1 -0
- package/dist/react/button.d.ts +75 -0
- package/dist/react/button.js +4 -0
- package/dist/react/flag.d.ts +37 -0
- package/dist/react/flag.js +3 -0
- package/dist/react/index.d.ts +29 -312
- package/dist/react/index.js +24 -3
- package/dist/react/input.d.ts +4 -0
- package/dist/react/input.js +3 -0
- package/dist/react/marquee.d.ts +44 -0
- package/dist/react/marquee.js +3 -0
- package/dist/react/network.d.ts +20 -0
- package/dist/react/network.js +3 -0
- package/dist/react/notifications.d.ts +17 -0
- package/dist/react/notifications.js +3 -0
- package/dist/react/palette.d.ts +231 -0
- package/dist/react/palette.js +5 -0
- package/dist/react/relative-time.d.ts +21 -0
- package/dist/react/relative-time.js +3 -0
- package/dist/react/search.d.ts +30 -0
- package/dist/react/search.js +3 -0
- package/dist/react/slot.d.ts +47 -0
- package/dist/react/slot.js +2 -0
- package/dist/react/toast.d.ts +40 -0
- package/dist/react/toast.js +4 -0
- package/dist/react-router/index.d.ts +22 -4
- package/dist/react-router/index.js +25 -4
- package/dist/relative-time-YpRTG7YH.d.ts +106 -0
- package/dist/search/index.d.ts +2 -2
- package/dist/search/index.js +1 -1
- package/dist/{search-CsO3L1Lw.d.ts → search-DXxY8SEH.d.ts} +15 -1
- package/dist/search-UQEXAPQB.js +50 -0
- package/package.json +54 -3
- package/recipes/input/styles.css +60 -20
- package/recipes/palette/styles.css +243 -0
- package/registry.json +186 -18
- package/src/core/flags.ts +88 -42
- package/src/core/input-icons.ts +34 -0
- package/src/core/input.ts +5 -21
- package/src/core/palette.ts +0 -0
- package/src/core/search.ts +60 -0
- package/src/index.ts +19 -3
- package/src/react/button.tsx +70 -4
- package/src/react/flag.tsx +18 -6
- package/src/react/index.ts +50 -5
- package/src/react/input/icon.tsx +17 -0
- package/src/react/input/index.tsx +307 -0
- package/src/react/input/password.tsx +174 -0
- package/src/react/input/search.tsx +82 -0
- package/src/react/input/types.ts +146 -0
- package/src/react/input/write-value.ts +18 -0
- package/src/react/palette/context.ts +60 -0
- package/src/react/palette/index.tsx +66 -0
- package/src/react/palette/root.tsx +661 -0
- package/src/react/slot.tsx +91 -0
- package/src/react/use-button.ts +3 -1
- package/dist/chunk-4GLYRF4B.js +0 -1259
- package/dist/chunk-JFNND6P4.js +0 -749
- package/src/react/input.tsx +0 -429
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
2
|
+
import { b as SearchMatch, c as SearchOptions } from '../search-DXxY8SEH.js';
|
|
3
|
+
import { R as RecentEntry } from '../palette-D7iuQh_T.js';
|
|
4
|
+
|
|
5
|
+
/** One line in the palette, whatever it came from. */
|
|
6
|
+
interface PaletteRow<Item> {
|
|
7
|
+
/** Stable within a render. Used for React keys and for `aria-activedescendant`. */
|
|
8
|
+
id: string;
|
|
9
|
+
/** Which group it appears under. */
|
|
10
|
+
group: string;
|
|
11
|
+
/** `item` for a result, `recent` for a memory, `action` for a row the app declared. */
|
|
12
|
+
kind: "item" | "recent" | "action";
|
|
13
|
+
item?: Item;
|
|
14
|
+
recent?: RecentEntry;
|
|
15
|
+
/** Set for a result that came from the engine, so a renderer can show the score. */
|
|
16
|
+
match?: SearchMatch<Item>;
|
|
17
|
+
/** What running this row does. The palette closes afterwards unless this returns false. */
|
|
18
|
+
onSelect?: () => void | boolean;
|
|
19
|
+
label: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
}
|
|
22
|
+
interface PaletteContextValue<Item = unknown> {
|
|
23
|
+
open: boolean;
|
|
24
|
+
setOpen: (open: boolean) => void;
|
|
25
|
+
query: string;
|
|
26
|
+
setQuery: (query: string) => void;
|
|
27
|
+
rows: PaletteRow<Item>[];
|
|
28
|
+
active: number;
|
|
29
|
+
setActive: (index: number) => void;
|
|
30
|
+
/** Run a row: its own action, or the palette's `onSelect`, then remember it. */
|
|
31
|
+
select: (row: PaletteRow<Item> | undefined) => void;
|
|
32
|
+
/** Wipe the remembered searches. */
|
|
33
|
+
clearRecents: () => void;
|
|
34
|
+
forgetRecent: (entry: RecentEntry) => void;
|
|
35
|
+
/** True while the engine is loading or an async source is in flight. */
|
|
36
|
+
busy: boolean;
|
|
37
|
+
/** ids the parts need to point at each other. */
|
|
38
|
+
ids: {
|
|
39
|
+
field: string;
|
|
40
|
+
list: string;
|
|
41
|
+
title: string;
|
|
42
|
+
};
|
|
43
|
+
/** `Ctrl K` or `⌘ K`, whichever this platform uses. */
|
|
44
|
+
shortcutLabel: string;
|
|
45
|
+
triggerRef: {
|
|
46
|
+
current: HTMLElement | null;
|
|
47
|
+
};
|
|
48
|
+
fieldRef: {
|
|
49
|
+
current: HTMLInputElement | null;
|
|
50
|
+
};
|
|
51
|
+
rowId: (row: PaletteRow<Item>) => string;
|
|
52
|
+
}
|
|
53
|
+
declare function usePaletteContext<Item = unknown>(part: string): PaletteContextValue<Item>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The command palette: the panel that opens on Ctrl/Cmd+K, searches as you type, remembers
|
|
57
|
+
* what was searched before, and is driven entirely from the keyboard.
|
|
58
|
+
*
|
|
59
|
+
* It is a DIALOG, which is why it is its own component rather than a prop on `<Input>`: a
|
|
60
|
+
* palette is a trigger, an overlay, a focus trap, a listbox and a footer, and the thing that
|
|
61
|
+
* makes those usable together is composition. Radix draws the line in the same place, and
|
|
62
|
+
* for the same reason - one `<input>` is a component, a widget made of parts is an anatomy:
|
|
63
|
+
*
|
|
64
|
+
* ```tsx
|
|
65
|
+
* <SearchPalette.Root items={docs} keys={["title"]} onSelect={open}>
|
|
66
|
+
* <SearchPalette.Trigger />
|
|
67
|
+
* <SearchPalette.Content>
|
|
68
|
+
* <SearchPalette.Field placeholder="Search the docs" />
|
|
69
|
+
* <SearchPalette.List />
|
|
70
|
+
* <SearchPalette.Footer />
|
|
71
|
+
* </SearchPalette.Content>
|
|
72
|
+
* </SearchPalette.Root>
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* `<SearchPalette>` on its own renders exactly that, for the case that needs no arguing
|
|
76
|
+
* with. Every part takes `asChild`, so any of them can be your own element instead.
|
|
77
|
+
*
|
|
78
|
+
* The keyboard sequence is ONE flat list across every group - a group boundary is invisible
|
|
79
|
+
* to the arrow keys - and the highlight wraps, because in a short list the row after the
|
|
80
|
+
* last one is the first, and a key that does nothing at the end reads as a frozen panel.
|
|
81
|
+
*/
|
|
82
|
+
interface PaletteSection<Item> {
|
|
83
|
+
label: string;
|
|
84
|
+
items: Item[];
|
|
85
|
+
/** Shown whatever the query, e.g. a list of commands. Off by default. */
|
|
86
|
+
always?: boolean;
|
|
87
|
+
}
|
|
88
|
+
interface PaletteRootProps<Item> {
|
|
89
|
+
/** What to search. */
|
|
90
|
+
items?: Item[];
|
|
91
|
+
/** Fields to read. Dotted paths work. */
|
|
92
|
+
keys?: SearchOptions<Item>["keys"];
|
|
93
|
+
/** Fuse.js's constructor, for fuzzy matching. Without it, a substring matcher runs. */
|
|
94
|
+
fuse?: SearchOptions<Item>["fuse"];
|
|
95
|
+
fuseOptions?: SearchOptions<Item>["fuseOptions"];
|
|
96
|
+
/** Replaces the engine outright. */
|
|
97
|
+
matcher?: SearchOptions<Item>["matcher"];
|
|
98
|
+
/** ms after the last keystroke. Default 120: a palette should feel immediate. */
|
|
99
|
+
delay?: number;
|
|
100
|
+
limit?: number;
|
|
101
|
+
/** Which group a result belongs under. One group when this is left out. */
|
|
102
|
+
groupBy?: (item: Item) => string;
|
|
103
|
+
/** The row's text. Falls back to the first string field. */
|
|
104
|
+
labelOf?: (item: Item) => string;
|
|
105
|
+
descriptionOf?: (item: Item) => string | undefined;
|
|
106
|
+
/** Rows the app always offers - commands, shortcuts, "create new". */
|
|
107
|
+
sections?: PaletteSection<Item>[];
|
|
108
|
+
/** What running a row does. Closing afterwards is the default; return false to stay. */
|
|
109
|
+
onSelect?: (item: Item) => void | boolean;
|
|
110
|
+
/** Remember what was searched, in this browser. On by default. */
|
|
111
|
+
recents?: boolean;
|
|
112
|
+
recentsKey?: string;
|
|
113
|
+
recentsLimit?: number;
|
|
114
|
+
/** The key that opens it, with Ctrl or Cmd. `null` binds nothing. Default "k". */
|
|
115
|
+
shortcut?: string | null;
|
|
116
|
+
/** Controlled open state. Leave both out for an uncontrolled palette. */
|
|
117
|
+
open?: boolean;
|
|
118
|
+
onOpenChange?: (open: boolean) => void;
|
|
119
|
+
defaultOpen?: boolean;
|
|
120
|
+
/** Wording for the empty group heading of ungrouped results. Default "Results". */
|
|
121
|
+
resultsLabel?: string;
|
|
122
|
+
recentsLabel?: string;
|
|
123
|
+
children?: ReactNode;
|
|
124
|
+
}
|
|
125
|
+
declare function PaletteRoot<Item>({ items, keys, fuse, fuseOptions, matcher, delay, limit, groupBy, labelOf, descriptionOf, sections, onSelect, recents, recentsKey, recentsLimit, shortcut, open: openProp, onOpenChange, defaultOpen, resultsLabel, recentsLabel, children }: PaletteRootProps<Item>): ReactNode;
|
|
126
|
+
interface PaletteTriggerProps extends ComponentPropsWithoutRef<"button"> {
|
|
127
|
+
asChild?: boolean;
|
|
128
|
+
}
|
|
129
|
+
/** Opens the palette. Carries the shortcut in `aria-keyshortcuts`, so it is announced. */
|
|
130
|
+
declare function PaletteTrigger({ asChild, children, onClick, ...props }: PaletteTriggerProps): ReactNode;
|
|
131
|
+
interface PaletteContentProps extends ComponentPropsWithoutRef<"div"> {
|
|
132
|
+
/** Accessible name for the dialog. Rendered for screen readers only. */
|
|
133
|
+
title?: string;
|
|
134
|
+
/** Render into `document.body`. On by default: a palette inside a clipped or
|
|
135
|
+
* transformed ancestor is a panel nobody can see. */
|
|
136
|
+
portal?: boolean;
|
|
137
|
+
/** Rendered behind the panel. Pass null for no overlay of ours. */
|
|
138
|
+
overlayProps?: ComponentPropsWithoutRef<"div"> | null;
|
|
139
|
+
/**
|
|
140
|
+
* How long the closing animation is given before the panel leaves the DOM, in ms.
|
|
141
|
+
*
|
|
142
|
+
* It exists because a component that unmounts on close can only ever animate IN: the
|
|
143
|
+
* element is gone before a leaving animation has a frame to run. `data-state="closed"`
|
|
144
|
+
* is set first, the stylesheet animates it, and only then does it unmount. 0 removes it
|
|
145
|
+
* immediately, which is also what a reader with reduced motion gets.
|
|
146
|
+
*/
|
|
147
|
+
closeDuration?: number;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The panel: overlay, focus trap, Escape, scroll lock, and focus handed back to the trigger.
|
|
151
|
+
*
|
|
152
|
+
* Mounted only while open, so nothing of the palette is in the document (or in the tab
|
|
153
|
+
* order) the rest of the time.
|
|
154
|
+
*/
|
|
155
|
+
declare function PaletteContent({ title, portal, overlayProps, closeDuration, children, ...props }: PaletteContentProps): ReactNode;
|
|
156
|
+
interface PaletteFieldProps extends Omit<ComponentPropsWithoutRef<"input">, "value" | "onChange"> {
|
|
157
|
+
asChild?: boolean;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The query field.
|
|
161
|
+
*
|
|
162
|
+
* A `combobox` that keeps the caret while the arrows move a highlight somewhere else -
|
|
163
|
+
* which is exactly what `aria-activedescendant` is for. Without it a screen reader hears
|
|
164
|
+
* nothing move, because focus never leaves the field.
|
|
165
|
+
*/
|
|
166
|
+
declare function PaletteField({ asChild, onKeyDown, ...props }: PaletteFieldProps): ReactNode;
|
|
167
|
+
interface PaletteListProps<Item> extends Omit<ComponentPropsWithoutRef<"div">, "children"> {
|
|
168
|
+
/** Render one row. The default prints its label, which is enough to be usable. */
|
|
169
|
+
children?: (row: PaletteRow<Item>, state: {
|
|
170
|
+
active: boolean;
|
|
171
|
+
index: number;
|
|
172
|
+
}) => ReactNode;
|
|
173
|
+
/** Rendered when there is nothing to show. */
|
|
174
|
+
empty?: ReactNode;
|
|
175
|
+
/** The group heading. Pass null for a flat list with no headings. */
|
|
176
|
+
heading?: ((label: string) => ReactNode) | null;
|
|
177
|
+
}
|
|
178
|
+
/** The results, grouped, with one flat keyboard sequence running through them. */
|
|
179
|
+
declare function PaletteList<Item>({ children, empty, heading, ...props }: PaletteListProps<Item>): ReactNode;
|
|
180
|
+
interface PaletteItemProps<Item> extends Omit<ComponentPropsWithoutRef<"div">, "children"> {
|
|
181
|
+
row: PaletteRow<Item>;
|
|
182
|
+
index: number;
|
|
183
|
+
children?: ReactNode;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* One row.
|
|
187
|
+
*
|
|
188
|
+
* The pointer MOVES the highlight rather than running a second one of its own: two
|
|
189
|
+
* highlights on screen is the thing that makes a palette feel unpredictable, because Enter
|
|
190
|
+
* then opens the row the mouse is not on.
|
|
191
|
+
*/
|
|
192
|
+
declare function PaletteItem<Item>({ row, index, children, ...props }: PaletteItemProps<Item>): ReactNode;
|
|
193
|
+
interface PaletteFooterProps extends ComponentPropsWithoutRef<"div"> {
|
|
194
|
+
/** Replace the hints. The default names the three keys that actually matter. */
|
|
195
|
+
hints?: ReactNode;
|
|
196
|
+
}
|
|
197
|
+
/** The strip along the bottom that says which keys do what. */
|
|
198
|
+
declare function PaletteFooter({ hints, children, ...props }: PaletteFooterProps): ReactNode;
|
|
199
|
+
|
|
200
|
+
interface SearchPaletteProps<Item> extends PaletteRootProps<Item> {
|
|
201
|
+
placeholder?: string;
|
|
202
|
+
/** The trigger's own content. Pass null for a palette that only opens on the shortcut. */
|
|
203
|
+
trigger?: ReactNode | null;
|
|
204
|
+
/** Render one row, same signature as `SearchPalette.List`. */
|
|
205
|
+
renderItem?: PaletteListProps<Item>["children"];
|
|
206
|
+
empty?: ReactNode;
|
|
207
|
+
footer?: ReactNode;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* The palette, assembled.
|
|
211
|
+
*
|
|
212
|
+
* ```tsx
|
|
213
|
+
* <SearchPalette items={docs} keys={["title", "body"]} onSelect={(doc) => go(doc.href)} />
|
|
214
|
+
* ```
|
|
215
|
+
*
|
|
216
|
+
* Everything it renders is a part you can render yourself instead - see `SearchPalette.Root`
|
|
217
|
+
* for the anatomy. This is the composition that covers the common case, not a different
|
|
218
|
+
* component: it is those parts, in the order they belong in.
|
|
219
|
+
*/
|
|
220
|
+
declare function SearchPalette<Item>({ placeholder, trigger, renderItem, empty, footer, children, ...root }: SearchPaletteProps<Item>): ReactNode;
|
|
221
|
+
declare namespace SearchPalette {
|
|
222
|
+
var Root: typeof PaletteRoot;
|
|
223
|
+
var Trigger: typeof PaletteTrigger;
|
|
224
|
+
var Content: typeof PaletteContent;
|
|
225
|
+
var Field: typeof PaletteField;
|
|
226
|
+
var List: typeof PaletteList;
|
|
227
|
+
var Item: typeof PaletteItem;
|
|
228
|
+
var Footer: typeof PaletteFooter;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export { PaletteContent, type PaletteContextValue, PaletteField, PaletteFooter, PaletteItem, PaletteList, type PaletteListProps, PaletteRoot, type PaletteRootProps, type PaletteRow, type PaletteSection, PaletteTrigger, SearchPalette, type SearchPaletteProps, type PaletteRow as SearchPaletteRow, usePaletteContext };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
export { PaletteContent, PaletteField, PaletteFooter, PaletteItem, PaletteList, PaletteRoot, PaletteTrigger, SearchPalette, usePaletteContext } from '../chunk-FWVWX67R.js';
|
|
3
|
+
import '../chunk-DTWZDONY.js';
|
|
4
|
+
import '../chunk-D5A2ZMAG.js';
|
|
5
|
+
import '../chunk-HS3X3XCW.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { a as RelativeTimeOptions } from '../relative-time-YpRTG7YH.js';
|
|
3
|
+
|
|
4
|
+
interface RelativeTimeProps extends RelativeTimeOptions, Omit<HTMLAttributes<HTMLElement>, "prefix" | "children"> {
|
|
5
|
+
/** ISO string, epoch milliseconds, or a Date. A string with no zone is read as UTC. */
|
|
6
|
+
date: string | number | Date | null | undefined;
|
|
7
|
+
/** Rendered when the date cannot be parsed. Nothing, by default. */
|
|
8
|
+
fallback?: ReactNode;
|
|
9
|
+
/** Title Case The Whole Phrase. Rarely what you want; `capitalizeFirst` usually is. */
|
|
10
|
+
capitalize?: boolean;
|
|
11
|
+
/** Uppercase the first letter, so a standalone "yesterday" reads as "Yesterday". */
|
|
12
|
+
capitalizeFirst?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Pin the instant the age is measured from. Pass the request's timestamp to make a
|
|
15
|
+
* server render and its hydration agree exactly.
|
|
16
|
+
*/
|
|
17
|
+
now?: Date;
|
|
18
|
+
}
|
|
19
|
+
declare function RelativeTime({ date, fallback, capitalize, capitalizeFirst, now, format, tense, precision, threshold, prefix, formatStyle, locale, timeZone, second, minute, hour, weekday, day, month, year, timeZoneName, noTitle, numericBeyondThreshold, ...rest }: RelativeTimeProps): ReactNode;
|
|
20
|
+
|
|
21
|
+
export { RelativeTime, type RelativeTimeProps };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
import { b as SearchMatch, c as SearchOptions } from '../search-DXxY8SEH.js';
|
|
3
|
+
|
|
4
|
+
interface UseSearchResult<T> {
|
|
5
|
+
/** Attach to the search field, or drive it yourself with `search`. */
|
|
6
|
+
inputRef: RefObject<HTMLInputElement | null>;
|
|
7
|
+
query: string;
|
|
8
|
+
results: SearchMatch<T>[];
|
|
9
|
+
/** Debounced. */
|
|
10
|
+
search: (query: string) => void;
|
|
11
|
+
/** Skips the debounce. */
|
|
12
|
+
searchNow: (query: string) => void;
|
|
13
|
+
clear: () => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Search-as-you-type over a list.
|
|
17
|
+
*
|
|
18
|
+
* Pass `fuse` (Fuse.js's constructor) for fuzzy matching, `matcher` to replace the
|
|
19
|
+
* engine, or neither for the built-in accent-insensitive substring search.
|
|
20
|
+
*
|
|
21
|
+
* ```tsx
|
|
22
|
+
* import Fuse from "fuse.js";
|
|
23
|
+
*
|
|
24
|
+
* const { inputRef, results } = useSearch({ items: docs, keys: ["title", "body"], fuse: Fuse });
|
|
25
|
+
* return <input ref={inputRef} type="search" placeholder="Search" />;
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
declare function useSearch<T>(options?: SearchOptions<T>): UseSearchResult<T>;
|
|
29
|
+
|
|
30
|
+
export { type UseSearchResult, useSearch };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* `asChild`: render the behaviour onto YOUR element instead of ours.
|
|
6
|
+
*
|
|
7
|
+
* This is the escape hatch that decides whether a headless package is usable at scale. A
|
|
8
|
+
* component that always renders its own `<button>` forces every consumer who needs a link,
|
|
9
|
+
* a `motion.button`, a router's `Link` or their own design-system button to reimplement the
|
|
10
|
+
* behaviour - and that is the moment a team stops using the package. With `asChild` the
|
|
11
|
+
* component contributes props, refs and handlers, and the consumer owns the element:
|
|
12
|
+
*
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <Button asChild shortcut="s">
|
|
15
|
+
* <motion.a href="/save" whileTap={{ scale: 0.98 }}>Save</motion.a>
|
|
16
|
+
* </Button>
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Radix's Slot, deliberately: the semantics are the ones a React developer already knows.
|
|
20
|
+
* Its rules, and why each is the way round it is:
|
|
21
|
+
*
|
|
22
|
+
* - The CHILD's props win, because the child is what the author wrote by hand at this call
|
|
23
|
+
* site, while ours are the defaults a component supplied.
|
|
24
|
+
* - EVENT HANDLERS are chained rather than replaced, ours first: dropping ours would take
|
|
25
|
+
* the behaviour with it silently, which is the failure `onClick` on the Button already
|
|
26
|
+
* cost once. The child's handler still runs even if ours called `preventDefault`, so a
|
|
27
|
+
* handler that wants to bail checks `event.defaultPrevented` itself.
|
|
28
|
+
* - `className` and `style` are MERGED, child last, because both are additive by nature and
|
|
29
|
+
* an overwritten className is the single most confusing thing a wrapper can do.
|
|
30
|
+
* - Refs are composed, so both sides keep the node.
|
|
31
|
+
*/
|
|
32
|
+
type Props = Record<string, unknown>;
|
|
33
|
+
/** Merge the slot's props into the child's, by the rules above. */
|
|
34
|
+
declare function mergeSlotProps(slotProps: Props, childProps: Props): Props;
|
|
35
|
+
interface SlotProps extends Props {
|
|
36
|
+
children?: ReactNode;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Clones its single child with the props it was given.
|
|
40
|
+
*
|
|
41
|
+
* A child that is not a single element is a mistake worth failing on rather than
|
|
42
|
+
* papering over: `asChild` with two children has no answer to "which one gets the
|
|
43
|
+
* behaviour", and rendering nothing would be a blank space nobody can debug.
|
|
44
|
+
*/
|
|
45
|
+
declare const Slot: react.ForwardRefExoticComponent<Omit<SlotProps, "ref"> & react.RefAttributes<HTMLElement>>;
|
|
46
|
+
|
|
47
|
+
export { Slot, type SlotProps, mergeSlotProps };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { d as Notifications, N as Notification } from '../notifications-BpVV6sel.js';
|
|
2
|
+
import { ReactNode, CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* `<Toaster />` - the stack, the movement and the gestures. No colours.
|
|
6
|
+
*
|
|
7
|
+
* The queue underneath already owns ordering, dedupe by key, sticky errors and timers that
|
|
8
|
+
* HOLD while the tab is hidden. What this adds is everything you cannot express in a queue:
|
|
9
|
+
* a toast that is on its way out is still on screen, a pointer resting on the stack must
|
|
10
|
+
* stop the clock, and a swipe has to follow the finger before it decides anything.
|
|
11
|
+
*
|
|
12
|
+
* Every part carries a data attribute, so the theme is a stylesheet you own. `enigma add
|
|
13
|
+
* toast --copy` writes one.
|
|
14
|
+
*/
|
|
15
|
+
type ToastPosition = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
|
|
16
|
+
interface ToasterProps {
|
|
17
|
+
/** Which queue to render. The shared one by default. */
|
|
18
|
+
queue?: Notifications;
|
|
19
|
+
position?: ToastPosition;
|
|
20
|
+
/**
|
|
21
|
+
* How long the exit animation lasts, in ms. The node stays mounted for exactly this
|
|
22
|
+
* long after it leaves the queue - a toast that vanishes the instant it is dismissed
|
|
23
|
+
* cannot animate out, and that is the only reason this component keeps its own list.
|
|
24
|
+
*/
|
|
25
|
+
exitDuration?: number;
|
|
26
|
+
/** Px a toast must travel before the release dismisses it. */
|
|
27
|
+
swipeThreshold?: number;
|
|
28
|
+
/** Render a toast yourself. The default renders title, body and the action. */
|
|
29
|
+
children?: (notification: Notification, controls: ToastControls) => ReactNode;
|
|
30
|
+
/** Accessible name for the region. */
|
|
31
|
+
label?: string;
|
|
32
|
+
className?: string;
|
|
33
|
+
style?: CSSProperties;
|
|
34
|
+
}
|
|
35
|
+
interface ToastControls {
|
|
36
|
+
dismiss: () => void;
|
|
37
|
+
}
|
|
38
|
+
declare function Toaster({ queue, position, exitDuration, swipeThreshold, children, label, className, style }: ToasterProps): ReactNode;
|
|
39
|
+
|
|
40
|
+
export { type ToastControls, type ToastPosition, Toaster, type ToasterProps };
|
|
@@ -1,8 +1,26 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ButtonProps } from '../react/
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
2
|
+
import { ButtonProps } from '../react/button.js';
|
|
3
|
+
export { UseMarqueeResult, useMarquee } from '../react/marquee.js';
|
|
4
|
+
export { M as MarqueeHover, a as MarqueeInstance, b as MarqueeOptions } from '../marquee-CJ3Uwy3E.js';
|
|
5
|
+
export { PasswordStrength, PasswordStrengthProps, UseButtonResult, UseInputResult, getLinkComponent, setLinkComponent, useButton, useInput } from '../react/index.js';
|
|
6
|
+
export { UseSearchResult, useSearch } from '../react/search.js';
|
|
7
|
+
export { I as InputAction, b as InputIcon, d as InputOptions } from '../input-BwXjFenq.js';
|
|
8
|
+
export { F as FuseConstructor, a as FuseLike, S as SearchInstance, b as SearchMatch, c as SearchOptions } from '../search-DXxY8SEH.js';
|
|
9
|
+
export { c as ButtonOptions, d as ButtonState } from '../button-CaXaqG_K.js';
|
|
10
|
+
export { B as BreachChecker, a as BreachState, b as BreachStatus, F as FieldAction, I as Input, c as InputBaseProps, d as InputProps, e as InputType, P as PasswordOnlyProps, g as PlainOnlyProps, S as SearchOnlyProps } from '../index-dTdAbOWl.js';
|
|
11
|
+
export { Slot, SlotProps, mergeSlotProps } from '../react/slot.js';
|
|
12
|
+
export { E as EstimateOptions, G as GeneratePasswordOptions, a as PasswordScore, b as PasswordStrengthReport, e as estimatePasswordStrength, g as generatePassword } from '../password-C8lG4Zm9.js';
|
|
13
|
+
export { UseNotificationsResult, createNotificationQueue, defaultQueue, useNotifications } from '../react/notifications.js';
|
|
14
|
+
export { ToastControls, ToastPosition, Toaster, ToasterProps } from '../react/toast.js';
|
|
15
|
+
export { useNetworkState } from '../react/network.js';
|
|
16
|
+
export { a as NetworkState } from '../network-D2LsBG_k.js';
|
|
17
|
+
export { RelativeTime, RelativeTimeProps } from '../react/relative-time.js';
|
|
18
|
+
export { R as RelativeTimeFormat, a as RelativeTimeOptions, b as RelativeTimePrecision, c as RelativeTimeStyle, d as RelativeTimeTense } from '../relative-time-YpRTG7YH.js';
|
|
19
|
+
export { N as Notification, a as NotificationAction, b as NotificationInput, c as NotificationTone, e as NotificationsOptions } from '../notifications-BpVV6sel.js';
|
|
20
|
+
export { Flag, FlagProps } from '../react/flag.js';
|
|
21
|
+
export { c as FlagFormat, d as FlagOptions, e as FlagShape, f as FlagSource, h as configureFlags, i as flagAttributes, k as flagName, l as flagSrc, m as flagView, n as normalizeFlagCode } from '../flags-BBJc9unY.js';
|
|
22
|
+
export { PaletteContent, PaletteContextValue, PaletteField, PaletteFooter, PaletteItem, PaletteList, PaletteListProps, PaletteRoot, PaletteRootProps, PaletteRow, PaletteSection, PaletteTrigger, SearchPalette, SearchPaletteProps, usePaletteContext } from '../react/palette.js';
|
|
23
|
+
export { R as RecentEntry, b as RecentStore, e as createRecentStore, g as groupRows, i as isPaletteShortcut, m as moveActive, r as recentKey, s as shortcutLabel } from '../palette-D7iuQh_T.js';
|
|
6
24
|
|
|
7
25
|
declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLElement>>;
|
|
8
26
|
|
|
@@ -1,8 +1,29 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
|
|
2
|
+
export { useInput } from '../chunk-U3V4EHOB.js';
|
|
3
|
+
export { PasswordStrength } from '../chunk-XQHCZAPJ.js';
|
|
4
|
+
export { Flag } from '../chunk-XNNQRA35.js';
|
|
5
|
+
export { Toaster } from '../chunk-ZCUFYBPB.js';
|
|
6
|
+
export { useMarquee } from '../chunk-ZWR2EXHQ.js';
|
|
7
|
+
export { useSearch } from '../chunk-QQFNAKMY.js';
|
|
8
|
+
export { useNetworkState } from '../chunk-S653GLSF.js';
|
|
9
|
+
export { createNotificationQueue, defaultQueue, useNotifications } from '../chunk-QYMUIW5I.js';
|
|
10
|
+
export { RelativeTime } from '../chunk-OCMI7R6H.js';
|
|
11
|
+
import '../chunk-KJINGUQN.js';
|
|
12
|
+
export { estimatePasswordStrength, generatePassword } from '../chunk-HC2ME5PU.js';
|
|
13
|
+
export { configureFlags, flagAttributes, flagName, flagSrc, flagView, normalizeFlagCode } from '../chunk-AU3H5WIY.js';
|
|
14
|
+
import '../chunk-UOSSNUSC.js';
|
|
15
|
+
import '../chunk-2QFTRNAZ.js';
|
|
16
|
+
import '../chunk-SNYUBXWQ.js';
|
|
17
|
+
import '../chunk-IXVMRVD4.js';
|
|
18
|
+
export { Input } from '../chunk-R4ZAEE7V.js';
|
|
19
|
+
import '../chunk-F25CGNQC.js';
|
|
20
|
+
export { PaletteContent, PaletteField, PaletteFooter, PaletteItem, PaletteList, PaletteRoot, PaletteTrigger, SearchPalette, usePaletteContext } from '../chunk-FWVWX67R.js';
|
|
21
|
+
export { createRecentStore, groupRows, isPaletteShortcut, moveActive, recentKey, shortcutLabel } from '../chunk-DTWZDONY.js';
|
|
22
|
+
import '../chunk-D5A2ZMAG.js';
|
|
23
|
+
import { Button } from '../chunk-6BGBYUSZ.js';
|
|
24
|
+
export { getLinkComponent, setLinkComponent, useButton } from '../chunk-6BGBYUSZ.js';
|
|
25
|
+
import '../chunk-MMQPZGSU.js';
|
|
26
|
+
export { Slot, mergeSlotProps } from '../chunk-HS3X3XCW.js';
|
|
6
27
|
import { Link } from 'react-router';
|
|
7
28
|
import { forwardRef, createElement } from 'react';
|
|
8
29
|
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Relative time: "3 hours ago", and everything that has to be right around it.
|
|
3
|
+
*
|
|
4
|
+
* The rendering itself is `<relative-time>` (@github/relative-time-element), which already
|
|
5
|
+
* owns the hard parts - Intl.RelativeTimeFormat per locale, and re-rendering on a schedule
|
|
6
|
+
* that gets slower as the date gets older. What is here is the part every wrapper
|
|
7
|
+
* re-implements and usually gets wrong: parsing a timestamp that does not declare its zone,
|
|
8
|
+
* knowing when the date has aged past the relative threshold, and producing an absolute
|
|
9
|
+
* label to show while the element is still loading, or forever if scripting is off.
|
|
10
|
+
*
|
|
11
|
+
* Nothing in this file touches the DOM, so it renders on a server.
|
|
12
|
+
*/
|
|
13
|
+
/** How the element should phrase it. `auto` is relative until the threshold, then a date. */
|
|
14
|
+
type RelativeTimeFormat = "auto" | "relative" | "duration" | "datetime" | "micro" | "elapsed";
|
|
15
|
+
type RelativeTimeTense = "auto" | "past" | "future";
|
|
16
|
+
type RelativeTimePrecision = "year" | "month" | "day" | "hour" | "minute" | "second";
|
|
17
|
+
type RelativeTimeStyle = "long" | "short" | "narrow";
|
|
18
|
+
type NumericStyle = "numeric" | "2-digit";
|
|
19
|
+
interface RelativeTimeOptions {
|
|
20
|
+
format?: RelativeTimeFormat;
|
|
21
|
+
tense?: RelativeTimeTense;
|
|
22
|
+
precision?: RelativeTimePrecision;
|
|
23
|
+
/** ISO 8601 duration. Past this age `auto` stops being relative. Default `P30D`. */
|
|
24
|
+
threshold?: string;
|
|
25
|
+
/** Word before an absolute date, e.g. "on 5 May". Empty string removes it. */
|
|
26
|
+
prefix?: string;
|
|
27
|
+
formatStyle?: RelativeTimeStyle;
|
|
28
|
+
/**
|
|
29
|
+
* BCP 47 tag. Left undefined the element reads the closest `lang` in the document,
|
|
30
|
+
* which is what a translated page wants - hardcoding one is how a Spanish page ends
|
|
31
|
+
* up saying "3 hours ago".
|
|
32
|
+
*/
|
|
33
|
+
locale?: string;
|
|
34
|
+
/** IANA zone for the absolute rendering. Undefined means the reader's own. */
|
|
35
|
+
timeZone?: string;
|
|
36
|
+
second?: NumericStyle;
|
|
37
|
+
minute?: NumericStyle;
|
|
38
|
+
hour?: NumericStyle;
|
|
39
|
+
weekday?: RelativeTimeStyle;
|
|
40
|
+
day?: NumericStyle;
|
|
41
|
+
month?: NumericStyle | "short" | "long" | "narrow";
|
|
42
|
+
year?: NumericStyle;
|
|
43
|
+
timeZoneName?: "long" | "short" | "shortOffset" | "longOffset" | "shortGeneric" | "longGeneric";
|
|
44
|
+
/** Drop the exact timestamp the element otherwise puts in `title`. */
|
|
45
|
+
noTitle?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Once the date is older than `threshold`, render it as digits (05/05/2026) instead of
|
|
48
|
+
* a prefixed month name. The cutoff is the threshold itself, not a guess at it.
|
|
49
|
+
*/
|
|
50
|
+
numericBeyondThreshold?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/** Everything derived from a date, in one pass, for whichever adapter is rendering it. */
|
|
53
|
+
interface RelativeTimeView {
|
|
54
|
+
/** Null when the input could not be parsed - nothing else here is meaningful then. */
|
|
55
|
+
date: Date | null;
|
|
56
|
+
/** `datetime` attribute value: always UTC, always ISO. */
|
|
57
|
+
iso: string;
|
|
58
|
+
/** Absolute text. Shown until the element upgrades, and forever without scripting. */
|
|
59
|
+
label: string;
|
|
60
|
+
/** Full timestamp for `title` / `aria-label`. */
|
|
61
|
+
exact: string;
|
|
62
|
+
/** The date is older (or further ahead) than `threshold`. */
|
|
63
|
+
beyondThreshold: boolean;
|
|
64
|
+
/** Render `label` in a plain `<time>` and skip the element entirely. */
|
|
65
|
+
absoluteOnly: boolean;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* A timestamp with no zone is UTC.
|
|
69
|
+
*
|
|
70
|
+
* This is the single most common defect in a date column: `2026-08-13 22:41:00` comes back
|
|
71
|
+
* from the database with no offset, `new Date()` reads it as LOCAL time, and every reader
|
|
72
|
+
* east or west of the server sees a time that is hours out - silently, because the wrong
|
|
73
|
+
* time is still a valid one.
|
|
74
|
+
*
|
|
75
|
+
* A date with no clock is left exactly as it is. The spec already reads a bare `YYYY-MM-DD`
|
|
76
|
+
* as UTC, so there is nothing to add - and `YYYY-MM-DDZ` is not in the spec's grammar at
|
|
77
|
+
* all, which drops it into each engine's own legacy parser. That is a portability coin
|
|
78
|
+
* flip on a value that was already correct.
|
|
79
|
+
*/
|
|
80
|
+
declare function ensureZone(text: string): string;
|
|
81
|
+
/** Parse anything a date column or an API hands over. Null rather than an Invalid Date. */
|
|
82
|
+
declare function normalizeDate(value: string | number | Date | null | undefined): Date | null;
|
|
83
|
+
/**
|
|
84
|
+
* ISO 8601 duration to milliseconds, for comparing an age against `threshold`.
|
|
85
|
+
*
|
|
86
|
+
* Years and months are approximated the way the element approximates them, because the
|
|
87
|
+
* threshold is a rough "old enough to stop counting", not an anniversary.
|
|
88
|
+
*/
|
|
89
|
+
declare function parseDuration(value: string): number;
|
|
90
|
+
/**
|
|
91
|
+
* Everything an adapter needs to render one date.
|
|
92
|
+
*
|
|
93
|
+
* `now` is a parameter so a test can pin it, and so a server render can pass the same
|
|
94
|
+
* instant it used elsewhere on the page.
|
|
95
|
+
*/
|
|
96
|
+
declare function relativeTimeView(value: string | number | Date | null | undefined, options?: RelativeTimeOptions, now?: Date): RelativeTimeView;
|
|
97
|
+
/**
|
|
98
|
+
* The element's attributes, kebab-cased, with anything undefined left out.
|
|
99
|
+
*
|
|
100
|
+
* Written as attributes rather than properties because that is the half of a custom
|
|
101
|
+
* element's API that works before it is defined - the markup is already correct when the
|
|
102
|
+
* definition arrives late, or never.
|
|
103
|
+
*/
|
|
104
|
+
declare function relativeTimeAttributes(view: RelativeTimeView, options?: RelativeTimeOptions): Record<string, string>;
|
|
105
|
+
|
|
106
|
+
export { type RelativeTimeFormat as R, type RelativeTimeOptions as a, type RelativeTimePrecision as b, type RelativeTimeStyle as c, type RelativeTimeTense as d, type RelativeTimeView as e, ensureZone as f, relativeTimeView as g, normalizeDate as n, parseDuration as p, relativeTimeAttributes as r };
|
package/dist/search/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as SearchOptions, S as SearchInstance } from '../search-
|
|
2
|
-
export { b as SearchMatch } from '../search-
|
|
1
|
+
import { c as SearchOptions, S as SearchInstance } from '../search-DXxY8SEH.js';
|
|
2
|
+
export { b as SearchMatch } from '../search-DXxY8SEH.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Search with Fuse.js already wired: the batteries-included entry point.
|
package/dist/search/index.js
CHANGED
|
@@ -63,6 +63,20 @@ interface SearchInstance<T> {
|
|
|
63
63
|
subscribe(listener: (results: SearchMatch<T>[], query: string) => void): () => void;
|
|
64
64
|
destroy(): void;
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Subsequence ranking: every letter of the query, in order, anywhere in the text.
|
|
68
|
+
*
|
|
69
|
+
* This is what a COMMAND palette wants and a substring filter cannot do: "qgate" finds
|
|
70
|
+
* "Quality gate" and "plyg" finds "Playground", because the letters only have to appear in
|
|
71
|
+
* order. The score rewards consecutive runs and word starts and penalises gaps, so the
|
|
72
|
+
* closest thing to what was typed comes first rather than the first thing that happened to
|
|
73
|
+
* contain the letters.
|
|
74
|
+
*
|
|
75
|
+
* Pass it as `matcher`, or take it as the default from the palette. The substring matcher
|
|
76
|
+
* stays the default for a plain search FIELD, where a typo should fail rather than quietly
|
|
77
|
+
* match something four words away.
|
|
78
|
+
*/
|
|
79
|
+
declare function subsequenceMatcher<T>(keys?: string[]): NonNullable<SearchOptions<T>["matcher"]>;
|
|
66
80
|
declare function createSearch<T>(options?: SearchOptions<T>): SearchInstance<T>;
|
|
67
81
|
|
|
68
|
-
export { type FuseConstructor as F, type SearchInstance as S, type FuseLike as a, type SearchMatch as b, type SearchOptions as c, createSearch as d };
|
|
82
|
+
export { type FuseConstructor as F, type SearchInstance as S, type FuseLike as a, type SearchMatch as b, type SearchOptions as c, createSearch as d, subsequenceMatcher as s };
|