@repraze/kernelkit 0.1.0-alpha.5 → 0.1.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/pager.d.ts +1 -1
- package/dist/components/pager.d.ts.map +1 -1
- package/dist/components/pager.js +4 -4
- package/dist/components/pager.js.map +1 -1
- package/dist/components/search-trigger.d.ts +10 -3
- package/dist/components/search-trigger.d.ts.map +1 -1
- package/dist/components/search-trigger.js +21 -3
- package/dist/components/search-trigger.js.map +1 -1
- package/dist/lib/recipes.d.ts +6 -2
- package/dist/lib/recipes.d.ts.map +1 -1
- package/dist/lib/recipes.js +6 -2
- package/dist/lib/recipes.js.map +1 -1
- package/dist/site/suite-header.d.ts +4 -1
- package/dist/site/suite-header.d.ts.map +1 -1
- package/dist/site/suite-header.js +7 -2
- package/dist/site/suite-header.js.map +1 -1
- package/package.json +1 -1
- package/src/components/pager.tsx +8 -8
- package/src/components/search-trigger.tsx +33 -6
- package/src/lib/recipes.ts +6 -2
- package/src/site/suite-header.tsx +25 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useRender } from "@base-ui/react/use-render";
|
|
2
2
|
import type * as React from "react";
|
|
3
|
-
/** Previous / next page links at the end of a page
|
|
3
|
+
/** Previous / next page links at the end of a page: stacked on phones, side by side from `sm`. */
|
|
4
4
|
declare function Pager({ className, render, ...props }: useRender.ComponentProps<"nav">): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
|
|
5
5
|
interface PagerLinkProps extends useRender.ComponentProps<"a"> {
|
|
6
6
|
direction: "previous" | "next";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pager.d.ts","sourceRoot":"","sources":["../../src/components/pager.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAC,SAAS,EAAC,MAAM,2BAA2B,CAAC;AAIpD,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,
|
|
1
|
+
{"version":3,"file":"pager.d.ts","sourceRoot":"","sources":["../../src/components/pager.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAC,SAAS,EAAC,MAAM,2BAA2B,CAAC;AAIpD,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,kGAAkG;AAClG,iBAAS,KAAK,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAC,EAAE,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,0EAa5E;AAED,UAAU,cAAe,SAAQ,SAAS,CAAC,cAAc,CAAC,GAAG,CAAC;IAC1D,SAAS,EAAE,UAAU,GAAG,MAAM,CAAC;IAC/B,sEAAsE;IACtE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,qGAAqG;AACrG,iBAAS,SAAS,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAC,EAAE,cAAc,0EAkC3F;AAED,OAAO,EAAC,KAAK,EAAE,SAAS,EAAC,CAAC;AAC1B,YAAY,EAAC,cAAc,EAAC,CAAC"}
|
package/dist/components/pager.js
CHANGED
|
@@ -5,13 +5,13 @@ import { useRender } from "@base-ui/react/use-render";
|
|
|
5
5
|
import { focusRing } from "@repraze/kernelkit/lib/recipes";
|
|
6
6
|
import { cn } from "cn";
|
|
7
7
|
import { ArrowLeftIcon, ArrowRightIcon } from "lucide-react";
|
|
8
|
-
/** Previous / next page links at the end of a page
|
|
8
|
+
/** Previous / next page links at the end of a page: stacked on phones, side by side from `sm`. */
|
|
9
9
|
function Pager({ className, render, ...props }) {
|
|
10
10
|
return useRender({
|
|
11
11
|
defaultTagName: "nav",
|
|
12
12
|
props: mergeProps({
|
|
13
13
|
"aria-label": "Pages",
|
|
14
|
-
className: cn("grid
|
|
14
|
+
className: cn("grid gap-3 border-t border-border pt-6 sm:grid-cols-2 sm:gap-4", className),
|
|
15
15
|
}, props),
|
|
16
16
|
render,
|
|
17
17
|
state: { slot: "pager" },
|
|
@@ -25,8 +25,8 @@ function PagerLink({ className, render, direction, label, children, ...props })
|
|
|
25
25
|
defaultTagName: "a",
|
|
26
26
|
props: mergeProps({
|
|
27
27
|
rel: next ? "next" : "prev",
|
|
28
|
-
className: cn("group/pager flex flex-col gap-1 rounded-lg border border-border px-4 py-3 transition-colors hover:border-primary-text hover:bg-hover", focusRing, next ? "
|
|
29
|
-
children: (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-xs text-muted-foreground", children: label ?? (next ? "Next" : "Previous") }), _jsxs("span", { className: "flex items-center gap-1.5 font-medium", children: [!next && (_jsx(Arrow, { className: "size-4 transition-transform group-hover/pager:-translate-x-0.5" })), children, next && (_jsx(Arrow, { className: "size-4 transition-transform group-hover/pager:translate-x-0.5" }))] })] })),
|
|
28
|
+
className: cn("group/pager flex min-w-0 flex-col gap-1 rounded-lg border border-border px-4 py-3 transition-colors hover:border-primary-text hover:bg-hover", focusRing, next ? "items-end text-end sm:col-start-2" : "items-start sm:col-start-1", className),
|
|
29
|
+
children: (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-xs text-muted-foreground", children: label ?? (next ? "Next" : "Previous") }), _jsxs("span", { className: "flex max-w-full items-center gap-1.5 font-medium", children: [!next && (_jsx(Arrow, { className: "size-4 shrink-0 transition-transform group-hover/pager:-translate-x-0.5" })), _jsx("span", { className: "min-w-0 wrap-break-word", children: children }), next && (_jsx(Arrow, { className: "size-4 shrink-0 transition-transform group-hover/pager:translate-x-0.5" }))] })] })),
|
|
30
30
|
}, props),
|
|
31
31
|
render,
|
|
32
32
|
state: { slot: "pager-link", direction },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pager.js","sourceRoot":"","sources":["../../src/components/pager.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAC,UAAU,EAAC,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAC,SAAS,EAAC,MAAM,2BAA2B,CAAC;AACpD,OAAO,EAAC,SAAS,EAAC,MAAM,gCAAgC,CAAC;AACzD,OAAO,EAAC,EAAE,EAAC,MAAM,IAAI,CAAC;AACtB,OAAO,EAAC,aAAa,EAAE,cAAc,EAAC,MAAM,cAAc,CAAC;AAG3D,
|
|
1
|
+
{"version":3,"file":"pager.js","sourceRoot":"","sources":["../../src/components/pager.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAC,UAAU,EAAC,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAC,SAAS,EAAC,MAAM,2BAA2B,CAAC;AACpD,OAAO,EAAC,SAAS,EAAC,MAAM,gCAAgC,CAAC;AACzD,OAAO,EAAC,EAAE,EAAC,MAAM,IAAI,CAAC;AACtB,OAAO,EAAC,aAAa,EAAE,cAAc,EAAC,MAAM,cAAc,CAAC;AAG3D,kGAAkG;AAClG,SAAS,KAAK,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAkC;IACzE,OAAO,SAAS,CAAC;QACb,cAAc,EAAE,KAAK;QACrB,KAAK,EAAE,UAAU,CACb;YACI,YAAY,EAAE,OAAO;YACrB,SAAS,EAAE,EAAE,CAAC,gEAAgE,EAAE,SAAS,CAAC;SAC7F,EACD,KAAK,CACR;QACD,MAAM;QACN,KAAK,EAAE,EAAC,IAAI,EAAE,OAAO,EAAC;KACzB,CAAC,CAAC;AACP,CAAC;AAQD,qGAAqG;AACrG,SAAS,SAAS,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAiB;IACxF,MAAM,IAAI,GAAG,SAAS,KAAK,MAAM,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC;IACpD,OAAO,SAAS,CAAC;QACb,cAAc,EAAE,GAAG;QACnB,KAAK,EAAE,UAAU,CACb;YACI,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YAC3B,SAAS,EAAE,EAAE,CACT,8IAA8I,EAC9I,SAAS,EACT,IAAI,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,4BAA4B,EACzE,SAAS,CACZ;YACD,QAAQ,EAAE,CACN,8BACI,eAAM,SAAS,EAAC,+BAA+B,YAAE,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,GAAQ,EAC9F,gBAAM,SAAS,EAAC,kDAAkD,aAC7D,CAAC,IAAI,IAAI,CACN,KAAC,KAAK,IAAC,SAAS,EAAC,yEAAyE,GAAG,CAChG,EACD,eAAM,SAAS,EAAC,yBAAyB,YAAE,QAAQ,GAAQ,EAC1D,IAAI,IAAI,CACL,KAAC,KAAK,IAAC,SAAS,EAAC,wEAAwE,GAAG,CAC/F,IACE,IACR,CACN;SACJ,EACD,KAAK,CACR;QACD,MAAM;QACN,KAAK,EAAE,EAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC;KACzC,CAAC,CAAC;AACP,CAAC;AAED,OAAO,EAAC,KAAK,EAAE,SAAS,EAAC,CAAC"}
|
|
@@ -12,12 +12,19 @@ declare function useSearchHotkeys(onOpen: (toggle: boolean) => void, { enabled }
|
|
|
12
12
|
interface SearchTriggerProps extends React.ComponentProps<typeof Button> {
|
|
13
13
|
/** Placeholder text. */
|
|
14
14
|
children?: React.ReactNode;
|
|
15
|
+
/** Full width with its placeholder at every size (a phone menu); otherwise an icon below `sm`. */
|
|
16
|
+
expanded?: boolean;
|
|
15
17
|
}
|
|
18
|
+
type SearchHandler = React.MouseEventHandler<HTMLButtonElement>;
|
|
19
|
+
declare function SearchRelay({ handler, children }: {
|
|
20
|
+
handler: React.RefObject<SearchHandler | null>;
|
|
21
|
+
children: React.ReactNode;
|
|
22
|
+
}): React.JSX.Element;
|
|
16
23
|
/**
|
|
17
24
|
* Header search button: icon, placeholder, OS-aware shortcut. Same 32px height as the header's icon buttons. Open your dialog in `onClick`.
|
|
18
25
|
* The keycap gets the same inset on the right as top/bottom (32 - 20 = 6px each side, border included).
|
|
19
26
|
*/
|
|
20
|
-
declare function SearchTrigger({ children, className, ...props }: SearchTriggerProps): React.JSX.Element;
|
|
21
|
-
export { SearchTrigger, useModKey, useSearchHotkeys };
|
|
22
|
-
export type { SearchTriggerProps };
|
|
27
|
+
declare function SearchTrigger({ children, expanded, className, onClick, ...props }: SearchTriggerProps): React.JSX.Element;
|
|
28
|
+
export { SearchRelay, SearchTrigger, useModKey, useSearchHotkeys };
|
|
29
|
+
export type { SearchHandler, SearchTriggerProps };
|
|
23
30
|
//# sourceMappingURL=search-trigger.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-trigger.d.ts","sourceRoot":"","sources":["../../src/components/search-trigger.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAC,MAAM,EAAC,MAAM,sCAAsC,CAAC;AAI5D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,gFAAgF;AAChF,iBAAS,SAAS,IAAI,MAAM,CAQ3B;AAQD;;;GAGG;AACH,iBAAS,gBAAgB,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,EAAE,EAAC,OAAc,EAAC,GAAE;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAM,QAiBtG;AAED,UAAU,kBAAmB,SAAQ,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC;IACpE,wBAAwB;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"search-trigger.d.ts","sourceRoot":"","sources":["../../src/components/search-trigger.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAC,MAAM,EAAC,MAAM,sCAAsC,CAAC;AAI5D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,gFAAgF;AAChF,iBAAS,SAAS,IAAI,MAAM,CAQ3B;AAQD;;;GAGG;AACH,iBAAS,gBAAgB,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,EAAE,EAAC,OAAc,EAAC,GAAE;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAM,QAiBtG;AAED,UAAU,kBAAmB,SAAQ,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC;IACpE,wBAAwB;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,kGAAkG;IAClG,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,KAAK,aAAa,GAAG,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;AAQhE,iBAAS,WAAW,CAAC,EAAC,OAAO,EAAE,QAAQ,EAAC,EAAE;IAAC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAC,qBAEpH;AAED;;;GAGG;AACH,iBAAS,aAAa,CAAC,EAAC,QAAoB,EAAE,QAAgB,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK,EAAC,EAAE,kBAAkB,qBA+BhH;AAED,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB,EAAC,CAAC;AACjE,YAAY,EAAC,aAAa,EAAE,kBAAkB,EAAC,CAAC"}
|
|
@@ -43,13 +43,31 @@ function useSearchHotkeys(onOpen, { enabled = true } = {}) {
|
|
|
43
43
|
return () => window.removeEventListener("keydown", onKey);
|
|
44
44
|
}, [onOpen, enabled]);
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Lets a shell open the page's search from another place (SuiteHeader's phone menu) without a second
|
|
48
|
+
* dialog: a SearchTrigger inside `SearchRelay` hands its `onClick` to the relay's ref.
|
|
49
|
+
*/
|
|
50
|
+
const SearchRelayContext = React.createContext(null);
|
|
51
|
+
function SearchRelay({ handler, children }) {
|
|
52
|
+
return _jsx(SearchRelayContext.Provider, { value: handler, children: children });
|
|
53
|
+
}
|
|
46
54
|
/**
|
|
47
55
|
* Header search button: icon, placeholder, OS-aware shortcut. Same 32px height as the header's icon buttons. Open your dialog in `onClick`.
|
|
48
56
|
* The keycap gets the same inset on the right as top/bottom (32 - 20 = 6px each side, border included).
|
|
49
57
|
*/
|
|
50
|
-
function SearchTrigger({ children = "Search…", className, ...props }) {
|
|
58
|
+
function SearchTrigger({ children = "Search…", expanded = false, className, onClick, ...props }) {
|
|
51
59
|
const mod = useModKey();
|
|
52
|
-
|
|
60
|
+
const relay = React.useContext(SearchRelayContext);
|
|
61
|
+
React.useEffect(() => {
|
|
62
|
+
if (!relay) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
relay.current = onClick ?? null;
|
|
66
|
+
return () => {
|
|
67
|
+
relay.current = null;
|
|
68
|
+
};
|
|
69
|
+
}, [relay, onClick]);
|
|
70
|
+
return (_jsxs(Button, { variant: "outline", "aria-label": "Search", "data-slot": "search-trigger", "data-expanded": expanded || undefined, className: cn("justify-start text-muted-foreground", expanded ? "w-full pr-1.25 pl-2.5" : "w-8 px-0 sm:w-40 sm:pr-1.25 sm:pl-2.5 lg:w-56", className), onClick: onClick, ...props, children: [_jsx(SearchIcon, { "data-icon": "inline-start", className: expanded ? undefined : "mx-auto sm:mx-0" }), _jsx("span", { className: cn("flex-1 truncate text-start", !expanded && "hidden sm:inline"), children: children }), _jsxs(Kbd, { className: "hidden sm:inline-flex", children: [mod, " K"] })] }));
|
|
53
71
|
}
|
|
54
|
-
export { SearchTrigger, useModKey, useSearchHotkeys };
|
|
72
|
+
export { SearchRelay, SearchTrigger, useModKey, useSearchHotkeys };
|
|
55
73
|
//# sourceMappingURL=search-trigger.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-trigger.js","sourceRoot":"","sources":["../../src/components/search-trigger.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAC,MAAM,EAAC,MAAM,sCAAsC,CAAC;AAC5D,OAAO,EAAC,GAAG,EAAC,MAAM,mCAAmC,CAAC;AACtD,OAAO,EAAC,EAAE,EAAC,MAAM,IAAI,CAAC;AACtB,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,gFAAgF;AAChF,SAAS,SAAS;IACd,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC7C,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACjB,IAAI,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,IAAI,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;YACpE,MAAM,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,GAAG,CAAC;AACf,CAAC;AAED,uEAAuE;AACvE,SAAS,UAAU,CAAC,MAA0B;IAC1C,MAAM,EAAE,GAAG,MAA4B,CAAC;IACxC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,iBAAiB,IAAI,4BAA4B,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;AAC3F,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,MAAiC,EAAE,EAAC,OAAO,GAAG,IAAI,KAAyB,EAAE;IACnG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACjB,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,OAAO;QACX,CAAC;QACD,MAAM,KAAK,GAAG,CAAC,CAAgB,EAAE,EAAE;YAC/B,IAAI,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1D,CAAC,CAAC,cAAc,EAAE,CAAC;gBACnB,MAAM,CAAC,IAAI,CAAC,CAAC;YACjB,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzF,CAAC,CAAC,cAAc,EAAE,CAAC;gBACnB,MAAM,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC;QACL,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC1C,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9D,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAC1B,CAAC;
|
|
1
|
+
{"version":3,"file":"search-trigger.js","sourceRoot":"","sources":["../../src/components/search-trigger.tsx"],"names":[],"mappings":"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"}
|
package/dist/lib/recipes.d.ts
CHANGED
|
@@ -25,8 +25,12 @@ export declare const listItem = "after:pointer-events-none after:absolute after:
|
|
|
25
25
|
export declare const listLabel = "px-2 py-1.5 text-xs font-medium text-muted-foreground";
|
|
26
26
|
/** Separator inside a popup or list. */
|
|
27
27
|
export declare const listSeparator = "-mx-1 my-1 h-px bg-border";
|
|
28
|
-
/**
|
|
29
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Modal backdrop for dialog, alert dialog, sheet, drawer. A transition on Base UI's starting/ending styles,
|
|
30
|
+
* not a keyframe: the backdrop stays mounted until the slower panel finishes, and a finished keyframe
|
|
31
|
+
* (no fill) snapped it back to full dim and blur for that wait, a flash on close.
|
|
32
|
+
*/
|
|
33
|
+
export declare const backdrop = "fixed inset-0 isolate z-50 bg-black/40 transition-opacity duration-150 ease-out motion-reduce:transition-none supports-backdrop-filter:backdrop-blur-xs data-starting-style:opacity-0 data-ending-style:opacity-0";
|
|
30
34
|
/** Title in cards, dialogs, sheets, popovers, empty states, alerts (§5). */
|
|
31
35
|
export declare const heading = "font-heading font-medium tracking-tight";
|
|
32
36
|
/** Empty track / placeholder: progress & meter tracks, skeletons, unlit segments. bg-muted vanishes on cards. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recipes.d.ts","sourceRoot":"","sources":["../../src/lib/recipes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wDAAwD;AACxD,eAAO,MAAM,SAAS,2FAA2F,CAAC;AAElH,2CAA2C;AAC3C,eAAO,MAAM,WAAW,gHACyF,CAAC;AAElH,iGAAiG;AACjG,eAAO,MAAM,YAAY,qNAC6L,CAAC;AAEvN,iFAAiF;AACjF,eAAO,MAAM,YAAY,+GACuF,CAAC;AAEjH,oCAAoC;AACpC,eAAO,MAAM,WAAW,yWACkV,CAAC;AAE3W;;;;GAIG;AACH,eAAO,MAAM,YAAY,8JACsI,CAAC;AAEhK,iFAAiF;AACjF,eAAO,MAAM,QAAQ,6nBAAmf,CAAC;AAEzgB,0CAA0C;AAC1C,eAAO,MAAM,SAAS,0DAA0D,CAAC;AAEjF,wCAAwC;AACxC,eAAO,MAAM,aAAa,8BAA8B,CAAC;AAEzD
|
|
1
|
+
{"version":3,"file":"recipes.d.ts","sourceRoot":"","sources":["../../src/lib/recipes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wDAAwD;AACxD,eAAO,MAAM,SAAS,2FAA2F,CAAC;AAElH,2CAA2C;AAC3C,eAAO,MAAM,WAAW,gHACyF,CAAC;AAElH,iGAAiG;AACjG,eAAO,MAAM,YAAY,qNAC6L,CAAC;AAEvN,iFAAiF;AACjF,eAAO,MAAM,YAAY,+GACuF,CAAC;AAEjH,oCAAoC;AACpC,eAAO,MAAM,WAAW,yWACkV,CAAC;AAE3W;;;;GAIG;AACH,eAAO,MAAM,YAAY,8JACsI,CAAC;AAEhK,iFAAiF;AACjF,eAAO,MAAM,QAAQ,6nBAAmf,CAAC;AAEzgB,0CAA0C;AAC1C,eAAO,MAAM,SAAS,0DAA0D,CAAC;AAEjF,wCAAwC;AACxC,eAAO,MAAM,aAAa,8BAA8B,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,QAAQ,sNACkM,CAAC;AAExN,4EAA4E;AAC5E,eAAO,MAAM,OAAO,4CAA4C,CAAC;AAEjE,iHAAiH;AACjH,eAAO,MAAM,eAAe,kCAAkC,CAAC;AAE/D,yGAAyG;AACzG,eAAO,MAAM,WAAW,gFAAgF,CAAC;AAEzG;;;;;GAKG;AACH,eAAO,MAAM,aAAa;;;CAMhB,CAAC;AAEX,eAAO,MAAM,oBAAoB,+DAA+D,CAAC"}
|
package/dist/lib/recipes.js
CHANGED
|
@@ -25,8 +25,12 @@ export const listItem = `${rowIndicator} data-highlighted:after:opacity-100 rela
|
|
|
25
25
|
export const listLabel = "px-2 py-1.5 text-xs font-medium text-muted-foreground";
|
|
26
26
|
/** Separator inside a popup or list. */
|
|
27
27
|
export const listSeparator = "-mx-1 my-1 h-px bg-border";
|
|
28
|
-
/**
|
|
29
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Modal backdrop for dialog, alert dialog, sheet, drawer. A transition on Base UI's starting/ending styles,
|
|
30
|
+
* not a keyframe: the backdrop stays mounted until the slower panel finishes, and a finished keyframe
|
|
31
|
+
* (no fill) snapped it back to full dim and blur for that wait, a flash on close.
|
|
32
|
+
*/
|
|
33
|
+
export const backdrop = "fixed inset-0 isolate z-50 bg-black/40 transition-opacity duration-150 ease-out motion-reduce:transition-none supports-backdrop-filter:backdrop-blur-xs data-starting-style:opacity-0 data-ending-style:opacity-0"; // lint-design-ignore: scrim is not a role
|
|
30
34
|
/** Title in cards, dialogs, sheets, popovers, empty states, alerts (§5). */
|
|
31
35
|
export const heading = "font-heading font-medium tracking-tight";
|
|
32
36
|
/** Empty track / placeholder: progress & meter tracks, skeletons, unlit segments. bg-muted vanishes on cards. */
|
package/dist/lib/recipes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recipes.js","sourceRoot":"","sources":["../../src/lib/recipes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wDAAwD;AACxD,MAAM,CAAC,MAAM,SAAS,GAAG,wFAAwF,CAAC;AAElH,2CAA2C;AAC3C,MAAM,CAAC,MAAM,WAAW,GACpB,6GAA6G,CAAC;AAElH,iGAAiG;AACjG,MAAM,CAAC,MAAM,YAAY,GACrB,kNAAkN,CAAC;AAEvN,iFAAiF;AACjF,MAAM,CAAC,MAAM,YAAY,GACrB,4GAA4G,CAAC;AAEjH,oCAAoC;AACpC,MAAM,CAAC,MAAM,WAAW,GACpB,sWAAsW,CAAC;AAE3W;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GACrB,2JAA2J,CAAC;AAEhK,iFAAiF;AACjF,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,YAAY,ieAAie,CAAC;AAEzgB,0CAA0C;AAC1C,MAAM,CAAC,MAAM,SAAS,GAAG,uDAAuD,CAAC;AAEjF,wCAAwC;AACxC,MAAM,CAAC,MAAM,aAAa,GAAG,2BAA2B,CAAC;AAEzD
|
|
1
|
+
{"version":3,"file":"recipes.js","sourceRoot":"","sources":["../../src/lib/recipes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wDAAwD;AACxD,MAAM,CAAC,MAAM,SAAS,GAAG,wFAAwF,CAAC;AAElH,2CAA2C;AAC3C,MAAM,CAAC,MAAM,WAAW,GACpB,6GAA6G,CAAC;AAElH,iGAAiG;AACjG,MAAM,CAAC,MAAM,YAAY,GACrB,kNAAkN,CAAC;AAEvN,iFAAiF;AACjF,MAAM,CAAC,MAAM,YAAY,GACrB,4GAA4G,CAAC;AAEjH,oCAAoC;AACpC,MAAM,CAAC,MAAM,WAAW,GACpB,sWAAsW,CAAC;AAE3W;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GACrB,2JAA2J,CAAC;AAEhK,iFAAiF;AACjF,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,YAAY,ieAAie,CAAC;AAEzgB,0CAA0C;AAC1C,MAAM,CAAC,MAAM,SAAS,GAAG,uDAAuD,CAAC;AAEjF,wCAAwC;AACxC,MAAM,CAAC,MAAM,aAAa,GAAG,2BAA2B,CAAC;AAEzD;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GACjB,mNAAmN,CAAC,CAAC,0CAA0C;AAEnQ,4EAA4E;AAC5E,MAAM,CAAC,MAAM,OAAO,GAAG,yCAAyC,CAAC;AAEjE,iHAAiH;AACjH,MAAM,CAAC,MAAM,eAAe,GAAG,+BAA+B,CAAC;AAE/D,yGAAyG;AACzG,MAAM,CAAC,MAAM,WAAW,GAAG,6EAA6E,CAAC;AAEzG;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IACzB,uGAAuG;IACvG,iGAAiG;IACjG,IAAI,EAAE,6EAA6E;IACnF,6DAA6D;IAC7D,OAAO,EAAE,6DAA6D;CAChE,CAAC;AAEX,MAAM,CAAC,MAAM,oBAAoB,GAAG,4DAA4D,CAAC"}
|
|
@@ -17,7 +17,10 @@ export interface SuiteHeaderProps {
|
|
|
17
17
|
nav: SuiteNavItem[];
|
|
18
18
|
/** Accessible name of the nav (default "Main"). */
|
|
19
19
|
navLabel?: string;
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* The search (DocsSearch, or the site's own built on SearchTrigger), before the separator. Below `md`
|
|
22
|
+
* it moves to the top of the phone menu: a full-width trigger there opens the same dialog.
|
|
23
|
+
*/
|
|
21
24
|
search?: React.ReactNode;
|
|
22
25
|
/** Replaces the default `<ThemeMenu />`. */
|
|
23
26
|
themeMenu?: React.ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suite-header.d.ts","sourceRoot":"","sources":["../../src/site/suite-header.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"suite-header.d.ts","sourceRoot":"","sources":["../../src/site/suite-header.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAKpC,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,kGAAkG;IAClG,MAAM,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6FAA6F;IAC7F,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC7B,4EAA4E;IAC5E,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,6FAA6F;IAC7F,IAAI,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC;IAC1B,GAAG,EAAE,YAAY,EAAE,CAAC;IACpB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,6CAA6C;IAC7C,UAAU,CAAC,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;KAAC,CAAC;IACpE,2EAA2E;IAC3E,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EACxB,KAAK,EACL,UAAU,EACV,IAAI,EACJ,GAAG,EACH,QAAiB,EACjB,MAAM,EACN,SAAS,EACT,UAAU,EACV,IAAI,EACJ,WAAW,GACd,EAAE,gBAAgB,qBAiElB"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Button } from "@repraze/kernelkit/components/button";
|
|
4
|
+
import { SearchRelay, SearchTrigger } from "@repraze/kernelkit/components/search-trigger";
|
|
4
5
|
import { Separator } from "@repraze/kernelkit/components/separator";
|
|
5
6
|
import { SiteHeader, SiteHeaderActions, SiteHeaderBrand, SiteHeaderContent, SiteHeaderMenu, SiteNav, SiteNavLink, } from "@repraze/kernelkit/components/site-header";
|
|
6
7
|
import { ThemeMenu } from "@repraze/kernelkit/components/theme-menu";
|
|
7
|
-
import { useEffect, useState } from "react";
|
|
8
|
+
import { useEffect, useRef, useState } from "react";
|
|
8
9
|
import { GithubIcon } from "./github-icon";
|
|
9
10
|
/**
|
|
10
11
|
* The suite's site header (GUIDELINES §7b): phone menu, brand, mono nav, then search · theme · repository.
|
|
@@ -13,7 +14,11 @@ import { GithubIcon } from "./github-icon";
|
|
|
13
14
|
export function SuiteHeader({ brand, brandLabel, home, nav, navLabel = "Main", search, themeMenu, repository, menu, locationKey, }) {
|
|
14
15
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
15
16
|
useEffect(() => setMenuOpen(false), [locationKey]);
|
|
17
|
+
const openSearch = useRef(null);
|
|
16
18
|
const navLinks = nav.map((item) => (_jsx(SiteNavLink, { href: item.href, "aria-current": item.current ? "page" : undefined, render: item.render, children: item.label }, item.label)));
|
|
17
|
-
return (_jsx(SiteHeader, { children: _jsxs(SiteHeaderContent, { children: [_jsxs(SiteHeaderMenu, { title: brand, open: menuOpen, onOpenChange: setMenuOpen, children: [_jsx("
|
|
19
|
+
return (_jsx(SiteHeader, { children: _jsxs(SiteHeaderContent, { children: [_jsxs(SiteHeaderMenu, { title: brand, open: menuOpen, onOpenChange: setMenuOpen, children: [search ? (_jsx("div", { className: "px-2 pt-2", children: _jsx(SearchTrigger, { expanded: true, "aria-label": "Search", onClick: (event) => {
|
|
20
|
+
setMenuOpen(false);
|
|
21
|
+
openSearch.current?.(event);
|
|
22
|
+
} }) })) : null, _jsx("nav", { "aria-label": navLabel, className: "flex flex-col gap-1 px-2 pt-2", children: navLinks }), menu] }), _jsx(SiteHeaderBrand, { "aria-label": brandLabel, href: home ? undefined : "/", render: home, children: brand }), _jsx(SiteNav, { "aria-label": navLabel, children: navLinks }), _jsxs(SiteHeaderActions, { children: [search ? (_jsx(SearchRelay, { handler: openSearch, children: _jsx("div", { className: "hidden md:contents", children: search }) })) : null, _jsx(Separator, { orientation: "vertical", className: "mx-1 hidden data-vertical:h-5 data-vertical:self-center md:block" }), themeMenu ?? _jsx(ThemeMenu, {}), repository ? (_jsx(Button, { variant: "ghost", size: "icon", render: _jsx("a", { href: repository.href, "aria-label": repository.label ?? "GitHub" }), children: repository.icon ?? _jsx(GithubIcon, { className: "size-4" }) })) : null] })] }) }));
|
|
18
23
|
}
|
|
19
24
|
//# sourceMappingURL=suite-header.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suite-header.js","sourceRoot":"","sources":["../../src/site/suite-header.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAC,MAAM,EAAC,MAAM,sCAAsC,CAAC;AAC5D,OAAO,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAClE,OAAO,EACH,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,OAAO,EACP,WAAW,GACd,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAC,SAAS,EAAC,MAAM,0CAA0C,CAAC;AAEnE,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"suite-header.js","sourceRoot":"","sources":["../../src/site/suite-header.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/components/pager.tsx
CHANGED
|
@@ -7,14 +7,14 @@ import {cn} from "cn";
|
|
|
7
7
|
import {ArrowLeftIcon, ArrowRightIcon} from "lucide-react";
|
|
8
8
|
import type * as React from "react";
|
|
9
9
|
|
|
10
|
-
/** Previous / next page links at the end of a page
|
|
10
|
+
/** Previous / next page links at the end of a page: stacked on phones, side by side from `sm`. */
|
|
11
11
|
function Pager({className, render, ...props}: useRender.ComponentProps<"nav">) {
|
|
12
12
|
return useRender({
|
|
13
13
|
defaultTagName: "nav",
|
|
14
14
|
props: mergeProps<"nav">(
|
|
15
15
|
{
|
|
16
16
|
"aria-label": "Pages",
|
|
17
|
-
className: cn("grid
|
|
17
|
+
className: cn("grid gap-3 border-t border-border pt-6 sm:grid-cols-2 sm:gap-4", className),
|
|
18
18
|
},
|
|
19
19
|
props,
|
|
20
20
|
),
|
|
@@ -39,21 +39,21 @@ function PagerLink({className, render, direction, label, children, ...props}: Pa
|
|
|
39
39
|
{
|
|
40
40
|
rel: next ? "next" : "prev",
|
|
41
41
|
className: cn(
|
|
42
|
-
"group/pager flex flex-col gap-1 rounded-lg border border-border px-4 py-3 transition-colors hover:border-primary-text hover:bg-hover",
|
|
42
|
+
"group/pager flex min-w-0 flex-col gap-1 rounded-lg border border-border px-4 py-3 transition-colors hover:border-primary-text hover:bg-hover",
|
|
43
43
|
focusRing,
|
|
44
|
-
next ? "
|
|
44
|
+
next ? "items-end text-end sm:col-start-2" : "items-start sm:col-start-1",
|
|
45
45
|
className,
|
|
46
46
|
),
|
|
47
47
|
children: (
|
|
48
48
|
<>
|
|
49
49
|
<span className="text-xs text-muted-foreground">{label ?? (next ? "Next" : "Previous")}</span>
|
|
50
|
-
<span className="flex items-center gap-1.5 font-medium">
|
|
50
|
+
<span className="flex max-w-full items-center gap-1.5 font-medium">
|
|
51
51
|
{!next && (
|
|
52
|
-
<Arrow className="size-4 transition-transform group-hover/pager:-translate-x-0.5" />
|
|
52
|
+
<Arrow className="size-4 shrink-0 transition-transform group-hover/pager:-translate-x-0.5" />
|
|
53
53
|
)}
|
|
54
|
-
{children}
|
|
54
|
+
<span className="min-w-0 wrap-break-word">{children}</span>
|
|
55
55
|
{next && (
|
|
56
|
-
<Arrow className="size-4 transition-transform group-hover/pager:translate-x-0.5" />
|
|
56
|
+
<Arrow className="size-4 shrink-0 transition-transform group-hover/pager:translate-x-0.5" />
|
|
57
57
|
)}
|
|
58
58
|
</span>
|
|
59
59
|
</>
|
|
@@ -49,31 +49,58 @@ function useSearchHotkeys(onOpen: (toggle: boolean) => void, {enabled = true}: {
|
|
|
49
49
|
interface SearchTriggerProps extends React.ComponentProps<typeof Button> {
|
|
50
50
|
/** Placeholder text. */
|
|
51
51
|
children?: React.ReactNode;
|
|
52
|
+
/** Full width with its placeholder at every size (a phone menu); otherwise an icon below `sm`. */
|
|
53
|
+
expanded?: boolean;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
type SearchHandler = React.MouseEventHandler<HTMLButtonElement>;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Lets a shell open the page's search from another place (SuiteHeader's phone menu) without a second
|
|
60
|
+
* dialog: a SearchTrigger inside `SearchRelay` hands its `onClick` to the relay's ref.
|
|
61
|
+
*/
|
|
62
|
+
const SearchRelayContext = React.createContext<React.RefObject<SearchHandler | null> | null>(null);
|
|
63
|
+
|
|
64
|
+
function SearchRelay({handler, children}: {handler: React.RefObject<SearchHandler | null>; children: React.ReactNode}) {
|
|
65
|
+
return <SearchRelayContext.Provider value={handler}>{children}</SearchRelayContext.Provider>;
|
|
52
66
|
}
|
|
53
67
|
|
|
54
68
|
/**
|
|
55
69
|
* Header search button: icon, placeholder, OS-aware shortcut. Same 32px height as the header's icon buttons. Open your dialog in `onClick`.
|
|
56
70
|
* The keycap gets the same inset on the right as top/bottom (32 - 20 = 6px each side, border included).
|
|
57
71
|
*/
|
|
58
|
-
function SearchTrigger({children = "Search…", className, ...props}: SearchTriggerProps) {
|
|
72
|
+
function SearchTrigger({children = "Search…", expanded = false, className, onClick, ...props}: SearchTriggerProps) {
|
|
59
73
|
const mod = useModKey();
|
|
74
|
+
const relay = React.useContext(SearchRelayContext);
|
|
75
|
+
React.useEffect(() => {
|
|
76
|
+
if (!relay) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
relay.current = onClick ?? null;
|
|
80
|
+
return () => {
|
|
81
|
+
relay.current = null;
|
|
82
|
+
};
|
|
83
|
+
}, [relay, onClick]);
|
|
60
84
|
return (
|
|
61
85
|
<Button
|
|
62
86
|
variant="outline"
|
|
63
87
|
aria-label="Search"
|
|
64
88
|
data-slot="search-trigger"
|
|
89
|
+
data-expanded={expanded || undefined}
|
|
65
90
|
className={cn(
|
|
66
|
-
"
|
|
91
|
+
"justify-start text-muted-foreground",
|
|
92
|
+
expanded ? "w-full pr-1.25 pl-2.5" : "w-8 px-0 sm:w-40 sm:pr-1.25 sm:pl-2.5 lg:w-56",
|
|
67
93
|
className,
|
|
68
94
|
)}
|
|
95
|
+
onClick={onClick}
|
|
69
96
|
{...props}
|
|
70
97
|
>
|
|
71
|
-
<SearchIcon data-icon="inline-start" className="mx-auto sm:mx-0" />
|
|
72
|
-
<span className="
|
|
98
|
+
<SearchIcon data-icon="inline-start" className={expanded ? undefined : "mx-auto sm:mx-0"} />
|
|
99
|
+
<span className={cn("flex-1 truncate text-start", !expanded && "hidden sm:inline")}>{children}</span>
|
|
73
100
|
<Kbd className="hidden sm:inline-flex">{mod} K</Kbd>
|
|
74
101
|
</Button>
|
|
75
102
|
);
|
|
76
103
|
}
|
|
77
104
|
|
|
78
|
-
export {SearchTrigger, useModKey, useSearchHotkeys};
|
|
79
|
-
export type {SearchTriggerProps};
|
|
105
|
+
export {SearchRelay, SearchTrigger, useModKey, useSearchHotkeys};
|
|
106
|
+
export type {SearchHandler, SearchTriggerProps};
|
package/src/lib/recipes.ts
CHANGED
|
@@ -40,9 +40,13 @@ export const listLabel = "px-2 py-1.5 text-xs font-medium text-muted-foreground"
|
|
|
40
40
|
/** Separator inside a popup or list. */
|
|
41
41
|
export const listSeparator = "-mx-1 my-1 h-px bg-border";
|
|
42
42
|
|
|
43
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Modal backdrop for dialog, alert dialog, sheet, drawer. A transition on Base UI's starting/ending styles,
|
|
45
|
+
* not a keyframe: the backdrop stays mounted until the slower panel finishes, and a finished keyframe
|
|
46
|
+
* (no fill) snapped it back to full dim and blur for that wait, a flash on close.
|
|
47
|
+
*/
|
|
44
48
|
export const backdrop =
|
|
45
|
-
"fixed inset-0 isolate z-50 bg-black/40 duration-
|
|
49
|
+
"fixed inset-0 isolate z-50 bg-black/40 transition-opacity duration-150 ease-out motion-reduce:transition-none supports-backdrop-filter:backdrop-blur-xs data-starting-style:opacity-0 data-ending-style:opacity-0"; // lint-design-ignore: scrim is not a role
|
|
46
50
|
|
|
47
51
|
/** Title in cards, dialogs, sheets, popovers, empty states, alerts (§5). */
|
|
48
52
|
export const heading = "font-heading font-medium tracking-tight";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import {Button} from "@repraze/kernelkit/components/button";
|
|
4
|
+
import {type SearchHandler, SearchRelay, SearchTrigger} from "@repraze/kernelkit/components/search-trigger";
|
|
4
5
|
import {Separator} from "@repraze/kernelkit/components/separator";
|
|
5
6
|
import {
|
|
6
7
|
SiteHeader,
|
|
@@ -13,7 +14,7 @@ import {
|
|
|
13
14
|
} from "@repraze/kernelkit/components/site-header";
|
|
14
15
|
import {ThemeMenu} from "@repraze/kernelkit/components/theme-menu";
|
|
15
16
|
import type * as React from "react";
|
|
16
|
-
import {useEffect, useState} from "react";
|
|
17
|
+
import {useEffect, useRef, useState} from "react";
|
|
17
18
|
|
|
18
19
|
import {GithubIcon} from "./github-icon";
|
|
19
20
|
|
|
@@ -36,7 +37,10 @@ export interface SuiteHeaderProps {
|
|
|
36
37
|
nav: SuiteNavItem[];
|
|
37
38
|
/** Accessible name of the nav (default "Main"). */
|
|
38
39
|
navLabel?: string;
|
|
39
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* The search (DocsSearch, or the site's own built on SearchTrigger), before the separator. Below `md`
|
|
42
|
+
* it moves to the top of the phone menu: a full-width trigger there opens the same dialog.
|
|
43
|
+
*/
|
|
40
44
|
search?: React.ReactNode;
|
|
41
45
|
/** Replaces the default `<ThemeMenu />`. */
|
|
42
46
|
themeMenu?: React.ReactNode;
|
|
@@ -66,6 +70,7 @@ export function SuiteHeader({
|
|
|
66
70
|
}: SuiteHeaderProps) {
|
|
67
71
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
68
72
|
useEffect(() => setMenuOpen(false), [locationKey]);
|
|
73
|
+
const openSearch = useRef<SearchHandler | null>(null);
|
|
69
74
|
|
|
70
75
|
const navLinks = nav.map((item) => (
|
|
71
76
|
<SiteNavLink
|
|
@@ -82,6 +87,18 @@ export function SuiteHeader({
|
|
|
82
87
|
<SiteHeader>
|
|
83
88
|
<SiteHeaderContent>
|
|
84
89
|
<SiteHeaderMenu title={brand} open={menuOpen} onOpenChange={setMenuOpen}>
|
|
90
|
+
{search ? (
|
|
91
|
+
<div className="px-2 pt-2">
|
|
92
|
+
<SearchTrigger
|
|
93
|
+
expanded
|
|
94
|
+
aria-label="Search"
|
|
95
|
+
onClick={(event) => {
|
|
96
|
+
setMenuOpen(false);
|
|
97
|
+
openSearch.current?.(event);
|
|
98
|
+
}}
|
|
99
|
+
/>
|
|
100
|
+
</div>
|
|
101
|
+
) : null}
|
|
85
102
|
<nav aria-label={navLabel} className="flex flex-col gap-1 px-2 pt-2">
|
|
86
103
|
{navLinks}
|
|
87
104
|
</nav>
|
|
@@ -92,10 +109,14 @@ export function SuiteHeader({
|
|
|
92
109
|
</SiteHeaderBrand>
|
|
93
110
|
<SiteNav aria-label={navLabel}>{navLinks}</SiteNav>
|
|
94
111
|
<SiteHeaderActions>
|
|
95
|
-
{search
|
|
112
|
+
{search ? (
|
|
113
|
+
<SearchRelay handler={openSearch}>
|
|
114
|
+
<div className="hidden md:contents">{search}</div>
|
|
115
|
+
</SearchRelay>
|
|
116
|
+
) : null}
|
|
96
117
|
<Separator
|
|
97
118
|
orientation="vertical"
|
|
98
|
-
className="mx-1 hidden data-vertical:h-5 data-vertical:self-center
|
|
119
|
+
className="mx-1 hidden data-vertical:h-5 data-vertical:self-center md:block"
|
|
99
120
|
/>
|
|
100
121
|
{themeMenu ?? <ThemeMenu />}
|
|
101
122
|
{repository ? (
|