@octaviaflow/core 3.1.0-beta.94 → 3.1.0-beta.96

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,78 @@
1
+ /**
2
+ * OrgSwitcher — move between the organizations a person belongs to.
3
+ *
4
+ * FOUR variants, because "switch org" is a different job depending on where it
5
+ * sits and how many orgs a person has. They are offered side by side so a
6
+ * product can pick the one that fits its chrome, not so it can use all four.
7
+ *
8
+ * menu a labelled trigger in the top bar → dropdown list.
9
+ * The default. Reads as "you are in X"; the switch is secondary.
10
+ * rail a vertical column of org avatars, always visible.
11
+ * For people who live in 2–5 orgs and switch constantly; costs
12
+ * permanent horizontal space and does not scale past ~8.
13
+ * search a trigger that opens a filtered list.
14
+ * The only one that works at 20+ orgs; slower for 3.
15
+ * inline a flat list, no popover.
16
+ * For settings pages and the post-login picker, where the choice
17
+ * IS the screen.
18
+ *
19
+ * ── The thing that shapes the whole component ──────────────────────────────
20
+ * Switching organization is NOT a client-side filter. The org a session can
21
+ * see is a signed claim in the access token, so switching re-mints the
22
+ * session server-side. That means it is a round-trip that can fail, and the
23
+ * UI must not pretend otherwise: pass `switchingOrgId` while it is in flight
24
+ * and the target row shows a pending state, the control is disabled, and
25
+ * nothing appears to have changed until the caller says it has.
26
+ *
27
+ * Rendering a switch as instant would be a lie, and a confusing one — the
28
+ * data on screen still belongs to the previous org until the new token
29
+ * arrives.
30
+ */
31
+ import { type ComponentPropsWithoutRef } from "react";
32
+ export type OrgSwitcherVariant = "menu" | "rail" | "search" | "inline";
33
+ export interface OrgSwitcherOrg {
34
+ id: string;
35
+ name: string;
36
+ /** Falls back to initials derived from `name`. */
37
+ initials?: string;
38
+ avatarUrl?: string;
39
+ /** Plan or tier, e.g. "Enterprise". Rendered as quiet secondary text. */
40
+ plan?: string;
41
+ /** The person's role in THAT org, e.g. "Owner". Also quiet. */
42
+ role?: string;
43
+ }
44
+ export interface OrgSwitcherProps extends Omit<ComponentPropsWithoutRef<"div">, "onSelect"> {
45
+ organizations: OrgSwitcherOrg[];
46
+ /** The org the current session is scoped to. */
47
+ currentOrgId: string;
48
+ /** Called with the org to switch to. The caller performs the round-trip. */
49
+ onSwitch: (orgId: string) => void;
50
+ variant?: OrgSwitcherVariant;
51
+ /**
52
+ * The org currently being switched TO. While set, that row shows a spinner
53
+ * and the control is inert — switching re-mints the session, so it is a
54
+ * request, not a toggle.
55
+ */
56
+ switchingOrgId?: string | null;
57
+ /** Optional "create organization" action, appended to the list. */
58
+ onCreate?: () => void;
59
+ createLabel?: string;
60
+ size?: "sm" | "md";
61
+ /**
62
+ * Render the trigger as the PRIMARY identity in a top bar's lead slot —
63
+ * the position a product wordmark would otherwise occupy.
64
+ *
65
+ * Inside the app the wordmark is redundant (you know which product you are
66
+ * in; the tab, the URL and the sidebar all say so) while the organization is
67
+ * not, so the switcher replaces it rather than sitting beside it. Showing
68
+ * both reads as "OctaviaFlow / Octaviaflow" — two names, one of them noise.
69
+ *
70
+ * This matches the wordmark's weight and size so the corner keeps its
71
+ * anchor. `menu` and `search` only.
72
+ */
73
+ lead?: boolean;
74
+ /** Accessible name for the trigger. */
75
+ ariaLabel?: string;
76
+ }
77
+ export declare function OrgSwitcher({ organizations, currentOrgId, onSwitch, variant, switchingOrgId, onCreate, createLabel, size, lead, ariaLabel, className, ...rest }: Readonly<OrgSwitcherProps>): import("react/jsx-runtime").JSX.Element;
78
+ //# sourceMappingURL=OrgSwitcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrgSwitcher.d.ts","sourceRoot":"","sources":["../../../src/components/OrgSwitcher/OrgSwitcher.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EACL,KAAK,wBAAwB,EAO9B,MAAM,OAAO,CAAC;AAOf,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBACf,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACzD,aAAa,EAAE,cAAc,EAAE,CAAC;IAChC,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA4DD,wBAAgB,WAAW,CAAC,EAC1B,aAAa,EACb,YAAY,EACZ,QAAQ,EACR,OAAgB,EAChB,cAAqB,EACrB,QAAQ,EACR,WAAmC,EACnC,IAAW,EACX,IAAY,EACZ,SAAiC,EACjC,SAAS,EACT,GAAG,IAAI,EACR,EAAE,QAAQ,CAAC,gBAAgB,CAAC,2CAoN5B"}
@@ -0,0 +1,2 @@
1
+ export { OrgSwitcher, type OrgSwitcherOrg, type OrgSwitcherProps, type OrgSwitcherVariant, } from "./OrgSwitcher";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/OrgSwitcher/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,GACxB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * PresenceBar — who else has this open right now.
3
+ *
4
+ * A stack of overlapping avatars, each ringed in that person's colour so the
5
+ * same colour identifies them wherever they appear: their ring here, their
6
+ * ring on a node they are looking at, their cursor. Surplus people collapse
7
+ * into a `+N` chip that names them on hover.
8
+ *
9
+ * ── What this component deliberately does NOT do ────────────────────────────
10
+ *
11
+ * It renders OTHER people, and that is all it does. There is no callback that
12
+ * changes the host's view — no `onMemberClick` that scrolls, selects, or opens
13
+ * anything.
14
+ *
15
+ * Presence is decoration. Seeing that a colleague is looking at a node must
16
+ * never move your panel, your selection, or your viewport; that is the classic
17
+ * multiplayer failure where one person's click moves another person's UI.
18
+ * Keeping this component output-only is part of how that guarantee holds —
19
+ * there is simply nothing here to wire the wrong way.
20
+ *
21
+ * If a future version wants "jump to what they are doing", it belongs behind an
22
+ * explicit, user-initiated control — never as a side effect of receiving
23
+ * presence.
24
+ *
25
+ * ── Host responsibilities ───────────────────────────────────────────────────
26
+ *
27
+ * - Filter the local user out before passing `members` if you don't want to see
28
+ * yourself. This component shows exactly who it is given.
29
+ * - `colour` is supplied per member rather than derived here, so the same
30
+ * person keeps the same colour across every surface (the ring on a node, a
31
+ * cursor label) — including surfaces this component knows nothing about.
32
+ */
33
+ import { type ComponentPropsWithoutRef } from "react";
34
+ import { type AvatarSize } from "../Avatar/Avatar";
35
+ export interface PresenceMember {
36
+ /** Stable identity. Used as the React key. */
37
+ userId: string;
38
+ /** Display name — the tooltip text and the avatar's accessible name. */
39
+ name: string;
40
+ /** Optional photo. Falls back to initials derived from `name`. */
41
+ avatarUrl?: string;
42
+ /**
43
+ * This person's identity colour, as any valid CSS colour.
44
+ *
45
+ * Supplied by the host rather than hashed here on purpose: the same value
46
+ * has to drive the ring drawn on a node and a cursor elsewhere in the app,
47
+ * so one source decides it and every surface reads it.
48
+ */
49
+ colour: string;
50
+ /**
51
+ * Whether this person can edit. Someone read-only is present but cannot
52
+ * collide, so they are shown more quietly — rendering them identically to an
53
+ * editor would misrepresent the risk of a clash.
54
+ */
55
+ canEdit?: boolean;
56
+ }
57
+ export interface PresenceBarProps extends Omit<ComponentPropsWithoutRef<"div">, "children"> {
58
+ /** The people to show, in the order they should appear. */
59
+ members: PresenceMember[];
60
+ /**
61
+ * How many avatars to show before collapsing into `+N`. Deliberately small:
62
+ * a wall of faces in a toolbar is noise, and the count carries the rest.
63
+ */
64
+ max?: number;
65
+ size?: AvatarSize;
66
+ /** Group label for assistive technology. */
67
+ label?: string;
68
+ /** Suffix appended to a read-only person's tooltip. */
69
+ viewingLabel?: string;
70
+ }
71
+ export declare const PresenceBar: import("react").ForwardRefExoticComponent<PresenceBarProps & import("react").RefAttributes<HTMLDivElement>>;
72
+ //# sourceMappingURL=PresenceBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PresenceBar.d.ts","sourceRoot":"","sources":["../../../src/components/PresenceBar/PresenceBar.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,KAAK,wBAAwB,EAAkC,MAAM,OAAO,CAAC;AAEtF,OAAO,EAAU,KAAK,UAAU,EAAe,MAAM,kBAAkB,CAAC;AAGxE,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACzF,2DAA2D;IAC3D,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA4BD,eAAO,MAAM,WAAW,6GAyDtB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export type { PresenceBarProps, PresenceMember } from "./PresenceBar";
2
+ export { PresenceBar } from "./PresenceBar";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PresenceBar/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}