@gusnips/react 0.9.11 → 0.9.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/dist/copy.d.ts +23 -0
- package/dist/copy.d.ts.map +1 -0
- package/dist/copy.js +46 -0
- package/dist/copy.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/ui/combobox.d.ts.map +1 -1
- package/dist/ui/combobox.js +1 -1
- package/dist/ui/combobox.js.map +1 -1
- package/dist/ui/select.d.ts.map +1 -1
- package/dist/ui/select.js +1 -1
- package/dist/ui/select.js.map +1 -1
- package/package.json +2 -2
- package/src/copy.test.ts +29 -0
- package/src/copy.ts +62 -0
- package/src/index.ts +1 -0
- package/src/ui/combobox.tsx +6 -2
- package/src/ui/focus.test.ts +21 -18
- package/src/ui/select.tsx +7 -2
package/README.md
CHANGED
|
@@ -417,6 +417,27 @@ In jsdom tests, mock `window.matchMedia`, which jsdom does not have, and run
|
|
|
417
417
|
`delete window.__frontkitTheme` between tests. There is one controller per page, and a jsdom
|
|
418
418
|
window lasts the whole file.
|
|
419
419
|
|
|
420
|
+
## A copy button that says when it failed
|
|
421
|
+
|
|
422
|
+
```tsx
|
|
423
|
+
import { useCopy } from "@gusnips/react";
|
|
424
|
+
|
|
425
|
+
const { state, copy } = useCopy();
|
|
426
|
+
|
|
427
|
+
<button onClick={() => void copy(apiKey)} aria-live="polite">
|
|
428
|
+
{state === "copied" ? "Copied" : state === "failed" ? "Select it and copy it yourself" : "Copy"}
|
|
429
|
+
</button>;
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
Of eight copy buttons we read, five failed without a word, so the reader pasted whatever was
|
|
433
|
+
already on the clipboard. Two more threw on a page served without https, where there is no
|
|
434
|
+
clipboard API. `useCopy` shows `"copied"` for 2 seconds or `"failed"` for 6, then goes back to
|
|
435
|
+
`"idle"`, and a second copy restarts the clock. `copy` resolves `false` instead of throwing, so a
|
|
436
|
+
toast needs no `catch`. Outside a component, `copyText(text)` does the write on its own.
|
|
437
|
+
|
|
438
|
+
The words are yours, and so is the live region: a label that changes needs `aria-live` to be
|
|
439
|
+
heard.
|
|
440
|
+
|
|
420
441
|
## Also here
|
|
421
442
|
|
|
422
443
|
`ErrorBoundary`, an SSE reader split into a platform-free parser and a stream wrapper,
|
|
@@ -459,6 +480,8 @@ writes you no longer own.
|
|
|
459
480
|
The main entry works in React Native. It imports `react` and nothing else you would have to go
|
|
460
481
|
find — no `react-dom`, no router, no store — so the fetch client, the retry rule and the SSE
|
|
461
482
|
parser all come along, and the four things that need a browser stay behind the subpaths above.
|
|
483
|
+
`useCopy` imports fine there but has no `navigator.clipboard` to write to, so every copy answers
|
|
484
|
+
`"failed"`: use the platform's clipboard on a phone.
|
|
462
485
|
|
|
463
486
|
## The Base UI wrappers
|
|
464
487
|
|
package/dist/copy.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Write `text` to the clipboard. `false` when the browser refused or has no clipboard API. */
|
|
2
|
+
export declare function copyText(text: string): Promise<boolean>;
|
|
3
|
+
export type CopyState = "idle" | "copied" | "failed";
|
|
4
|
+
export interface CopyOptions {
|
|
5
|
+
/** How long `"copied"` shows. Default 2000 ms. */
|
|
6
|
+
copiedMs?: number;
|
|
7
|
+
/** How long `"failed"` shows. Default 6000 ms: a failure is a sentence the reader has to act on. */
|
|
8
|
+
failedMs?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A copy with an outcome the reader can see. What it says stays yours — "Copied", or "Select it
|
|
12
|
+
* and copy it yourself", in a label or a toast — and so does announcing it: a label that changes
|
|
13
|
+
* needs `aria-live="polite"` to be heard.
|
|
14
|
+
*
|
|
15
|
+
* The outcome goes back to `"idle"` on its own. A "Copied" that never clears makes the second copy
|
|
16
|
+
* look like it did not take.
|
|
17
|
+
*/
|
|
18
|
+
export declare function useCopy({ copiedMs, failedMs }?: CopyOptions): {
|
|
19
|
+
state: CopyState;
|
|
20
|
+
/** Resolves `false` instead of throwing, so a caller can toast without a `catch`. */
|
|
21
|
+
copy: (text: string) => Promise<boolean>;
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=copy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copy.d.ts","sourceRoot":"","sources":["../src/copy.ts"],"names":[],"mappings":"AAWA,+FAA+F;AAC/F,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO7D;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oGAAoG;IACpG,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,EAAE,QAAe,EAAE,QAAe,EAAE,GAAE,WAAgB,GAAG;IAC/E,KAAK,EAAE,SAAS,CAAC;IACjB,qFAAqF;IACrF,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1C,CAmBA"}
|
package/dist/copy.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
// Eight products wrote a copy button, and five of them failed silently, one under a comment
|
|
3
|
+
// saying it must not. Silent is worse than it looks: the reader pastes whatever was already on
|
|
4
|
+
// the clipboard, and for a key shown once that is pasting something else over the only copy.
|
|
5
|
+
// Two more called `writeText` outside a `try`, and on a page not served over https there is no
|
|
6
|
+
// `navigator.clipboard` at all, so the click threw a TypeError instead of rejecting.
|
|
7
|
+
//
|
|
8
|
+
// No `execCommand` fallback, and none of the eight had one: it is deprecated, the async API is
|
|
9
|
+
// there in every browser over https, and a copy that says it failed beats a shim that pretends.
|
|
10
|
+
/** Write `text` to the clipboard. `false` when the browser refused or has no clipboard API. */
|
|
11
|
+
export async function copyText(text) {
|
|
12
|
+
try {
|
|
13
|
+
await navigator.clipboard.writeText(text);
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A copy with an outcome the reader can see. What it says stays yours — "Copied", or "Select it
|
|
22
|
+
* and copy it yourself", in a label or a toast — and so does announcing it: a label that changes
|
|
23
|
+
* needs `aria-live="polite"` to be heard.
|
|
24
|
+
*
|
|
25
|
+
* The outcome goes back to `"idle"` on its own. A "Copied" that never clears makes the second copy
|
|
26
|
+
* look like it did not take.
|
|
27
|
+
*/
|
|
28
|
+
export function useCopy({ copiedMs = 2000, failedMs = 6000 } = {}) {
|
|
29
|
+
// A new object on every copy, so copying again restarts the clock even when the state is the
|
|
30
|
+
// same: two copies a second apart read "Copied" for two seconds after the second one.
|
|
31
|
+
const [outcome, setOutcome] = useState({ state: "idle" });
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (outcome.state === "idle")
|
|
34
|
+
return;
|
|
35
|
+
const ms = outcome.state === "copied" ? copiedMs : failedMs;
|
|
36
|
+
const timer = setTimeout(() => setOutcome({ state: "idle" }), ms);
|
|
37
|
+
return () => clearTimeout(timer);
|
|
38
|
+
}, [outcome, copiedMs, failedMs]);
|
|
39
|
+
const copy = useCallback(async (text) => {
|
|
40
|
+
const copied = await copyText(text);
|
|
41
|
+
setOutcome({ state: copied ? "copied" : "failed" });
|
|
42
|
+
return copied;
|
|
43
|
+
}, []);
|
|
44
|
+
return { state: outcome.state, copy };
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=copy.js.map
|
package/dist/copy.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copy.js","sourceRoot":"","sources":["../src/copy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEzD,4FAA4F;AAC5F,+FAA+F;AAC/F,6FAA6F;AAC7F,+FAA+F;AAC/F,qFAAqF;AACrF,EAAE;AACF,+FAA+F;AAC/F,gGAAgG;AAEhG,+FAA+F;AAC/F,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY;IACzC,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAWD;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,EAAE,QAAQ,GAAG,IAAI,EAAE,QAAQ,GAAG,IAAI,KAAkB,EAAE;IAK5E,6FAA6F;IAC7F,sFAAsF;IACtF,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAuB,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAEhF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO;QACrC,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC5D,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAClE,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAElC,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;QAC9C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpC,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpD,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;AACxC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { cn } from "./cn.ts";
|
|
2
|
+
export { copyText, useCopy, type CopyOptions, type CopyState } from "./copy.ts";
|
|
2
3
|
export { returnPathFromLocation, safeInternalPath, type PathParts } from "./internal-path.ts";
|
|
3
4
|
export { ApiError, isAbortError, retryAfterSecs } from "./api-error.ts";
|
|
4
5
|
export { createApiClient, type ApiClient, type ApiClientOptions, type RefreshResult, type RequestOptions, type SessionAdapter, } from "./api-client.ts";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE9F,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EACL,eAAe,EACf,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,EACL,aAAa,EACb,SAAS,EACT,YAAY,EACZ,WAAW,EACX,KAAK,oBAAoB,EACzB,KAAK,SAAS,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EACjB,KAAK,SAAS,GACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAElF,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE9F,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EACL,eAAe,EACf,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,EACL,aAAa,EACb,SAAS,EACT,YAAY,EACZ,WAAW,EACX,KAAK,oBAAoB,EACzB,KAAK,SAAS,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EACjB,KAAK,SAAS,GACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAElF,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
// Check that claim against `dist/`, never against this file: a type-only re-export looks
|
|
31
31
|
// identical in source.
|
|
32
32
|
export { cn } from "./cn.js";
|
|
33
|
+
export { copyText, useCopy } from "./copy.js";
|
|
33
34
|
export { returnPathFromLocation, safeInternalPath } from "./internal-path.js";
|
|
34
35
|
export { ApiError, isAbortError, retryAfterSecs } from "./api-error.js";
|
|
35
36
|
export { createApiClient, } from "./api-client.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,2CAA2C;AAC3C,EAAE;AACF,+FAA+F;AAC/F,gGAAgG;AAChG,+FAA+F;AAC/F,iGAAiG;AACjG,0BAA0B;AAC1B,EAAE;AACF,qEAAqE;AACrE,8DAA8D;AAC9D,uEAAuE;AACvE,gEAAgE;AAChE,4EAA4E;AAC5E,4FAA4F;AAC5F,8FAA8F;AAC9F,EAAE;AACF,2FAA2F;AAC3F,iGAAiG;AACjG,+FAA+F;AAC/F,gGAAgG;AAChG,4EAA4E;AAC5E,EAAE;AACF,2FAA2F;AAC3F,iGAAiG;AACjG,qFAAqF;AACrF,6FAA6F;AAC7F,iGAAiG;AACjG,yFAAyF;AACzF,uBAAuB;AAEvB,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAkB,MAAM,oBAAoB,CAAC;AAE9F,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EACL,eAAe,GAMhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAiB,MAAM,UAAU,CAAC;AAEzE,OAAO,EACL,aAAa,EACb,SAAS,EACT,YAAY,EACZ,WAAW,GAGZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,GAGd,MAAM,qBAAsB,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,YAAY,GAQb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,iGAAiG;AACjG,kGAAkG;AAClG,6FAA6F;AAC7F,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAwB,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,2CAA2C;AAC3C,EAAE;AACF,+FAA+F;AAC/F,gGAAgG;AAChG,+FAA+F;AAC/F,iGAAiG;AACjG,0BAA0B;AAC1B,EAAE;AACF,qEAAqE;AACrE,8DAA8D;AAC9D,uEAAuE;AACvE,gEAAgE;AAChE,4EAA4E;AAC5E,4FAA4F;AAC5F,8FAA8F;AAC9F,EAAE;AACF,2FAA2F;AAC3F,iGAAiG;AACjG,+FAA+F;AAC/F,gGAAgG;AAChG,4EAA4E;AAC5E,EAAE;AACF,2FAA2F;AAC3F,iGAAiG;AACjG,qFAAqF;AACrF,6FAA6F;AAC7F,iGAAiG;AACjG,yFAAyF;AACzF,uBAAuB;AAEvB,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAoC,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAkB,MAAM,oBAAoB,CAAC;AAE9F,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EACL,eAAe,GAMhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAiB,MAAM,UAAU,CAAC;AAEzE,OAAO,EACL,aAAa,EACb,SAAS,EACT,YAAY,EACZ,WAAW,GAGZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,GAGd,MAAM,qBAAsB,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,YAAY,GAQb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,iGAAiG;AACjG,kGAAkG;AAClG,6FAA6F;AAC7F,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAwB,MAAM,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../../src/ui/combobox.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../../src/ui/combobox.tsx"],"names":[],"mappings":"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"}
|
package/dist/ui/combobox.js
CHANGED
|
@@ -65,6 +65,6 @@ export function Combobox({ value, search, getKey, getLabel, renderItem, emptyHin
|
|
|
65
65
|
],
|
|
66
66
|
// The caller's classes land BEFORE the space reserved for the buttons is
|
|
67
67
|
// re-applied below, so a `px-*` of their own cannot swallow it.
|
|
68
|
-
className) }), _jsxs("span", { className: "absolute top-1/2 right-1.5 z-10 flex -translate-y-1/2 items-center gap-0.5", children: [_jsx(Primitive.Clear, { "aria-label": clearLabel, className: "inline-flex rounded-full p-1.5 text-muted-foreground", children: _jsx(CloseGlyph, {}) }), _jsx(Primitive.Trigger, { "aria-label": openLabel, className: "inline-flex rounded-full p-1.5 text-muted-foreground", children: _jsx(ChevronGlyph, {}) })] })] }), _jsx(Primitive.Portal, { children: _jsx(Primitive.Positioner, { sideOffset: 4, ...positionerProps, className: mergeClassName("z-[60] max-w-[var(--available-width)] outline-none", positionerProps?.className), children: _jsxs(Primitive.Popup, { className: mergeClassName("w-[var(--anchor-width)] overflow-hidden border border-border bg-popover text-popover-foreground outline-none transition-[scale,opacity] data-ending-style:scale-95 data-ending-style:opacity-0 data-starting-style:scale-95 data-starting-style:opacity-0", popupClassName), children: [_jsx(Primitive.Empty, { children: _jsx("div", { className: "px-3 py-2 text-muted-foreground", children: loading ? loadingHint : emptyHint }) }), _jsx(Primitive.List, { className: "max-h-[var(--available-height)] overflow-y-auto", children: (item) => (_jsx(Primitive.Item, { value: item, className: "cursor-default px-3 py-2
|
|
68
|
+
className) }), _jsxs("span", { className: "absolute top-1/2 right-1.5 z-10 flex -translate-y-1/2 items-center gap-0.5", children: [_jsx(Primitive.Clear, { "aria-label": clearLabel, className: "inline-flex rounded-full p-1.5 text-muted-foreground", children: _jsx(CloseGlyph, {}) }), _jsx(Primitive.Trigger, { "aria-label": openLabel, className: "inline-flex rounded-full p-1.5 text-muted-foreground", children: _jsx(ChevronGlyph, {}) })] })] }), _jsx(Primitive.Portal, { children: _jsx(Primitive.Positioner, { sideOffset: 4, ...positionerProps, className: mergeClassName("z-[60] max-w-[var(--available-width)] outline-none", positionerProps?.className), children: _jsxs(Primitive.Popup, { className: mergeClassName("w-[var(--anchor-width)] overflow-hidden border border-border bg-popover text-popover-foreground outline-none transition-[scale,opacity] data-ending-style:scale-95 data-ending-style:opacity-0 data-starting-style:scale-95 data-starting-style:opacity-0", popupClassName), children: [_jsx(Primitive.Empty, { children: _jsx("div", { className: "px-3 py-2 text-muted-foreground", children: loading ? loadingHint : emptyHint }) }), _jsx(Primitive.List, { className: "max-h-[var(--available-height)] overflow-y-auto", children: (item) => (_jsx(Primitive.Item, { value: item, className: "cursor-default px-3 py-2 data-highlighted:bg-accent data-highlighted:text-accent-foreground forced-colors:data-highlighted:outline-2 forced-colors:data-highlighted:-outline-offset-2", children: renderItem ? renderItem(item) : getLabel(item) }, getKey(item))) })] }) }) })] }));
|
|
69
69
|
}
|
|
70
70
|
//# sourceMappingURL=combobox.js.map
|
package/dist/ui/combobox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combobox.js","sourceRoot":"","sources":["../../src/ui/combobox.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"combobox.js","sourceRoot":"","sources":["../../src/ui/combobox.tsx"],"names":[],"mappings":"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"}
|
package/dist/ui/select.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/ui/select.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKtE,eAAO,MAAM,UAAU,uBAAiB,CAAC;AACzC,eAAO,MAAM,aAAa,wJAAoB,CAAC;AAC/C,eAAO,MAAM,WAAW,oJAAkB,CAAC;AAC3C,eAAO,MAAM,UAAU,mJAAiB,CAAC;AACzC,eAAO,MAAM,YAAY,oJAAmB,CAAC;AAC7C,eAAO,MAAM,gBAAgB,wJAAuB,CAAC;AACrD,eAAO,MAAM,WAAW,mJAAkB,CAAC;AAC3C,eAAO,MAAM,UAAU,kJAAiB,CAAC;AACzC,eAAO,MAAM,UAAU,0IAAiB,CAAC;AACzC,eAAO,MAAM,mBAAmB,4JAA0B,CAAC;AAC3D,eAAO,MAAM,cAAc,iJAAqB,CAAC;AACjD,eAAO,MAAM,WAAW,mJAAkB,CAAC;AAC3C,eAAO,MAAM,gBAAgB,wJAAuB,CAAC;AACrD,eAAO,MAAM,eAAe,0IAAsB,CAAC;AAEnD,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACrD,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,IAAI,CACvD,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAC9B,UAAU,GAAG,OAAO,GAAG,cAAc,GAAG,UAAU,CACnD,GAAG;IACF,OAAO,CAAC,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IACrC,gFAAgF;IAChF,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;OAGG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,wCAAwC;IACxC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACpD,cAAc,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACvD,YAAY,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;IACvC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;CAC9C,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,EAChD,KAAK,EACL,OAAY,EACZ,WAAW,EACX,UAAU,EACV,UAAU,EACV,KAAK,EACL,OAAO,EACP,SAAS,EACT,SAAS,EACT,cAAc,EACd,YAAY,EACZ,eAAe,EACf,GAAG,IAAI,EACR,EAAE,WAAW,CAAC,CAAC,CAAC,+
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/ui/select.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKtE,eAAO,MAAM,UAAU,uBAAiB,CAAC;AACzC,eAAO,MAAM,aAAa,wJAAoB,CAAC;AAC/C,eAAO,MAAM,WAAW,oJAAkB,CAAC;AAC3C,eAAO,MAAM,UAAU,mJAAiB,CAAC;AACzC,eAAO,MAAM,YAAY,oJAAmB,CAAC;AAC7C,eAAO,MAAM,gBAAgB,wJAAuB,CAAC;AACrD,eAAO,MAAM,WAAW,mJAAkB,CAAC;AAC3C,eAAO,MAAM,UAAU,kJAAiB,CAAC;AACzC,eAAO,MAAM,UAAU,0IAAiB,CAAC;AACzC,eAAO,MAAM,mBAAmB,4JAA0B,CAAC;AAC3D,eAAO,MAAM,cAAc,iJAAqB,CAAC;AACjD,eAAO,MAAM,WAAW,mJAAkB,CAAC;AAC3C,eAAO,MAAM,gBAAgB,wJAAuB,CAAC;AACrD,eAAO,MAAM,eAAe,0IAAsB,CAAC;AAEnD,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACrD,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,IAAI,CACvD,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAC9B,UAAU,GAAG,OAAO,GAAG,cAAc,GAAG,UAAU,CACnD,GAAG;IACF,OAAO,CAAC,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IACrC,gFAAgF;IAChF,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;OAGG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,wCAAwC;IACxC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACpD,cAAc,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACvD,YAAY,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;IACvC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;CAC9C,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,EAChD,KAAK,EACL,OAAY,EACZ,WAAW,EACX,UAAU,EACV,UAAU,EACV,KAAK,EACL,OAAO,EACP,SAAS,EACT,SAAS,EACT,cAAc,EACd,YAAY,EACZ,eAAe,EACf,GAAG,IAAI,EACR,EAAE,WAAW,CAAC,CAAC,CAAC,+BAwGhB"}
|
package/dist/ui/select.js
CHANGED
|
@@ -43,6 +43,6 @@ export function Select({ value, options = [], placeholder, emptyLabel, clearLabe
|
|
|
43
43
|
// An Item with `value={null}`, not a button above the list: only an item is
|
|
44
44
|
// reachable by arrow keys and typeahead, and only an item closes the popup
|
|
45
45
|
// on its own. `null` is what arrives at `onValueChange`.
|
|
46
|
-
_jsxs(Primitive.Item, { value: null, className: "flex cursor-default items-center gap-2 px-3 py-2 text-muted-foreground outline-
|
|
46
|
+
_jsxs(Primitive.Item, { value: null, className: "flex cursor-default items-center gap-2 px-3 py-2 text-muted-foreground focus-visible:outline-hidden focus-visible:-outline-offset-2 data-highlighted:bg-accent data-highlighted:text-accent-foreground", children: [_jsx("span", { className: "size-4 shrink-0", "aria-hidden": "true" }), _jsx(Primitive.ItemText, { children: clearLabel })] })) : null, options.length === 0 ? (_jsx("div", { className: "px-3 py-2 text-muted-foreground", children: emptyLabel })) : (options.map((option) => (_jsxs(Primitive.Item, { value: option.value, disabled: option.disabled, className: "flex cursor-default items-center gap-2 px-3 py-2 focus-visible:outline-hidden focus-visible:-outline-offset-2 data-disabled:pointer-events-none data-disabled:opacity-50 data-highlighted:bg-accent data-highlighted:text-accent-foreground", children: [_jsx("span", { className: "size-4 shrink-0", children: _jsx(Primitive.ItemIndicator, { children: indicator ?? _jsx(CheckGlyph, {}) }) }), option.icon ? (_jsx("span", { className: "inline-flex shrink-0", children: option.icon })) : null, _jsx(Primitive.ItemText, { children: option.label })] }, option.value))))] }) }) }) })] }));
|
|
47
47
|
}
|
|
48
48
|
//# sourceMappingURL=select.js.map
|
package/dist/ui/select.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/ui/select.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/ui/select.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gusnips/react",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.13",
|
|
4
4
|
"description": "The headless runtime under a Vite + React SPA: typed fetch client with single-flight refresh, auth store, query defaults, route guards, error boundary, stale-tab recovery, i18n bootstrap.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"release:major": "bun pm version major && bun publish --access public"
|
|
81
81
|
},
|
|
82
82
|
"dependencies": {
|
|
83
|
-
"@gusnips/http": "0.1.
|
|
83
|
+
"@gusnips/http": "0.1.1",
|
|
84
84
|
"clsx": "^2.1.1",
|
|
85
85
|
"tailwind-merge": "^3.6.0"
|
|
86
86
|
},
|
package/src/copy.test.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { copyText } from "./copy.ts";
|
|
3
|
+
|
|
4
|
+
afterEach(() => {
|
|
5
|
+
vi.unstubAllGlobals();
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
describe("copyText", () => {
|
|
9
|
+
it("answers true once the clipboard has the text", async () => {
|
|
10
|
+
const writeText = vi.fn(() => Promise.resolve());
|
|
11
|
+
vi.stubGlobal("navigator", { clipboard: { writeText } });
|
|
12
|
+
await expect(copyText("sk_live_1")).resolves.toBe(true);
|
|
13
|
+
expect(writeText).toHaveBeenCalledWith("sk_live_1");
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("answers false when the browser refuses the write", async () => {
|
|
17
|
+
vi.stubGlobal("navigator", {
|
|
18
|
+
clipboard: { writeText: () => Promise.reject(new DOMException("denied", "NotAllowedError")) },
|
|
19
|
+
});
|
|
20
|
+
await expect(copyText("sk_live_1")).resolves.toBe(false);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Over plain http there is no `navigator.clipboard`, so `writeText` is read off `undefined` and
|
|
24
|
+
// throws before any promise exists. Two copies in the fleet let that escape the click handler.
|
|
25
|
+
it("answers false, and does not throw, where there is no clipboard API", async () => {
|
|
26
|
+
vi.stubGlobal("navigator", {});
|
|
27
|
+
await expect(copyText("sk_live_1")).resolves.toBe(false);
|
|
28
|
+
});
|
|
29
|
+
});
|
package/src/copy.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
// Eight products wrote a copy button, and five of them failed silently, one under a comment
|
|
4
|
+
// saying it must not. Silent is worse than it looks: the reader pastes whatever was already on
|
|
5
|
+
// the clipboard, and for a key shown once that is pasting something else over the only copy.
|
|
6
|
+
// Two more called `writeText` outside a `try`, and on a page not served over https there is no
|
|
7
|
+
// `navigator.clipboard` at all, so the click threw a TypeError instead of rejecting.
|
|
8
|
+
//
|
|
9
|
+
// No `execCommand` fallback, and none of the eight had one: it is deprecated, the async API is
|
|
10
|
+
// there in every browser over https, and a copy that says it failed beats a shim that pretends.
|
|
11
|
+
|
|
12
|
+
/** Write `text` to the clipboard. `false` when the browser refused or has no clipboard API. */
|
|
13
|
+
export async function copyText(text: string): Promise<boolean> {
|
|
14
|
+
try {
|
|
15
|
+
await navigator.clipboard.writeText(text);
|
|
16
|
+
return true;
|
|
17
|
+
} catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type CopyState = "idle" | "copied" | "failed";
|
|
23
|
+
|
|
24
|
+
export interface CopyOptions {
|
|
25
|
+
/** How long `"copied"` shows. Default 2000 ms. */
|
|
26
|
+
copiedMs?: number;
|
|
27
|
+
/** How long `"failed"` shows. Default 6000 ms: a failure is a sentence the reader has to act on. */
|
|
28
|
+
failedMs?: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A copy with an outcome the reader can see. What it says stays yours — "Copied", or "Select it
|
|
33
|
+
* and copy it yourself", in a label or a toast — and so does announcing it: a label that changes
|
|
34
|
+
* needs `aria-live="polite"` to be heard.
|
|
35
|
+
*
|
|
36
|
+
* The outcome goes back to `"idle"` on its own. A "Copied" that never clears makes the second copy
|
|
37
|
+
* look like it did not take.
|
|
38
|
+
*/
|
|
39
|
+
export function useCopy({ copiedMs = 2000, failedMs = 6000 }: CopyOptions = {}): {
|
|
40
|
+
state: CopyState;
|
|
41
|
+
/** Resolves `false` instead of throwing, so a caller can toast without a `catch`. */
|
|
42
|
+
copy: (text: string) => Promise<boolean>;
|
|
43
|
+
} {
|
|
44
|
+
// A new object on every copy, so copying again restarts the clock even when the state is the
|
|
45
|
+
// same: two copies a second apart read "Copied" for two seconds after the second one.
|
|
46
|
+
const [outcome, setOutcome] = useState<{ state: CopyState }>({ state: "idle" });
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (outcome.state === "idle") return;
|
|
50
|
+
const ms = outcome.state === "copied" ? copiedMs : failedMs;
|
|
51
|
+
const timer = setTimeout(() => setOutcome({ state: "idle" }), ms);
|
|
52
|
+
return () => clearTimeout(timer);
|
|
53
|
+
}, [outcome, copiedMs, failedMs]);
|
|
54
|
+
|
|
55
|
+
const copy = useCallback(async (text: string) => {
|
|
56
|
+
const copied = await copyText(text);
|
|
57
|
+
setOutcome({ state: copied ? "copied" : "failed" });
|
|
58
|
+
return copied;
|
|
59
|
+
}, []);
|
|
60
|
+
|
|
61
|
+
return { state: outcome.state, copy };
|
|
62
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
// identical in source.
|
|
32
32
|
|
|
33
33
|
export { cn } from "./cn.ts";
|
|
34
|
+
export { copyText, useCopy, type CopyOptions, type CopyState } from "./copy.ts";
|
|
34
35
|
export { returnPathFromLocation, safeInternalPath, type PathParts } from "./internal-path.ts";
|
|
35
36
|
|
|
36
37
|
export { ApiError, isAbortError, retryAfterSecs } from "./api-error.ts";
|
package/src/ui/combobox.tsx
CHANGED
|
@@ -222,13 +222,17 @@ export function Combobox<T>({
|
|
|
222
222
|
</Primitive.Empty>
|
|
223
223
|
{/* `--available-height` is the room the positioner measured between the anchor
|
|
224
224
|
and the edge of the viewport. Without it the list is unbounded and a long
|
|
225
|
-
result set runs off the bottom of the screen with no way to reach the end.
|
|
225
|
+
result set runs off the bottom of the screen with no way to reach the end.
|
|
226
|
+
Focus stays in the input and the highlight follows the arrow keys, so an item
|
|
227
|
+
never matches `:focus-visible`. Forced colors paint no background, which takes
|
|
228
|
+
the highlight with it, so there the highlighted item draws an outline, inset
|
|
229
|
+
or the list's overflow clips it at both edges. */}
|
|
226
230
|
<Primitive.List className="max-h-[var(--available-height)] overflow-y-auto">
|
|
227
231
|
{(item: T) => (
|
|
228
232
|
<Primitive.Item
|
|
229
233
|
key={getKey(item)}
|
|
230
234
|
value={item}
|
|
231
|
-
className="cursor-default px-3 py-2
|
|
235
|
+
className="cursor-default px-3 py-2 data-highlighted:bg-accent data-highlighted:text-accent-foreground forced-colors:data-highlighted:outline-2 forced-colors:data-highlighted:-outline-offset-2"
|
|
232
236
|
>
|
|
233
237
|
{renderItem ? renderItem(item) : getLabel(item)}
|
|
234
238
|
</Primitive.Item>
|
package/src/ui/focus.test.ts
CHANGED
|
@@ -27,15 +27,18 @@ const sources = readdirSync(here)
|
|
|
27
27
|
* guard that fails on its own explanation teaches people to delete the explanation.
|
|
28
28
|
*/
|
|
29
29
|
function linesMatching(text: string, pattern: RegExp): number[] {
|
|
30
|
+
return codeLines(text)
|
|
31
|
+
.map((line, i) => (pattern.test(line) ? i + 1 : 0))
|
|
32
|
+
.filter(Boolean);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function codeLines(text: string): string[] {
|
|
30
36
|
// Block comments are BLANKED, not deleted: removing them would collapse lines and every number
|
|
31
37
|
// reported after one would point at the wrong place. (That is also why this cannot share
|
|
32
38
|
// `menu.test.ts`'s `codeOf`, which strips outright because it only ever counts occurrences.)
|
|
33
39
|
// Blanking also means a wrapped comment line is ignored whether or not it opens with a `*`.
|
|
34
40
|
const code = text.replace(/\/\*[\s\S]*?\*\//g, (block) => block.replace(/[^\n]/g, " "));
|
|
35
|
-
return code
|
|
36
|
-
.split("\n")
|
|
37
|
-
.map((line, i) => (!line.trim().startsWith("//") && pattern.test(line) ? i + 1 : 0))
|
|
38
|
-
.filter(Boolean);
|
|
41
|
+
return code.split("\n").map((line) => (line.trim().startsWith("//") ? "" : line));
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
describe("the wrappers do not draw their own focus ring", () => {
|
|
@@ -49,21 +52,21 @@ describe("the wrappers do not draw their own focus ring", () => {
|
|
|
49
52
|
});
|
|
50
53
|
|
|
51
54
|
// The other half: `outline-none` is legitimate on a container that takes focus
|
|
52
|
-
// programmatically (a Popup, its Positioner, a
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
it.each(sources)("$name resets the outline only on popup
|
|
55
|
+
// programmatically (a Popup, its Positioner, a Backdrop), and nowhere else. An ITEM is not one
|
|
56
|
+
// of those, even though its highlight shows focus: forced colors paint no background, so the
|
|
57
|
+
// highlight is gone there and a bare `outline-none` leaves the item with nothing at all. An item
|
|
58
|
+
// hides the outline with `outline-hidden`, which Tailwind brings back in forced colors.
|
|
59
|
+
it.each(sources)("$name resets the outline only on popup containers", ({ text }) => {
|
|
60
|
+
const containers = new Set(["Popup", "Positioner", "Backdrop", "Viewport"]);
|
|
61
|
+
const code = codeLines(text);
|
|
57
62
|
const offenders = linesMatching(text, /outline-none/).filter((line) => {
|
|
58
|
-
// ponytail:
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
.join("\n");
|
|
66
|
-
return !/<Primitive\.(Popup|Positioner|Item|ItemsEmpty|Backdrop|Viewport)\b/.test(context);
|
|
63
|
+
// ponytail: the element is taken to be the nearest `<Primitive.X` at or above the line,
|
|
64
|
+
// since a class string sits in its element's own props. The ceiling is a plain element
|
|
65
|
+
// nested inside a popup part, which would read as that part; none exists today. If one
|
|
66
|
+
// does, parse the enclosing JSX element instead.
|
|
67
|
+
const above = code.slice(0, line).join("\n");
|
|
68
|
+
const part = [...above.matchAll(/<Primitive\.(\w+)/g)].at(-1)?.[1];
|
|
69
|
+
return part === undefined || !containers.has(part);
|
|
67
70
|
});
|
|
68
71
|
expect(offenders).toEqual([]);
|
|
69
72
|
});
|
package/src/ui/select.tsx
CHANGED
|
@@ -145,6 +145,11 @@ export function Select<T extends string = string>({
|
|
|
145
145
|
popupClassName,
|
|
146
146
|
)}
|
|
147
147
|
>
|
|
148
|
+
{/* An item takes real focus as the arrow keys move, and its highlight is what shows
|
|
149
|
+
it, so the items hide the app's outline. `outline-hidden`, not `outline-none`:
|
|
150
|
+
forced colors paint no background, so the highlight is gone there, and
|
|
151
|
+
`outline-hidden` is the one that comes back as an outline. Inset, or the list's
|
|
152
|
+
overflow clips it at both edges. */}
|
|
148
153
|
<Primitive.List className="max-h-[var(--available-height)] overflow-y-auto">
|
|
149
154
|
{clearLabel !== undefined && value != null ? (
|
|
150
155
|
// An Item with `value={null}`, not a button above the list: only an item is
|
|
@@ -152,7 +157,7 @@ export function Select<T extends string = string>({
|
|
|
152
157
|
// on its own. `null` is what arrives at `onValueChange`.
|
|
153
158
|
<Primitive.Item
|
|
154
159
|
value={null}
|
|
155
|
-
className="flex cursor-default items-center gap-2 px-3 py-2 text-muted-foreground outline-
|
|
160
|
+
className="flex cursor-default items-center gap-2 px-3 py-2 text-muted-foreground focus-visible:outline-hidden focus-visible:-outline-offset-2 data-highlighted:bg-accent data-highlighted:text-accent-foreground"
|
|
156
161
|
>
|
|
157
162
|
<span className="size-4 shrink-0" aria-hidden="true" />
|
|
158
163
|
<Primitive.ItemText>{clearLabel}</Primitive.ItemText>
|
|
@@ -166,7 +171,7 @@ export function Select<T extends string = string>({
|
|
|
166
171
|
key={option.value}
|
|
167
172
|
value={option.value}
|
|
168
173
|
disabled={option.disabled}
|
|
169
|
-
className="flex cursor-default items-center gap-2 px-3 py-2 outline-
|
|
174
|
+
className="flex cursor-default items-center gap-2 px-3 py-2 focus-visible:outline-hidden focus-visible:-outline-offset-2 data-disabled:pointer-events-none data-disabled:opacity-50 data-highlighted:bg-accent data-highlighted:text-accent-foreground"
|
|
170
175
|
>
|
|
171
176
|
{/* The mark keeps a column of its own whether or not it is showing, so
|
|
172
177
|
the labels do not shift by 16px when the selection moves. */}
|