@fasl-work/caos-app-shell 0.6.1 → 0.6.3
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/index.d.ts +27 -0
- package/dist/index.js +17 -4
- package/package.json +1 -1
- package/styles.css +4 -0
package/dist/index.d.ts
CHANGED
|
@@ -68,6 +68,21 @@ interface ShellConfig {
|
|
|
68
68
|
es: string;
|
|
69
69
|
};
|
|
70
70
|
};
|
|
71
|
+
/**
|
|
72
|
+
* Routes whose surface IS the viewport (ADR-0071 rule 1): on these the shell adds
|
|
73
|
+
* `.app-shell.fixed`, which sizes the page to 100dvh and lets flex distribute the
|
|
74
|
+
* height, so the ONE container that owns long content scrolls and the document
|
|
75
|
+
* never does. A doc route is not listed and keeps the document scroll. Matching is
|
|
76
|
+
* exact, or by prefix for a non-root path (`/lab` matches `/lab/case-1`).
|
|
77
|
+
*
|
|
78
|
+
* The stylesheet has carried `.app-shell.fixed` with the note "apps that fill the
|
|
79
|
+
* viewport add it" since the containment fix, and no app could: this component
|
|
80
|
+
* rendered a fixed class string. Measured on Porvenir before this field existed:
|
|
81
|
+
* every tab of the App route scrolled the document by 200 to 770px.
|
|
82
|
+
*/
|
|
83
|
+
fixedRoutes?: string[];
|
|
84
|
+
/** Every route fixed: a single-surface app (a hub, a one-page tool). */
|
|
85
|
+
fixed?: boolean;
|
|
71
86
|
}
|
|
72
87
|
/** The shared CAOS/Faena app shell: sticky header (brand + nav + icon-links + lang/theme) + footer.
|
|
73
88
|
* Wrap your <Routes> (or single landing) in it, inside a Router. */
|
|
@@ -262,6 +277,18 @@ interface CaseSelectorProps {
|
|
|
262
277
|
deepLink?: boolean | string;
|
|
263
278
|
ariaLabel?: string;
|
|
264
279
|
className?: string;
|
|
280
|
+
/**
|
|
281
|
+
* How the one-of-N choice is presented. Default 'chips' keeps the labelled chip
|
|
282
|
+
* blocks; 'select' renders a native dropdown with one optgroup per category.
|
|
283
|
+
*
|
|
284
|
+
* ADR-0071 rule 7 asks for the dropdown whenever the deck is a categorised
|
|
285
|
+
* one-of-N choice, because the chip layout spends vertical space linearly in the
|
|
286
|
+
* number of cases and that space is taken from the instrument on every render.
|
|
287
|
+
* Measured on Porvenir at 2560x1440: ten cases in four categories occupied a
|
|
288
|
+
* 308px block, 21% of the viewport, for a choice one control expresses. The
|
|
289
|
+
* category structure is preserved either way; only the height changes.
|
|
290
|
+
*/
|
|
291
|
+
layout?: 'chips' | 'select';
|
|
265
292
|
}
|
|
266
293
|
/**
|
|
267
294
|
* CaseSelector v2 — the shared source + case picker. Renders (1) an optional first-level source
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, useState, useRef, useEffect, useCallback, useId, useContext } from 'react';
|
|
2
|
-
import { NavLink } from 'react-router';
|
|
2
|
+
import { useLocation, NavLink } from 'react-router';
|
|
3
3
|
import { Sun, Moon, Languages, Boxes, Github, Globe, Briefcase, Info } from 'lucide-react';
|
|
4
4
|
import { create } from 'zustand';
|
|
5
5
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -254,7 +254,9 @@ function AppShell({ config, children }) {
|
|
|
254
254
|
const portfolio = config.links.portfolio ?? PORTFOLIO;
|
|
255
255
|
const [archOpen, setArchOpen] = useState(false);
|
|
256
256
|
const archLabel = lang === "es" ? "Arquitectura / C\xF3mo funciona" : "Architecture / How it works";
|
|
257
|
-
|
|
257
|
+
const { pathname } = useLocation();
|
|
258
|
+
const fixed = config.fixed === true || (config.fixedRoutes ?? []).some((p) => p === pathname || p !== "/" && pathname.startsWith(p.replace(/\/$/, "") + "/"));
|
|
259
|
+
return /* @__PURE__ */ jsxs("div", { className: fixed ? "app-shell fixed" : "app-shell", children: [
|
|
258
260
|
/* @__PURE__ */ jsx("header", { className: "site-header", children: /* @__PURE__ */ jsxs("div", { className: "header-inner", children: [
|
|
259
261
|
/* @__PURE__ */ jsxs(NavLink, { to: "/", className: "brand", "aria-label": config.product.name, children: [
|
|
260
262
|
/* @__PURE__ */ jsx("span", { className: "brand-mark", children: config.product.mark ?? /* @__PURE__ */ jsx(Boxes, { size: 18, "aria-hidden": "true" }) }),
|
|
@@ -568,7 +570,8 @@ function CaseSelector(props) {
|
|
|
568
570
|
text,
|
|
569
571
|
deepLink,
|
|
570
572
|
ariaLabel,
|
|
571
|
-
className
|
|
573
|
+
className,
|
|
574
|
+
layout = "chips"
|
|
572
575
|
} = props;
|
|
573
576
|
const t = { ...TEXT[lang], ...text };
|
|
574
577
|
const baseId = useId();
|
|
@@ -606,7 +609,17 @@ function CaseSelector(props) {
|
|
|
606
609
|
)) })
|
|
607
610
|
] }),
|
|
608
611
|
source && source !== "synthetic" && /* @__PURE__ */ jsx("p", { className: "cs-locked banner", children: lockedNote ?? t.lockedNote }),
|
|
609
|
-
|
|
612
|
+
layout === "select" && /* @__PURE__ */ jsx(
|
|
613
|
+
"select",
|
|
614
|
+
{
|
|
615
|
+
className: "select cs-select",
|
|
616
|
+
"aria-label": ariaLabel ?? "Case selector",
|
|
617
|
+
value: selectedId,
|
|
618
|
+
onChange: (e) => onSelect(e.target.value),
|
|
619
|
+
children: groups.map((g) => /* @__PURE__ */ jsx("optgroup", { label: g.category || " ", children: g.cases.map((c) => /* @__PURE__ */ jsx("option", { value: c.id, disabled: c.disabled, title: caseTooltip(c) || void 0, children: `${c.id} \xB7 ${c.name}` }, c.id)) }, g.category || "_"))
|
|
620
|
+
}
|
|
621
|
+
),
|
|
622
|
+
layout === "chips" && groups.map((g) => /* @__PURE__ */ jsxs("div", { className: "cs-group", role: "group", "aria-label": g.category || void 0, children: [
|
|
610
623
|
g.category && /* @__PURE__ */ jsx("span", { className: "cs-group-label", children: g.category }),
|
|
611
624
|
/* @__PURE__ */ jsx("div", { className: "cs-chips", children: g.cases.map((c) => {
|
|
612
625
|
const on = c.id === selectedId;
|
package/package.json
CHANGED
package/styles.css
CHANGED
|
@@ -316,3 +316,7 @@ html, body { overflow-x: hidden; }
|
|
|
316
316
|
[data-arch-lang] .l-es { display: none; }
|
|
317
317
|
[data-arch-lang="es"] .l-en { display: none; }
|
|
318
318
|
[data-arch-lang="es"] .l-es { display: inline; }
|
|
319
|
+
|
|
320
|
+
/* The compact one-of-N case picker (ADR-0071 rule 7). Ten cases in four categories
|
|
321
|
+
cost a 308px chip block, 21% of a 2560x1440 viewport, and one row as a dropdown. */
|
|
322
|
+
.cs-select { width: 100%; max-width: 460px; }
|