@withpotter/components 0.13.0-next.81 → 0.13.0-next.82

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.
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Which "arrival" a path belongs to. A page fades and settles in when this key changes, and
3
+ * everything inside it is drawn again. Most paths are their own arrival; a host names the sections
4
+ * whose pages are tabs of one place (`/dashboard/staff` and its tabs), so moving between the tabs
5
+ * does not make the title and tab bar arrive again.
6
+ */
7
+ export declare function transitionPath(pathname: string | null | undefined, groups: readonly string[]): string;
@@ -0,0 +1,11 @@
1
+ function transitionPath(pathname, groups) {
2
+ const path = pathname ?? "";
3
+ for (const group of groups) {
4
+ if (path === group || path.startsWith(`${group}/`)) return group;
5
+ }
6
+ return path;
7
+ }
8
+ export {
9
+ transitionPath
10
+ };
11
+ //# sourceMappingURL=page-transition-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/dashboard/page-transition-key.ts"],"sourcesContent":["/**\n * Which \"arrival\" a path belongs to. A page fades and settles in when this key changes, and\n * everything inside it is drawn again. Most paths are their own arrival; a host names the sections\n * whose pages are tabs of one place (`/dashboard/staff` and its tabs), so moving between the tabs\n * does not make the title and tab bar arrive again.\n */\nexport function transitionPath(\n pathname: string | null | undefined,\n groups: readonly string[],\n): string {\n const path = pathname ?? '';\n for (const group of groups) {\n if (path === group || path.startsWith(`${group}/`)) return group;\n }\n return path;\n}\n"],"mappings":"AAMO,SAAS,eACd,UACA,QACQ;AACR,QAAM,OAAO,YAAY;AACzB,aAAW,SAAS,QAAQ;AAC1B,QAAI,SAAS,SAAS,KAAK,WAAW,GAAG,KAAK,GAAG,EAAG,QAAO;AAAA,EAC7D;AACA,SAAO;AACT;","names":[]}
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Sections whose pages are tabs of one place, by their first path (`/dashboard/staff`). Moving
3
+ * between their tabs is not an arrival: the frame stays, the content changes under it. A host puts
4
+ * this around the dashboard; with none, every path arrives on its own as before.
5
+ */
6
+ export declare const PageTransitionGroups: import("react").Provider<readonly string[]>;
1
7
  /**
2
8
  * The arrival of a route's content.
3
9
  *
@@ -23,6 +29,11 @@
23
29
  * the app was the one arrival with no motion on it. Nothing new is needed for
24
30
  * it: changing business IS an arrival, and it should arrive the way every
25
31
  * other one does.
32
+ *
33
+ * TABS OF ONE PLACE ARE ONE ARRIVAL. A host names such sections with `PageTransitionGroups`
34
+ * (see `page-transition-key.ts`); moving between their tabs keeps the key, so the frame the tabs
35
+ * share stays on screen and only what is under it changes, instead of the whole page fading in
36
+ * again on every tab.
26
37
  */
27
38
  export declare function PageTransition({ children }: {
28
39
  children: React.ReactNode;
@@ -1,12 +1,18 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
+ import { createContext, useContext } from "react";
3
4
  import { usePathname } from "@withpotter/lib/use-pathname";
4
5
  import { AnimatePresence, motion } from "motion/react";
5
6
  import { springs } from "@withpotter/lib/motion";
6
7
  import { useAuth } from "@withpotter/lib/auth-context";
8
+ import { transitionPath } from "./page-transition-key";
9
+ const NO_GROUPS = [];
10
+ const GroupsContext = createContext(NO_GROUPS);
11
+ const PageTransitionGroups = GroupsContext.Provider;
7
12
  function PageTransition({ children }) {
8
13
  const pathname = usePathname();
9
14
  const { tenant } = useAuth();
15
+ const groups = useContext(GroupsContext);
10
16
  return /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", initial: false, children: /* @__PURE__ */ jsx(
11
17
  motion.div,
12
18
  {
@@ -16,10 +22,11 @@ function PageTransition({ children }) {
16
22
  className: "motion-reduce:transform-none",
17
23
  children
18
24
  },
19
- `${tenant?.slug ?? ""}:${pathname}`
25
+ `${tenant?.slug ?? ""}:${transitionPath(pathname, groups)}`
20
26
  ) });
21
27
  }
22
28
  export {
23
- PageTransition
29
+ PageTransition,
30
+ PageTransitionGroups
24
31
  };
25
32
  //# sourceMappingURL=page-transition.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/dashboard/page-transition.tsx"],"sourcesContent":["'use client';\n\nimport { usePathname } from '@withpotter/lib/use-pathname';\nimport { AnimatePresence, motion } from 'motion/react';\nimport { springs } from '@withpotter/lib/motion';\nimport { useAuth } from '@withpotter/lib/auth-context';\n\n/**\n * The arrival of a route's content.\n *\n * Navigation used to be a hard swap: the old page's pixels were replaced by the\n * new page's pixels on the same frame, which reads as a flicker rather than a\n * move — you cannot tell whether something loaded or the screen glitched.\n *\n * This is one of the cases `lib/motion.ts` reserves a spring for: the content\n * genuinely travels, so it carries velocity and settles rather than stopping\n * dead on a fixed curve. `springs.gentle` is the surface preset — cards, panels\n * and page blocks — so a route arrives the same way a sheet does.\n *\n * The travel is deliberately small (6px) and there is no exit animation: making\n * the outgoing page linger delays the incoming one, and the brand direction is\n * explicit that motion is never load-bearing. `prefers-reduced-motion` drops it\n * to a plain opacity settle.\n *\n * THE WORKSPACE IS PART OF THE KEY, not just the path.\n * John, 2026-08-23: *\"when you change a workspace why is there no motion or\n * spring physics, it just loads sharp.\"* Switching businesses is a soft swap —\n * the tenant changes in context and every consumer re-renders — so the URL\n * never moves, the key never changed, and the single biggest content change in\n * the app was the one arrival with no motion on it. Nothing new is needed for\n * it: changing business IS an arrival, and it should arrive the way every\n * other one does.\n */\nexport function PageTransition({ children }: { children: React.ReactNode }) {\n const pathname = usePathname();\n const { tenant } = useAuth();\n\n return (\n <AnimatePresence mode=\"wait\" initial={false}>\n <motion.div\n key={`${tenant?.slug ?? ''}:${pathname}`}\n initial={{ opacity: 0, y: 6 }}\n animate={{ opacity: 1, y: 0 }}\n transition={springs.gentle}\n className=\"motion-reduce:transform-none\"\n >\n {children}\n </motion.div>\n </AnimatePresence>\n );\n}\n"],"mappings":";AAuCM;AArCN,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB,cAAc;AACxC,SAAS,eAAe;AACxB,SAAS,eAAe;AA4BjB,SAAS,eAAe,EAAE,SAAS,GAAkC;AAC1E,QAAM,WAAW,YAAY;AAC7B,QAAM,EAAE,OAAO,IAAI,QAAQ;AAE3B,SACE,oBAAC,mBAAgB,MAAK,QAAO,SAAS,OACpC;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MAEC,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,MAC5B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,MAC5B,YAAY,QAAQ;AAAA,MACpB,WAAU;AAAA,MAET;AAAA;AAAA,IANI,GAAG,QAAQ,QAAQ,EAAE,IAAI,QAAQ;AAAA,EAOxC,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/dashboard/page-transition.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, useContext } from 'react';\nimport { usePathname } from '@withpotter/lib/use-pathname';\nimport { AnimatePresence, motion } from 'motion/react';\nimport { springs } from '@withpotter/lib/motion';\nimport { useAuth } from '@withpotter/lib/auth-context';\nimport { transitionPath } from './page-transition-key';\n\nconst NO_GROUPS: readonly string[] = [];\nconst GroupsContext = createContext<readonly string[]>(NO_GROUPS);\n\n/**\n * Sections whose pages are tabs of one place, by their first path (`/dashboard/staff`). Moving\n * between their tabs is not an arrival: the frame stays, the content changes under it. A host puts\n * this around the dashboard; with none, every path arrives on its own as before.\n */\nexport const PageTransitionGroups = GroupsContext.Provider;\n\n/**\n * The arrival of a route's content.\n *\n * Navigation used to be a hard swap: the old page's pixels were replaced by the\n * new page's pixels on the same frame, which reads as a flicker rather than a\n * move — you cannot tell whether something loaded or the screen glitched.\n *\n * This is one of the cases `lib/motion.ts` reserves a spring for: the content\n * genuinely travels, so it carries velocity and settles rather than stopping\n * dead on a fixed curve. `springs.gentle` is the surface preset — cards, panels\n * and page blocks — so a route arrives the same way a sheet does.\n *\n * The travel is deliberately small (6px) and there is no exit animation: making\n * the outgoing page linger delays the incoming one, and the brand direction is\n * explicit that motion is never load-bearing. `prefers-reduced-motion` drops it\n * to a plain opacity settle.\n *\n * THE WORKSPACE IS PART OF THE KEY, not just the path.\n * John, 2026-08-23: *\"when you change a workspace why is there no motion or\n * spring physics, it just loads sharp.\"* Switching businesses is a soft swap —\n * the tenant changes in context and every consumer re-renders — so the URL\n * never moves, the key never changed, and the single biggest content change in\n * the app was the one arrival with no motion on it. Nothing new is needed for\n * it: changing business IS an arrival, and it should arrive the way every\n * other one does.\n *\n * TABS OF ONE PLACE ARE ONE ARRIVAL. A host names such sections with `PageTransitionGroups`\n * (see `page-transition-key.ts`); moving between their tabs keeps the key, so the frame the tabs\n * share stays on screen and only what is under it changes, instead of the whole page fading in\n * again on every tab.\n */\nexport function PageTransition({ children }: { children: React.ReactNode }) {\n const pathname = usePathname();\n const { tenant } = useAuth();\n const groups = useContext(GroupsContext);\n\n return (\n <AnimatePresence mode=\"wait\" initial={false}>\n <motion.div\n key={`${tenant?.slug ?? ''}:${transitionPath(pathname, groups)}`}\n initial={{ opacity: 0, y: 6 }}\n animate={{ opacity: 1, y: 0 }}\n transition={springs.gentle}\n className=\"motion-reduce:transform-none\"\n >\n {children}\n </motion.div>\n </AnimatePresence>\n );\n}\n"],"mappings":";AAyDM;AAvDN,SAAS,eAAe,kBAAkB;AAC1C,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB,cAAc;AACxC,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAE/B,MAAM,YAA+B,CAAC;AACtC,MAAM,gBAAgB,cAAiC,SAAS;AAOzD,MAAM,uBAAuB,cAAc;AAiC3C,SAAS,eAAe,EAAE,SAAS,GAAkC;AAC1E,QAAM,WAAW,YAAY;AAC7B,QAAM,EAAE,OAAO,IAAI,QAAQ;AAC3B,QAAM,SAAS,WAAW,aAAa;AAEvC,SACE,oBAAC,mBAAgB,MAAK,QAAO,SAAS,OACpC;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MAEC,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,MAC5B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,MAC5B,YAAY,QAAQ;AAAA,MACpB,WAAU;AAAA,MAET;AAAA;AAAA,IANI,GAAG,QAAQ,QAAQ,EAAE,IAAI,eAAe,UAAU,MAAM,CAAC;AAAA,EAOhE,GACF;AAEJ;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@withpotter/components",
3
- "version": "0.13.0-next.81",
3
+ "version": "0.13.0-next.82",
4
4
  "description": "Box dashboard feature components: editors, mobile screens, pickers, and composite UI built on @withpotter/ui-kit.",
5
5
  "license": "UNLICENSED",
6
6
  "sideEffects": [
@@ -50,9 +50,9 @@
50
50
  "@tiptap/react": "^3.22.5",
51
51
  "@tiptap/starter-kit": "^3.22.5",
52
52
  "@tiptap/suggestion": "^3.22.5",
53
- "@withpotter/hooks": "^0.13.0-next.81",
54
- "@withpotter/lib": "^0.13.0-next.81",
55
- "@withpotter/ui-kit": "^0.13.0-next.81",
53
+ "@withpotter/hooks": "^0.13.0-next.82",
54
+ "@withpotter/lib": "^0.13.0-next.82",
55
+ "@withpotter/ui-kit": "^0.13.0-next.82",
56
56
  "@xyflow/react": "^12.11.2",
57
57
  "dompurify": "^3.3.1",
58
58
  "jsqr": "1.4.0",