@scouterna/ui-react 0.1.4 → 0.2.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/components/app-waffle/app-waffle.d.ts +10 -0
- package/dist/components/app-waffle/app-waffle.js +37 -0
- package/dist/components/app-waffle/app-waffle.js.map +1 -0
- package/dist/components/app-waffle/usher.d.ts +14 -0
- package/dist/components/app-waffle/usher.js +39 -0
- package/dist/components/app-waffle/usher.js.map +1 -0
- package/dist/components/button/button.d.ts +1 -1
- package/dist/components/button/button.js +2 -0
- package/dist/components/button/button.js.map +1 -1
- package/dist/lib/preload.d.ts +5 -0
- package/dist/lib/preload.js +19 -0
- package/dist/lib/preload.js.map +1 -0
- package/dist/style.css +128 -0
- package/package.json +6 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Popover } from "@base-ui-components/react/popover";
|
|
2
|
+
import type { ComponentProps } from "react";
|
|
3
|
+
type RenderProp = ComponentProps<typeof Popover.Trigger>["render"];
|
|
4
|
+
type Props = {
|
|
5
|
+
children?: RenderProp;
|
|
6
|
+
referrer: string;
|
|
7
|
+
usherUrl: string;
|
|
8
|
+
};
|
|
9
|
+
declare function AppWaffle({ children, referrer, usherUrl }: Props): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export { AppWaffle };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Popover } from "@base-ui-components/react/popover";
|
|
3
|
+
import { LayoutGridIcon } from "lucide-react";
|
|
4
|
+
import { usePreloadImages } from "../../lib/preload.js";
|
|
5
|
+
import { Button } from "../button/button.js";
|
|
6
|
+
import { useClients } from "./usher.js";
|
|
7
|
+
const FALLBACK_LOGO_URL = "https://cdn.scouterna.net/jamboree26/images/app-placeholder.png";
|
|
8
|
+
function AppWaffle({ children, referrer, usherUrl }) {
|
|
9
|
+
const { clients, error } = useClients({ usherUrl });
|
|
10
|
+
const imageUrls = clients.map((client) => client.logoUrl ?? FALLBACK_LOGO_URL);
|
|
11
|
+
usePreloadImages(imageUrls);
|
|
12
|
+
const clientsWithReferrer = clients.map((client) => {
|
|
13
|
+
const url = new URL(client.url);
|
|
14
|
+
url.searchParams.set("referrer", referrer);
|
|
15
|
+
return {
|
|
16
|
+
...client,
|
|
17
|
+
url: url.toString(),
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
children = children ?? (_jsx(Button, { size: "medium-icon", variant: "text", "aria-label": "Change app", children: _jsx(LayoutGridIcon, {}) }));
|
|
21
|
+
return (_jsxs(Popover.Root, { children: [_jsx(Popover.Trigger, { render: children }), _jsx(Popover.Portal, { children: _jsx(Popover.Positioner, { sideOffset: 8, children: _jsxs(Popover.Popup, { className: "origin-[var(--transform-origin)] rounded-lg bg-[canvas] p-4 text-gray-900 shadow outline outline-gray-200 transition-[transform,scale,opacity] data-[ending-style]:scale-90 data-[ending-style]:opacity-0 data-[starting-style]:scale-90 data-[starting-style]:opacity-0", children: [_jsx(Popover.Arrow, { className: "data-[side=bottom]:top-[-8px] data-[side=left]:right-[-13px] data-[side=left]:rotate-90 data-[side=right]:left-[-13px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180", children: _jsx(ArrowSvg, {}) }), error ? (_jsx("div", { children: "Something went wrong while loading your apps." })) : (_jsx("div", { className: "grid grid-cols-3 gap-2 grid-flow-row-dense", children: clientsWithReferrer.map((client) => (_jsx("a", { href: client.url, target: "_blank", rel: "noopener noreferrer", className: "relative size-20", children: _jsxs("div", { className: `
|
|
22
|
+
group/app-card
|
|
23
|
+
absolute w-full h-full min-h-full rounded-lg pt-3 pb-1 px-1 flex flex-col items-center
|
|
24
|
+
hover:h-auto hover:bg-gray-100/80
|
|
25
|
+
select-none
|
|
26
|
+
`, children: [_jsx("img", { src: client.logoUrl ?? FALLBACK_LOGO_URL, alt: client.name, className: "size-9 aspect-square object-cover rounded-sm" }), _jsx("span", { className: `
|
|
27
|
+
text-sm text-center mt-1 overflow-ellipsis line-clamp-1
|
|
28
|
+
group-hover/app-card:line-clamp-none
|
|
29
|
+
`, children: client.name })] }) }, client.id))) }))] }) }) })] }));
|
|
30
|
+
}
|
|
31
|
+
function ArrowSvg(props) {
|
|
32
|
+
return (
|
|
33
|
+
// biome-ignore lint/a11y/noSvgWithoutTitle: This is only for display
|
|
34
|
+
_jsxs("svg", { width: "20", height: "10", viewBox: "0 0 20 10", fill: "none", ...props, "aria-hidden": true, children: [_jsx("path", { d: "M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z", className: "fill-[canvas]" }), _jsx("path", { d: "M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z", className: "fill-gray-200" })] }));
|
|
35
|
+
}
|
|
36
|
+
export { AppWaffle };
|
|
37
|
+
//# sourceMappingURL=app-waffle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-waffle.js","sourceRoot":"","sources":["../../../src/components/app-waffle/app-waffle.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type UseClientsOptions = {
|
|
2
|
+
usherUrl: string;
|
|
3
|
+
};
|
|
4
|
+
export type Client = {
|
|
5
|
+
id: string;
|
|
6
|
+
url: string;
|
|
7
|
+
name: string;
|
|
8
|
+
alwaysShow: boolean;
|
|
9
|
+
logoUrl: string | null;
|
|
10
|
+
};
|
|
11
|
+
export declare const useClients: ({ usherUrl }: UseClientsOptions) => {
|
|
12
|
+
clients: Client[];
|
|
13
|
+
error: string | null;
|
|
14
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState } from "react";
|
|
2
|
+
// Creates a temporary iframe, waits for a postMessage from it and sets a state variable to the received data
|
|
3
|
+
export const useClients = ({ usherUrl }) => {
|
|
4
|
+
const [clients, setClients] = useState([]);
|
|
5
|
+
const [error, setError] = useState(null);
|
|
6
|
+
const embedUrl = useMemo(() => new URL("/embed", usherUrl), [usherUrl]);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
const iframe = document.createElement("iframe");
|
|
9
|
+
iframe.src = embedUrl.toString();
|
|
10
|
+
iframe.style.display = "none";
|
|
11
|
+
document.body.appendChild(iframe);
|
|
12
|
+
const handleMessage = (event) => {
|
|
13
|
+
if (event.origin !== embedUrl.origin)
|
|
14
|
+
return;
|
|
15
|
+
if (!("type" in event.data))
|
|
16
|
+
return;
|
|
17
|
+
if (!event.data.type.startsWith("usher-"))
|
|
18
|
+
return;
|
|
19
|
+
iframe.remove();
|
|
20
|
+
if (event.data.type === "usher-clients") {
|
|
21
|
+
setClients(event.data.data);
|
|
22
|
+
}
|
|
23
|
+
else if (event.data.type === "usher-error") {
|
|
24
|
+
console.error("Received error from Usher iframe:", event.data.error);
|
|
25
|
+
setError(event.data.error);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.log("Received unknown message type:", event.data.type);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
window.addEventListener("message", handleMessage);
|
|
32
|
+
return () => {
|
|
33
|
+
window.removeEventListener("message", handleMessage);
|
|
34
|
+
iframe.remove();
|
|
35
|
+
};
|
|
36
|
+
}, [embedUrl]);
|
|
37
|
+
return { clients, error };
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=usher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usher.js","sourceRoot":"","sources":["../../../src/components/app-waffle/usher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAcrD,6GAA6G;AAC7G,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EAAE,QAAQ,EAAqB,EAAE,EAAE;IAC5D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IACrD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAExE,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAElC,MAAM,aAAa,GAAG,CAAC,KAAmB,EAAE,EAAE;YAC5C,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM;gBAAE,OAAO;YAC7C,IAAI,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC;gBAAE,OAAO;YACpC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,OAAO;YAElD,MAAM,CAAC,MAAM,EAAE,CAAC;YAEhB,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;gBACxC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBAC7C,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACrE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,gCAAgC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjE,CAAC;QACH,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAClD,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;YACrD,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { type VariantProps } from "class-variance-authority";
|
|
|
3
3
|
declare const buttonVariants: (props?: ({
|
|
4
4
|
color?: "gray" | "blue" | "orange" | "red" | "trackergreen" | "discovererblue" | "adventurerorange" | "challengerpink" | "roveryellow" | null | undefined;
|
|
5
5
|
variant?: "contained" | "text" | "outlined" | null | undefined;
|
|
6
|
-
size?: "medium" | "small" | "tiny-icon" | null | undefined;
|
|
6
|
+
size?: "medium" | "small" | "medium-icon" | "small-icon" | "tiny-icon" | null | undefined;
|
|
7
7
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
8
8
|
export type ButtonProps = Omit<useRender.ComponentProps<"button">, "color"> & VariantProps<typeof buttonVariants>;
|
|
9
9
|
declare const Button: (props: ButtonProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
@@ -129,6 +129,8 @@ const buttonVariants = cva(`
|
|
|
129
129
|
size: {
|
|
130
130
|
medium: "text-base px-4 h-10 rounded-lg",
|
|
131
131
|
small: "text-sm px-3 h-8 rounded-md",
|
|
132
|
+
"medium-icon": "text-base size-10 rounded-lg",
|
|
133
|
+
"small-icon": "text-sm size-8 rounded-md",
|
|
132
134
|
"tiny-icon": "text-sm p-1 size-6 rounded-md",
|
|
133
135
|
},
|
|
134
136
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../../src/components/button/button.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,GAAG,EAAqB,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAExC,MAAM,cAAc,GAAG,GAAG,CACxB;;;;;;;GAOC,EACD;IACE,QAAQ,EAAE;QACR,KAAK,EAAE;YACL,IAAI,EAAE;;;;;;;;;SASL;YACD,IAAI,EAAE;;;;;;;;;SASL;YACD,MAAM,EAAE;;;;;;;;;SASP;YACD,GAAG,EAAE;;;;;;;;;SASJ;YACD,YAAY,EAAE;;;;;;;;;SASb;YACD,cAAc,EAAE;;;;;;;;;SASf;YACD,gBAAgB,EAAE;;;;;;;;;SASjB;YACD,cAAc,EAAE;;;;;;;;;SASf;YACD,WAAW,EAAE;;;;;;;;;SASZ;SACF;QACD,OAAO,EAAE;YACP,SAAS,EAAE;;;;;;SAMV;YACD,IAAI,EAAE;;;;;;SAML;YACD,QAAQ,EAAE;;;;;;SAMT;SACF;QACD,IAAI,EAAE;YACJ,MAAM,EAAE,gCAAgC;YACxC,KAAK,EAAE,6BAA6B;YACpC,WAAW,EAAE,+BAA+B;SAC7C;KACF;IACD,eAAe,EAAE;QACf,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,WAAW;QACpB,IAAI,EAAE,QAAQ;KACf;IACD,gBAAgB,EAAE;QAChB;YACE,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,MAAM;YACf,KAAK,EAAE;;SAEN;SACF;QACD;YACE,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,UAAU;YACnB,KAAK,EAAE;;SAEN;SACF;KACF;CACF,CACF,CAAC;AAKF,MAAM,MAAM,GAAG,CAAC,KAAkB,EAAE,EAAE;IACpC,MAAM;IACJ,+DAA+D;IAC/D,MAAM,GAAG,kBAAU,EACnB,SAAS,EACT,KAAK,EACL,OAAO,EACP,IAAI,EACJ,GAAG,UAAU,EACd,GAAG,KAAK,CAAC;IAEV,MAAM,YAAY,GAAqC;QACrD,SAAS,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAClE,IAAI,EAAE,QAAQ;KACf,CAAC;IAEF,OAAO,SAAS,CAAC;QACf,MAAM;QACN,KAAK,EAAE,UAAU,CAAC,YAAY,EAAE,UAAU,CAAC;KAC5C,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../../src/components/button/button.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,GAAG,EAAqB,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAExC,MAAM,cAAc,GAAG,GAAG,CACxB;;;;;;;GAOC,EACD;IACE,QAAQ,EAAE;QACR,KAAK,EAAE;YACL,IAAI,EAAE;;;;;;;;;SASL;YACD,IAAI,EAAE;;;;;;;;;SASL;YACD,MAAM,EAAE;;;;;;;;;SASP;YACD,GAAG,EAAE;;;;;;;;;SASJ;YACD,YAAY,EAAE;;;;;;;;;SASb;YACD,cAAc,EAAE;;;;;;;;;SASf;YACD,gBAAgB,EAAE;;;;;;;;;SASjB;YACD,cAAc,EAAE;;;;;;;;;SASf;YACD,WAAW,EAAE;;;;;;;;;SASZ;SACF;QACD,OAAO,EAAE;YACP,SAAS,EAAE;;;;;;SAMV;YACD,IAAI,EAAE;;;;;;SAML;YACD,QAAQ,EAAE;;;;;;SAMT;SACF;QACD,IAAI,EAAE;YACJ,MAAM,EAAE,gCAAgC;YACxC,KAAK,EAAE,6BAA6B;YACpC,aAAa,EAAE,8BAA8B;YAC7C,YAAY,EAAE,2BAA2B;YACzC,WAAW,EAAE,+BAA+B;SAC7C;KACF;IACD,eAAe,EAAE;QACf,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,WAAW;QACpB,IAAI,EAAE,QAAQ;KACf;IACD,gBAAgB,EAAE;QAChB;YACE,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,MAAM;YACf,KAAK,EAAE;;SAEN;SACF;QACD;YACE,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,UAAU;YACnB,KAAK,EAAE;;SAEN;SACF;KACF;CACF,CACF,CAAC;AAKF,MAAM,MAAM,GAAG,CAAC,KAAkB,EAAE,EAAE;IACpC,MAAM;IACJ,+DAA+D;IAC/D,MAAM,GAAG,kBAAU,EACnB,SAAS,EACT,KAAK,EACL,OAAO,EACP,IAAI,EACJ,GAAG,UAAU,EACd,GAAG,KAAK,CAAC;IAEV,MAAM,YAAY,GAAqC;QACrD,SAAS,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAClE,IAAI,EAAE,QAAQ;KACf,CAAC;IAEF,OAAO,SAAS,CAAC;QACf,MAAM;QACN,KAAK,EAAE,UAAU,CAAC,YAAY,EAAE,UAAU,CAAC;KAC5C,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
export function usePreloadImages(hrefs) {
|
|
3
|
+
const isBrowser = typeof window !== "undefined";
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
if (!isBrowser)
|
|
6
|
+
return;
|
|
7
|
+
const uniqueHrefs = Array.from(new Set(hrefs));
|
|
8
|
+
import("react-dom")
|
|
9
|
+
.then(({ preload }) => {
|
|
10
|
+
for (const href of uniqueHrefs) {
|
|
11
|
+
preload(href, {
|
|
12
|
+
as: "image",
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
.catch((err) => console.warn("Couldn't import react-dom:", err));
|
|
17
|
+
}, [isBrowser, hrefs]);
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=preload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preload.js","sourceRoot":"","sources":["../../src/lib/preload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOlC,MAAM,UAAU,gBAAgB,CAAC,KAAe;IAC9C,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;IAEhD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAE/C,MAAM,CAAC,WAAW,CAAC;aAChB,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YACpB,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;gBAC/B,OAAO,CAAC,IAAI,EAAE;oBACZ,EAAE,EAAE,OAAO;iBACZ,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC,CAAC;IACrE,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;AACzB,CAAC"}
|
package/dist/style.css
CHANGED
|
@@ -144,6 +144,12 @@
|
|
|
144
144
|
.ml-5 {
|
|
145
145
|
margin-left: calc(var(--spacing) * 5);
|
|
146
146
|
}
|
|
147
|
+
.line-clamp-1 {
|
|
148
|
+
overflow: hidden;
|
|
149
|
+
display: -webkit-box;
|
|
150
|
+
-webkit-box-orient: vertical;
|
|
151
|
+
-webkit-line-clamp: 1;
|
|
152
|
+
}
|
|
147
153
|
.flex {
|
|
148
154
|
display: flex;
|
|
149
155
|
}
|
|
@@ -162,6 +168,9 @@
|
|
|
162
168
|
.table {
|
|
163
169
|
display: table;
|
|
164
170
|
}
|
|
171
|
+
.aspect-square {
|
|
172
|
+
aspect-ratio: 1 / 1;
|
|
173
|
+
}
|
|
165
174
|
.size-4 {
|
|
166
175
|
width: calc(var(--spacing) * 4);
|
|
167
176
|
height: calc(var(--spacing) * 4);
|
|
@@ -174,6 +183,22 @@
|
|
|
174
183
|
width: calc(var(--spacing) * 6);
|
|
175
184
|
height: calc(var(--spacing) * 6);
|
|
176
185
|
}
|
|
186
|
+
.size-8 {
|
|
187
|
+
width: calc(var(--spacing) * 8);
|
|
188
|
+
height: calc(var(--spacing) * 8);
|
|
189
|
+
}
|
|
190
|
+
.size-9 {
|
|
191
|
+
width: calc(var(--spacing) * 9);
|
|
192
|
+
height: calc(var(--spacing) * 9);
|
|
193
|
+
}
|
|
194
|
+
.size-10 {
|
|
195
|
+
width: calc(var(--spacing) * 10);
|
|
196
|
+
height: calc(var(--spacing) * 10);
|
|
197
|
+
}
|
|
198
|
+
.size-20 {
|
|
199
|
+
width: calc(var(--spacing) * 20);
|
|
200
|
+
height: calc(var(--spacing) * 20);
|
|
201
|
+
}
|
|
177
202
|
.h-6 {
|
|
178
203
|
height: calc(var(--spacing) * 6);
|
|
179
204
|
}
|
|
@@ -195,6 +220,9 @@
|
|
|
195
220
|
.min-h-48 {
|
|
196
221
|
min-height: calc(var(--spacing) * 48);
|
|
197
222
|
}
|
|
223
|
+
.min-h-full {
|
|
224
|
+
min-height: 100%;
|
|
225
|
+
}
|
|
198
226
|
.w-2 {
|
|
199
227
|
width: calc(var(--spacing) * 2);
|
|
200
228
|
}
|
|
@@ -243,9 +271,18 @@
|
|
|
243
271
|
.appearance-none {
|
|
244
272
|
appearance: none;
|
|
245
273
|
}
|
|
274
|
+
.grid-flow-row-dense {
|
|
275
|
+
grid-auto-flow: row dense;
|
|
276
|
+
}
|
|
277
|
+
.grid-cols-3 {
|
|
278
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
279
|
+
}
|
|
246
280
|
.grid-cols-\[1rem_auto_1rem\] {
|
|
247
281
|
grid-template-columns: 1rem auto 1rem;
|
|
248
282
|
}
|
|
283
|
+
.flex-col {
|
|
284
|
+
flex-direction: column;
|
|
285
|
+
}
|
|
249
286
|
.items-center {
|
|
250
287
|
align-items: center;
|
|
251
288
|
}
|
|
@@ -323,6 +360,9 @@
|
|
|
323
360
|
.bg-\(--btn-bg\) {
|
|
324
361
|
background-color: var(--btn-bg);
|
|
325
362
|
}
|
|
363
|
+
.bg-\[canvas\] {
|
|
364
|
+
background-color: canvas;
|
|
365
|
+
}
|
|
326
366
|
.bg-blue-100 {
|
|
327
367
|
background-color: var(--color-blue-100);
|
|
328
368
|
}
|
|
@@ -350,12 +390,21 @@
|
|
|
350
390
|
.bg-transparent {
|
|
351
391
|
background-color: transparent;
|
|
352
392
|
}
|
|
393
|
+
.fill-\[canvas\] {
|
|
394
|
+
fill: canvas;
|
|
395
|
+
}
|
|
353
396
|
.fill-gray-100 {
|
|
354
397
|
fill: var(--color-gray-100);
|
|
355
398
|
}
|
|
399
|
+
.fill-gray-200 {
|
|
400
|
+
fill: var(--color-gray-200);
|
|
401
|
+
}
|
|
356
402
|
.fill-gray-300 {
|
|
357
403
|
fill: var(--color-gray-300);
|
|
358
404
|
}
|
|
405
|
+
.object-cover {
|
|
406
|
+
object-fit: cover;
|
|
407
|
+
}
|
|
359
408
|
.p-0 {
|
|
360
409
|
padding: calc(var(--spacing) * 0);
|
|
361
410
|
}
|
|
@@ -377,6 +426,9 @@
|
|
|
377
426
|
.p-40 {
|
|
378
427
|
padding: calc(var(--spacing) * 40);
|
|
379
428
|
}
|
|
429
|
+
.px-1 {
|
|
430
|
+
padding-inline: calc(var(--spacing) * 1);
|
|
431
|
+
}
|
|
380
432
|
.px-2 {
|
|
381
433
|
padding-inline: calc(var(--spacing) * 2);
|
|
382
434
|
}
|
|
@@ -401,18 +453,27 @@
|
|
|
401
453
|
.py-3 {
|
|
402
454
|
padding-block: calc(var(--spacing) * 3);
|
|
403
455
|
}
|
|
456
|
+
.pt-3 {
|
|
457
|
+
padding-top: calc(var(--spacing) * 3);
|
|
458
|
+
}
|
|
404
459
|
.pr-1 {
|
|
405
460
|
padding-right: calc(var(--spacing) * 1);
|
|
406
461
|
}
|
|
407
462
|
.pr-\[35px\] {
|
|
408
463
|
padding-right: 35px;
|
|
409
464
|
}
|
|
465
|
+
.pb-1 {
|
|
466
|
+
padding-bottom: calc(var(--spacing) * 1);
|
|
467
|
+
}
|
|
410
468
|
.pl-2 {
|
|
411
469
|
padding-left: calc(var(--spacing) * 2);
|
|
412
470
|
}
|
|
413
471
|
.pl-\[25px\] {
|
|
414
472
|
padding-left: 25px;
|
|
415
473
|
}
|
|
474
|
+
.text-center {
|
|
475
|
+
text-align: center;
|
|
476
|
+
}
|
|
416
477
|
.text-left {
|
|
417
478
|
text-align: left;
|
|
418
479
|
}
|
|
@@ -447,6 +508,9 @@
|
|
|
447
508
|
--tw-font-weight: var(--font-weight-semibold);
|
|
448
509
|
font-weight: var(--font-weight-semibold);
|
|
449
510
|
}
|
|
511
|
+
.overflow-ellipsis {
|
|
512
|
+
text-overflow: ellipsis;
|
|
513
|
+
}
|
|
450
514
|
.text-\(--btn-bg\) {
|
|
451
515
|
color: var(--btn-bg);
|
|
452
516
|
}
|
|
@@ -486,6 +550,10 @@
|
|
|
486
550
|
.opacity-50 {
|
|
487
551
|
opacity: 50%;
|
|
488
552
|
}
|
|
553
|
+
.shadow {
|
|
554
|
+
--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
|
|
555
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
556
|
+
}
|
|
489
557
|
.shadow-lg {
|
|
490
558
|
--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
|
|
491
559
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
@@ -498,6 +566,13 @@
|
|
|
498
566
|
--tw-ring-offset-width: 2px;
|
|
499
567
|
--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
500
568
|
}
|
|
569
|
+
.outline {
|
|
570
|
+
outline-style: var(--tw-outline-style);
|
|
571
|
+
outline-width: 1px;
|
|
572
|
+
}
|
|
573
|
+
.outline-gray-200 {
|
|
574
|
+
outline-color: var(--color-gray-200);
|
|
575
|
+
}
|
|
501
576
|
.transition-\[transform\,scale\,opacity\] {
|
|
502
577
|
transition-property: transform,scale,opacity;
|
|
503
578
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
@@ -699,6 +774,16 @@
|
|
|
699
774
|
border-bottom-width: 1px;
|
|
700
775
|
}
|
|
701
776
|
}
|
|
777
|
+
.group-hover\/app-card\:line-clamp-none {
|
|
778
|
+
&:is(:where(.group\/app-card):hover *) {
|
|
779
|
+
@media (hover: hover) {
|
|
780
|
+
overflow: visible;
|
|
781
|
+
display: block;
|
|
782
|
+
-webkit-box-orient: horizontal;
|
|
783
|
+
-webkit-line-clamp: unset;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
}
|
|
702
787
|
.group-aria-\[haspopup\]\/item\:block {
|
|
703
788
|
&:is(:where(.group\/item)[aria-haspopup] *) {
|
|
704
789
|
display: block;
|
|
@@ -780,6 +865,13 @@
|
|
|
780
865
|
background-color: var(--color-gray-300);
|
|
781
866
|
}
|
|
782
867
|
}
|
|
868
|
+
.hover\:h-auto {
|
|
869
|
+
&:hover {
|
|
870
|
+
@media (hover: hover) {
|
|
871
|
+
height: auto;
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
783
875
|
.hover\:bg-\(--btn-bg-hover\) {
|
|
784
876
|
&:hover {
|
|
785
877
|
@media (hover: hover) {
|
|
@@ -794,6 +886,16 @@
|
|
|
794
886
|
}
|
|
795
887
|
}
|
|
796
888
|
}
|
|
889
|
+
.hover\:bg-gray-100\/80 {
|
|
890
|
+
&:hover {
|
|
891
|
+
@media (hover: hover) {
|
|
892
|
+
background-color: color-mix(in srgb, #f2f2ee 80%, transparent);
|
|
893
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
894
|
+
background-color: color-mix(in oklab, var(--color-gray-100) 80%, transparent);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
}
|
|
797
899
|
.hover\:bg-gray-200 {
|
|
798
900
|
&:hover {
|
|
799
901
|
@media (hover: hover) {
|
|
@@ -976,6 +1078,11 @@
|
|
|
976
1078
|
top: calc(8px * -1);
|
|
977
1079
|
}
|
|
978
1080
|
}
|
|
1081
|
+
.data-\[side\=bottom\]\:top-\[-8px\] {
|
|
1082
|
+
&[data-side="bottom"] {
|
|
1083
|
+
top: -8px;
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
979
1086
|
.data-\[side\=bottom\]\:rotate-0 {
|
|
980
1087
|
&[data-side="bottom"] {
|
|
981
1088
|
rotate: 0deg;
|
|
@@ -986,6 +1093,11 @@
|
|
|
986
1093
|
right: calc(13px * -1);
|
|
987
1094
|
}
|
|
988
1095
|
}
|
|
1096
|
+
.data-\[side\=left\]\:right-\[-13px\] {
|
|
1097
|
+
&[data-side="left"] {
|
|
1098
|
+
right: -13px;
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
989
1101
|
.data-\[side\=left\]\:rotate-90 {
|
|
990
1102
|
&[data-side="left"] {
|
|
991
1103
|
rotate: 90deg;
|
|
@@ -996,6 +1108,11 @@
|
|
|
996
1108
|
left: calc(13px * -1);
|
|
997
1109
|
}
|
|
998
1110
|
}
|
|
1111
|
+
.data-\[side\=right\]\:left-\[-13px\] {
|
|
1112
|
+
&[data-side="right"] {
|
|
1113
|
+
left: -13px;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
999
1116
|
.data-\[side\=right\]\:-rotate-90 {
|
|
1000
1117
|
&[data-side="right"] {
|
|
1001
1118
|
rotate: calc(90deg * -1);
|
|
@@ -1006,6 +1123,11 @@
|
|
|
1006
1123
|
bottom: calc(8px * -1);
|
|
1007
1124
|
}
|
|
1008
1125
|
}
|
|
1126
|
+
.data-\[side\=top\]\:bottom-\[-8px\] {
|
|
1127
|
+
&[data-side="top"] {
|
|
1128
|
+
bottom: -8px;
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1009
1131
|
.data-\[side\=top\]\:rotate-180 {
|
|
1010
1132
|
&[data-side="top"] {
|
|
1011
1133
|
rotate: 180deg;
|
|
@@ -1133,6 +1255,11 @@
|
|
|
1133
1255
|
inherits: false;
|
|
1134
1256
|
initial-value: 0 0 #0000;
|
|
1135
1257
|
}
|
|
1258
|
+
@property --tw-outline-style {
|
|
1259
|
+
syntax: "*";
|
|
1260
|
+
inherits: false;
|
|
1261
|
+
initial-value: solid;
|
|
1262
|
+
}
|
|
1136
1263
|
@property --tw-content {
|
|
1137
1264
|
syntax: "*";
|
|
1138
1265
|
initial-value: "";
|
|
@@ -1178,6 +1305,7 @@
|
|
|
1178
1305
|
--tw-ring-offset-width: 0px;
|
|
1179
1306
|
--tw-ring-offset-color: #fff;
|
|
1180
1307
|
--tw-ring-offset-shadow: 0 0 #0000;
|
|
1308
|
+
--tw-outline-style: solid;
|
|
1181
1309
|
--tw-content: "";
|
|
1182
1310
|
--tw-scale-x: 1;
|
|
1183
1311
|
--tw-scale-y: 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scouterna/ui-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -41,6 +41,9 @@
|
|
|
41
41
|
"tailwind-merge": "^3.3.1",
|
|
42
42
|
"tailwindcss": "^4.1.11"
|
|
43
43
|
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"react-dom": "^19.1.0"
|
|
46
|
+
},
|
|
44
47
|
"devDependencies": {
|
|
45
48
|
"@storybook/addon-a11y": "^8.6.14",
|
|
46
49
|
"@storybook/addon-docs": "8.6.14",
|
|
@@ -52,6 +55,7 @@
|
|
|
52
55
|
"@storybook/test": "8.6.14",
|
|
53
56
|
"@tailwindcss/cli": "^4.1.11",
|
|
54
57
|
"@types/react": "^19.1.8",
|
|
58
|
+
"@types/react-dom": "^19.1.6",
|
|
55
59
|
"@vitest/browser": "^3.2.4",
|
|
56
60
|
"@vitest/coverage-v8": "^3.2.4",
|
|
57
61
|
"copyfiles": "^2.4.1",
|
|
@@ -60,6 +64,7 @@
|
|
|
60
64
|
"storybook": "8.6.14",
|
|
61
65
|
"typescript": "^5.8.3",
|
|
62
66
|
"vite": "^6.3.5",
|
|
67
|
+
"vite-plugin-mkcert": "^1.17.8",
|
|
63
68
|
"vitest": "^3.2.4"
|
|
64
69
|
}
|
|
65
70
|
}
|