@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,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Country flags as ASSETS, which is the only form of them that renders everywhere.
|
|
3
|
+
*
|
|
4
|
+
* The emoji flag is the thing this replaces. It is a pair of regional-indicator code
|
|
5
|
+
* points, and the glyph for that pair exists only where the platform ships one: Windows
|
|
6
|
+
* has never shipped country flags in Segoe UI Emoji, so `\u{1F1EA}\u{1F1F8}` renders as
|
|
7
|
+
* the letters "ES" for the largest desktop platform there is - and a language picker built
|
|
8
|
+
* out of them looks broken to those readers, with nothing in the code to explain why.
|
|
9
|
+
* There is no font stack that fixes it, so the fix is not a font: it is an image.
|
|
10
|
+
*
|
|
11
|
+
* Three sets, all SVG, all served by enigma itself:
|
|
12
|
+
*
|
|
13
|
+
* - `rect` (4:3) and `square` (1:1) - the classic rectangular artwork.
|
|
14
|
+
* - `circle` - round, which is what a flag next to an avatar or inside a chip wants.
|
|
15
|
+
*
|
|
16
|
+
* They are served from enigma's own tree rather than from anyone else's, because a
|
|
17
|
+
* component whose default source is a third party is a component that breaks when that
|
|
18
|
+
* third party moves, renames a branch, or goes away.
|
|
19
|
+
*
|
|
20
|
+
* Nothing here touches the DOM, so it renders on a server.
|
|
21
|
+
*/
|
|
22
|
+
type FlagShape = "rect" | "square" | "circle";
|
|
23
|
+
/**
|
|
24
|
+
* `svg` is what the sets are stored as, so it is what a remote source can serve. `png` and
|
|
25
|
+
* `webp` exist for a LOCAL set (`enigma add flags --flags local --flag-formats webp`), which
|
|
26
|
+
* rasterises what it downloads, and for a mirror of your own.
|
|
27
|
+
*/
|
|
28
|
+
type FlagFormat = "svg" | "png" | "webp";
|
|
29
|
+
/**
|
|
30
|
+
* Where the files come from.
|
|
31
|
+
*
|
|
32
|
+
* - `"cdn"` - enigma's own artwork, over a CDN. Nothing to install.
|
|
33
|
+
* - `"local"` - files under `basePath` in your own public directory.
|
|
34
|
+
* - any URL - a mirror of your own with the same layout
|
|
35
|
+
* (`<base>/<shape>/<code>.<format>`), which is exactly the tree the downloader writes.
|
|
36
|
+
*/
|
|
37
|
+
type FlagSource = "cdn" | "local" | (string & {});
|
|
38
|
+
/** enigma's own artwork, over a CDN. Every source shares this layout. */
|
|
39
|
+
declare const FLAG_CDN = "https://cdn.jsdelivr.net/gh/FJRG2007/enigma@main/assets/flags";
|
|
40
|
+
interface FlagOptions {
|
|
41
|
+
shape?: FlagShape;
|
|
42
|
+
format?: FlagFormat;
|
|
43
|
+
source?: FlagSource;
|
|
44
|
+
/** Where a local set is served from. Default `/flags`. */
|
|
45
|
+
basePath?: string;
|
|
46
|
+
/** Rendered HEIGHT in px. The width follows the shape's ratio. Default 16. */
|
|
47
|
+
size?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Language the automatic name is written in. Left out, it follows the document's own
|
|
50
|
+
* `lang`, which is what a translated page wants.
|
|
51
|
+
*/
|
|
52
|
+
locale?: string;
|
|
53
|
+
}
|
|
54
|
+
interface FlagConfig extends Required<Omit<FlagOptions, "size" | "locale">> {
|
|
55
|
+
size: number;
|
|
56
|
+
locale?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Set the defaults for every flag on the page, once, at startup.
|
|
60
|
+
*
|
|
61
|
+
* This is what makes the CDN/local decision a one-line change rather than a prop on every
|
|
62
|
+
* call site: `configureFlags({ source: "local" })` moves the whole app onto the files the
|
|
63
|
+
* downloader wrote, and nothing else in the codebase mentions where a flag comes from.
|
|
64
|
+
*/
|
|
65
|
+
declare function configureFlags(patch: Partial<FlagConfig>): FlagConfig;
|
|
66
|
+
declare function flagConfig(): FlagConfig;
|
|
67
|
+
/** Test seam and a way back to the shipped defaults. */
|
|
68
|
+
declare function resetFlagConfig(): FlagConfig;
|
|
69
|
+
/** Width / height of each shape. The circle set is square; only `rect` is 4:3. */
|
|
70
|
+
declare const FLAG_RATIO: Record<FlagShape, number>;
|
|
71
|
+
/**
|
|
72
|
+
* Anything a codebase calls a country into the file name the sets use, or null.
|
|
73
|
+
*
|
|
74
|
+
* Null rather than a guess: a code this cannot resolve would otherwise become a 404 image
|
|
75
|
+
* with no alt text, and a broken flag beside a country name is worse than no flag at all.
|
|
76
|
+
* An emoji flag is accepted and converted, so migrating an existing picker is a rename of
|
|
77
|
+
* the component and nothing else.
|
|
78
|
+
*/
|
|
79
|
+
declare function normalizeFlagCode(value: string | null | undefined): string | null;
|
|
80
|
+
/**
|
|
81
|
+
* The country's name, in the reader's language, or null.
|
|
82
|
+
*
|
|
83
|
+
* `Intl.DisplayNames` is the whole implementation: the names are in the runtime already,
|
|
84
|
+
* translated, and maintained by whoever maintains the platform - so this ships no table of
|
|
85
|
+
* 250 country names to go stale, and a Spanish page says "España" without being told.
|
|
86
|
+
*
|
|
87
|
+
* Null for anything it cannot name, and that is deliberate for SUBDIVISIONS: `gb-eng` is
|
|
88
|
+
* England, and falling back to the region (`gb`, "United Kingdom") would put a confidently
|
|
89
|
+
* wrong name on the flag. A name nobody can source is worse than no name.
|
|
90
|
+
*/
|
|
91
|
+
declare function flagName(code: string | null | undefined, locale?: string): string | null;
|
|
92
|
+
/** Everything a renderer needs, computed in one pass. Null when the code is unusable. */
|
|
93
|
+
interface FlagView {
|
|
94
|
+
/** The file name, e.g. `es`, `gb-eng`. */
|
|
95
|
+
code: string;
|
|
96
|
+
src: string;
|
|
97
|
+
shape: FlagShape;
|
|
98
|
+
format: FlagFormat;
|
|
99
|
+
width: number;
|
|
100
|
+
height: number;
|
|
101
|
+
/** The automatic name, when there is one. */
|
|
102
|
+
name: string | null;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The URL for one flag. Null when the code cannot be resolved.
|
|
106
|
+
*
|
|
107
|
+
* A raster format asked of the CDN falls back to SVG rather than producing a 404: the sets
|
|
108
|
+
* are stored as SVG, so `format: "webp"` is only meaningful against a local set or a mirror.
|
|
109
|
+
* It says so once, in development, instead of silently disagreeing with the call site.
|
|
110
|
+
*/
|
|
111
|
+
declare function flagSrc(code: string | null | undefined, options?: FlagOptions): string | null;
|
|
112
|
+
/** `flagSrc` plus the resolved geometry and name, for a renderer that has to size the box. */
|
|
113
|
+
declare function flagView(code: string | null | undefined, options?: FlagOptions): FlagView | null;
|
|
114
|
+
interface FlagAttributeOptions extends FlagOptions {
|
|
115
|
+
/** Your own accessible name, which wins over the automatic one. */
|
|
116
|
+
label?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Beside a country name that is already on screen, the flag is decoration and repeating
|
|
119
|
+
* the name only makes a screen reader say it twice.
|
|
120
|
+
*/
|
|
121
|
+
decorative?: boolean;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Attributes for a plain `<img>`, for vanilla, Astro and any template language.
|
|
125
|
+
*
|
|
126
|
+
* The accessible name is AUTOMATIC: the country's own name, in the reader's language, from
|
|
127
|
+
* `Intl.DisplayNames`. `label` replaces it and `decorative` drops it. Nothing is ever
|
|
128
|
+
* invented - a subdivision the platform cannot name, or a runtime without `Intl`, renders
|
|
129
|
+
* as decoration rather than putting a bare "ES" into a screen reader.
|
|
130
|
+
*/
|
|
131
|
+
declare function flagAttributes(code: string | null | undefined, options?: FlagAttributeOptions): Record<string, string | number> | null;
|
|
132
|
+
|
|
133
|
+
export { FLAG_CDN as F, FLAG_RATIO as a, type FlagConfig as b, type FlagFormat as c, type FlagOptions as d, type FlagShape as e, type FlagSource as f, type FlagView as g, configureFlags as h, flagAttributes as i, flagConfig as j, flagName as k, flagSrc as l, flagView as m, normalizeFlagCode as n, resetFlagConfig as r };
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { ReactNode, ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
import { c as SearchOptions, F as FuseConstructor, b as SearchMatch } from './search-DXxY8SEH.js';
|
|
3
|
+
import { G as GeneratePasswordOptions, E as EstimateOptions, b as PasswordStrengthReport } from './password-C8lG4Zm9.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The prop shapes for `<Input>`, split from the component so the per-type chunks can import
|
|
7
|
+
* them without importing the component - and so every type in here is erased at build,
|
|
8
|
+
* which is what keeps a `type="text"` field from pulling the password estimator or a search
|
|
9
|
+
* engine into the bundle.
|
|
10
|
+
*
|
|
11
|
+
* The API is ONE component keyed on `type`, the way HTML itself is: `type` is an attribute
|
|
12
|
+
* of one element, not a different element. Radix splits Select, Checkbox and Slider into
|
|
13
|
+
* their own primitives because those are composed widgets rather than an `<input>` - that
|
|
14
|
+
* split is about the DOM, not about the props. What varies here is which props EXIST, and
|
|
15
|
+
* that is a discriminated union: `strength` on a text field and `items` on a password field
|
|
16
|
+
* are compile errors rather than props that quietly do nothing.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** An extra button inside the field. The built-ins are the same shape. */
|
|
20
|
+
interface FieldAction {
|
|
21
|
+
/** Stable id. Lands on `data-enigma-input-action`, and replaces a built-in of the same name. */
|
|
22
|
+
name: string;
|
|
23
|
+
/** Accessible name. Becomes `aria-label` and `title`. */
|
|
24
|
+
label: string;
|
|
25
|
+
icon: ReactNode;
|
|
26
|
+
onSelect: () => void;
|
|
27
|
+
/** Renders `aria-pressed`. Omit for actions that are not toggles. */
|
|
28
|
+
pressed?: boolean;
|
|
29
|
+
/** Default true. A false action is not rendered at all. */
|
|
30
|
+
visible?: boolean;
|
|
31
|
+
}
|
|
32
|
+
type BreachStatus = "idle" | "checking" | "safe" | "breached" | "error";
|
|
33
|
+
interface BreachState {
|
|
34
|
+
status: BreachStatus;
|
|
35
|
+
/** How many breaches the password appears in. 0 unless `status` is "breached". */
|
|
36
|
+
count: number;
|
|
37
|
+
/** Whatever the checker threw. The form decides whether that is worth showing. */
|
|
38
|
+
error: unknown;
|
|
39
|
+
}
|
|
40
|
+
type BreachChecker = (password: string, options: {
|
|
41
|
+
signal: AbortSignal;
|
|
42
|
+
}) => Promise<{
|
|
43
|
+
breached: boolean;
|
|
44
|
+
count: number;
|
|
45
|
+
}>;
|
|
46
|
+
/** Every `type` a single `<input>` element takes, plus the two this component teaches. */
|
|
47
|
+
type InputType = "text" | "email" | "password" | "search" | "tel" | "url" | "number" | "date" | "datetime-local" | "month" | "week" | "time" | "color" | "file" | "range" | "hidden" | "checkbox" | "radio";
|
|
48
|
+
interface PasswordStrengthClassNames {
|
|
49
|
+
track?: string;
|
|
50
|
+
segment?: string;
|
|
51
|
+
label?: string;
|
|
52
|
+
warning?: string;
|
|
53
|
+
}
|
|
54
|
+
/** What every type has, whatever it is. */
|
|
55
|
+
interface InputBaseProps extends Omit<ComponentPropsWithoutRef<"input">, "children" | "type"> {
|
|
56
|
+
/** The reveal toggle. Defaults to on for `type="password"` and off for everything else. */
|
|
57
|
+
reveal?: boolean;
|
|
58
|
+
revealLabels?: {
|
|
59
|
+
show?: string;
|
|
60
|
+
hide?: string;
|
|
61
|
+
};
|
|
62
|
+
/** Extra buttons, or a replacement for a built-in by name. */
|
|
63
|
+
actions?: FieldAction[];
|
|
64
|
+
/** Which end the buttons sit at. Position them yourself; this only orders the markup. */
|
|
65
|
+
position?: "start" | "end";
|
|
66
|
+
/** Props for the element wrapping the field, its buttons and anything under them. */
|
|
67
|
+
wrapperProps?: ComponentPropsWithoutRef<"div">;
|
|
68
|
+
/** Props for the row holding the field and its buttons - this is what you position. */
|
|
69
|
+
fieldProps?: ComponentPropsWithoutRef<"div">;
|
|
70
|
+
/**
|
|
71
|
+
* Classes for the parts you cannot reach with a ref, which is what Tailwind needs.
|
|
72
|
+
* `className` still goes to the `<input>` itself, where you would expect it.
|
|
73
|
+
*/
|
|
74
|
+
classNames?: {
|
|
75
|
+
actions?: string;
|
|
76
|
+
action?: string;
|
|
77
|
+
strength?: PasswordStrengthClassNames;
|
|
78
|
+
results?: string;
|
|
79
|
+
result?: string;
|
|
80
|
+
};
|
|
81
|
+
/** Rendered inside the wrapper, after everything the type adds. Your error goes here. */
|
|
82
|
+
children?: ReactNode;
|
|
83
|
+
}
|
|
84
|
+
/** The half only a password field has. */
|
|
85
|
+
interface PasswordOnlyProps {
|
|
86
|
+
type: "password";
|
|
87
|
+
/** Offer to generate a password. `true` for the defaults, or the generator's options. */
|
|
88
|
+
generate?: boolean | GeneratePasswordOptions;
|
|
89
|
+
generateLabel?: string;
|
|
90
|
+
/** Show what was generated. On by default - a password nobody can read is not usable. */
|
|
91
|
+
revealOnGenerate?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Also copy it to the clipboard. OFF by default and worth leaving off: the clipboard is
|
|
94
|
+
* shared with every other app on the machine and is not cleared.
|
|
95
|
+
*/
|
|
96
|
+
copyOnGenerate?: boolean;
|
|
97
|
+
onGenerate?: (password: string) => void;
|
|
98
|
+
/** Score the password as it is typed, and render the meter under the field. */
|
|
99
|
+
strength?: boolean | EstimateOptions;
|
|
100
|
+
onStrengthChange?: (report: PasswordStrengthReport) => void;
|
|
101
|
+
/**
|
|
102
|
+
* Check the password against a breach corpus - pass `checkPasswordBreach` from
|
|
103
|
+
* @enigmax/utils, or your own. It is a prop rather than a built-in because it makes a
|
|
104
|
+
* network request, and that is not a decision a field should take on its own.
|
|
105
|
+
*/
|
|
106
|
+
breach?: BreachChecker;
|
|
107
|
+
/** Quiet time before a check fires, in ms. Default 500. */
|
|
108
|
+
breachDelay?: number;
|
|
109
|
+
onBreachChange?: (state: BreachState) => void;
|
|
110
|
+
}
|
|
111
|
+
/** The half only a search field has. The palette is its own component, not a prop. */
|
|
112
|
+
interface SearchOnlyProps<Item = unknown> {
|
|
113
|
+
type: "search";
|
|
114
|
+
/** What to search. Leave it out for a field that only reports the query. */
|
|
115
|
+
items?: Item[];
|
|
116
|
+
/** Which fields to read. `["title", "body"]`, or leave it out for every string field. */
|
|
117
|
+
keys?: SearchOptions<Item>["keys"];
|
|
118
|
+
/** Quiet time before a search runs, in ms. Default 150. */
|
|
119
|
+
delay?: number;
|
|
120
|
+
/** Cap the result list. Applies to the empty query too. */
|
|
121
|
+
limit?: number;
|
|
122
|
+
/** Fuse.js's constructor, for fuzzy matching. Without it, a substring matcher is used. */
|
|
123
|
+
fuse?: FuseConstructor;
|
|
124
|
+
fuseOptions?: SearchOptions<Item>["fuseOptions"];
|
|
125
|
+
/** Replaces the engine outright, and wins over `fuse`. */
|
|
126
|
+
matcher?: SearchOptions<Item>["matcher"];
|
|
127
|
+
onResults?: (matches: SearchMatch<Item>[], query: string) => void;
|
|
128
|
+
/** Render the results under the field. Without it, the field only reports them. */
|
|
129
|
+
renderResults?: (matches: SearchMatch<Item>[], query: string) => ReactNode;
|
|
130
|
+
/** Clear button. On by default for a search field, because the platform's own is not. */
|
|
131
|
+
clearable?: boolean;
|
|
132
|
+
clearLabel?: string;
|
|
133
|
+
}
|
|
134
|
+
/** Everything else: one `<input>`, its native props, and no extras to bundle. */
|
|
135
|
+
interface PlainOnlyProps {
|
|
136
|
+
type?: Exclude<InputType, "password" | "search">;
|
|
137
|
+
}
|
|
138
|
+
type InputProps<Item = unknown> = InputBaseProps & (PasswordOnlyProps | SearchOnlyProps<Item> | PlainOnlyProps);
|
|
139
|
+
|
|
140
|
+
declare const Input: <Item = unknown>(props: InputProps<Item> & {
|
|
141
|
+
ref?: React.Ref<HTMLInputElement>;
|
|
142
|
+
}) => ReactNode;
|
|
143
|
+
|
|
144
|
+
export { type BreachChecker as B, type FieldAction as F, Input as I, type PasswordOnlyProps as P, type SearchOnlyProps as S, type BreachState as a, type BreachStatus as b, type InputBaseProps as c, type InputProps as d, type InputType as e, type PasswordStrengthClassNames as f, type PlainOnlyProps as g };
|