@flamingo-stack/openframe-frontend-core 0.0.839 → 0.0.841
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/build/export-map.json +1 -1
- package/dist/build/route-styles.cjs +3 -1
- package/dist/build/style-sources.cjs +15 -2
- package/dist/build/style-sources.d.ts +3 -0
- package/dist/{chunk-37XKZ4JM.cjs → chunk-275AQ6LC.cjs} +6 -6
- package/dist/{chunk-5BM7X4GA.cjs → chunk-5GBLXY5F.cjs} +2 -2
- package/dist/{chunk-5L3UKDC6.cjs → chunk-6LDL3UZE.cjs} +9 -9
- package/dist/{chunk-SWMUW3RR.cjs → chunk-744JXTDP.cjs} +19 -19
- package/dist/{chunk-46LATWQR.cjs → chunk-7WKRMJI6.cjs} +5 -5
- package/dist/{chunk-XJ4AB24Y.cjs → chunk-AT6D7BAZ.cjs} +5 -5
- package/dist/{chunk-C4OQIYGW.cjs → chunk-CCRXBFNL.cjs} +8 -8
- package/dist/{chunk-LC65AC6M.cjs → chunk-COWMXUHN.cjs} +2 -0
- package/dist/{chunk-5E4YEHHO.cjs → chunk-DGY5KEPY.cjs} +55 -55
- package/dist/{chunk-N2TCVIPR.cjs → chunk-DYDQLS2R.cjs} +539 -539
- package/dist/{chunk-LWMWY3JO.cjs → chunk-E7M54JWW.cjs} +14 -14
- package/dist/{chunk-Z7A7IZWL.cjs → chunk-EV6BPF47.cjs} +236 -210
- package/dist/{chunk-7XRFAHJF.cjs → chunk-FHI4I3TQ.cjs} +9 -9
- package/dist/{chunk-ZABZIM2Y.cjs → chunk-FRL2ZN4O.cjs} +3 -3
- package/dist/{chunk-7Z536SPR.cjs → chunk-FW7RKWPY.cjs} +15 -1
- package/dist/{chunk-3MBKEF7Z.cjs → chunk-GMK4JGC2.cjs} +46 -46
- package/dist/{chunk-SZVPRP5E.cjs → chunk-GUKFMMDZ.cjs} +3 -3
- package/dist/{chunk-GN6LEJWY.cjs → chunk-HXTZZE3R.cjs} +253 -131
- package/dist/{chunk-2XZZHRRU.cjs → chunk-IELPVUPR.cjs} +18 -18
- package/dist/{chunk-64PF3UC7.cjs → chunk-INBFKUZA.cjs} +17 -17
- package/dist/{chunk-APOMNC7H.cjs → chunk-IUDBG3HJ.cjs} +3 -3
- package/dist/{chunk-4JHO2NVI.cjs → chunk-J2IXYCEH.cjs} +26 -10
- package/dist/{chunk-C4RYIDPU.cjs → chunk-JM2XA7VY.cjs} +28 -28
- package/dist/{chunk-GPXKG34G.cjs → chunk-JUEAZCD6.cjs} +46 -46
- package/dist/{chunk-2QAUQPGC.cjs → chunk-MYAPG3FQ.cjs} +21 -21
- package/dist/{chunk-GRHF5SWL.cjs → chunk-NFNSPLGC.cjs} +3 -3
- package/dist/{chunk-UDRVVCOC.cjs → chunk-Q6WUHYOG.cjs} +72 -72
- package/dist/{chunk-H3WTYAVR.cjs → chunk-RSJYTQEA.cjs} +30 -30
- package/dist/{chunk-MG3HJIGG.cjs → chunk-UAI4VMEF.cjs} +4 -4
- package/dist/{chunk-S5RMRQKT.cjs → chunk-UZPYYHF5.cjs} +18 -18
- package/dist/{chunk-DFTXZE7B.cjs → chunk-VBH2RCFM.cjs} +73 -73
- package/dist/{chunk-FNNDGOR3.cjs → chunk-WCK5T3UD.cjs} +43 -43
- package/dist/{chunk-TRZEFT2N.cjs → chunk-WI7EXAZT.cjs} +9 -5
- package/dist/{chunk-TKS25VKE.cjs → chunk-Z35PL3UR.cjs} +32 -32
- package/dist/{chunk-ENK75WN4.cjs → chunk-ZAO5SYBJ.cjs} +4 -4
- package/dist/{cloud-tenants-WE3H3VAW.cjs → cloud-tenants-PV63RZ73.cjs} +19 -19
- package/dist/components/case-studies/index.cjs +33 -33
- package/dist/components/chat/chat-nav-sidebar.d.ts.map +1 -1
- package/dist/components/chat/chat-nav-sidebar.js +17 -3
- package/dist/components/chat/index.cjs +13 -13
- package/dist/components/contact/index.cjs +20 -20
- package/dist/components/docs/index.cjs +23 -23
- package/dist/components/embeds/index.cjs +20 -20
- package/dist/components/faq/index.cjs +21 -21
- package/dist/components/features/index.cjs +19 -19
- package/dist/components/help-center-pages/index.cjs +120 -120
- package/dist/components/index.cjs +76 -76
- package/dist/components/meeting-scheduler/index.cjs +82 -82
- package/dist/components/navigation/account-popover.d.ts.map +1 -1
- package/dist/components/navigation/account-popover.js +26 -2
- package/dist/components/navigation/app-layout-side-panel.d.ts.map +1 -1
- package/dist/components/navigation/app-layout-side-panel.js +2 -9
- package/dist/components/navigation/index.cjs +22 -22
- package/dist/components/navigation/navigation-sidebar-grouped.d.ts.map +1 -1
- package/dist/components/navigation/navigation-sidebar-grouped.js +30 -6
- package/dist/components/navigation/navigation-sidebar-item.d.ts.map +1 -1
- package/dist/components/navigation/navigation-sidebar-item.js +14 -1
- package/dist/components/navigation/navigation-sidebar.d.ts.map +1 -1
- package/dist/components/navigation/navigation-sidebar.js +72 -3
- package/dist/components/onboarding-guides/index.cjs +22 -22
- package/dist/components/product-demo/index.cjs +30 -30
- package/dist/components/related-content/index.cjs +8 -8
- package/dist/components/tickets/index.cjs +24 -24
- package/dist/components/ui/index.cjs +19 -19
- package/dist/components/ui/panel-resize-handle.d.ts +27 -6
- package/dist/components/ui/panel-resize-handle.d.ts.map +1 -1
- package/dist/components/ui/panel-resize-handle.js +27 -3
- package/dist/{devices-ZBZN2RRG.cjs → devices-VECG5JNC.cjs} +20 -20
- package/dist/{embeddable-chat-RBC7F4TL.cjs → embeddable-chat-VRYAQQF6.cjs} +90 -90
- package/dist/hooks/index.cjs +11 -7
- package/dist/hooks/ui/index.d.ts +1 -0
- package/dist/hooks/ui/index.d.ts.map +1 -1
- package/dist/hooks/ui/index.js +1 -0
- package/dist/hooks/ui/use-clipped-label-tooltip.d.ts +14 -0
- package/dist/hooks/ui/use-clipped-label-tooltip.d.ts.map +1 -0
- package/dist/hooks/ui/use-clipped-label-tooltip.js +13 -0
- package/dist/hooks/ui/use-is-truncated.d.ts.map +1 -1
- package/dist/hooks/ui/use-is-truncated.js +1 -0
- package/dist/hooks/ui/use-media-query.d.ts.map +1 -1
- package/dist/hooks/ui/use-media-query.js +1 -0
- package/dist/hooks/ui/use-resizable-panel-size.d.ts +1 -0
- package/dist/hooks/ui/use-resizable-panel-size.d.ts.map +1 -1
- package/dist/hooks/ui/use-resizable-panel-size.js +5 -1
- package/dist/index.cjs +28 -24
- package/dist/{knowledge-2QNZGDFO.cjs → knowledge-YJSDJIXT.cjs} +20 -20
- package/dist/{logs-YPWTJVIH.cjs → logs-42JG3NZ5.cjs} +26 -26
- package/dist/{policies-BK7TUKAF.cjs → policies-D4QNVJ26.cjs} +23 -23
- package/dist/{remote-session-CN3G7JNR.cjs → remote-session-EE6477O3.cjs} +10 -10
- package/dist/{scripts-K7AOYWZE.cjs → scripts-4VFYBXBE.cjs} +26 -26
- package/dist/{software-update-UFN4SBMY.cjs → software-update-OSDZQ5CP.cjs} +23 -23
- package/dist/{tickets-board-PLYD2NSY.cjs → tickets-board-44HO3LR4.cjs} +10 -10
- package/dist/types/navigation.d.ts +36 -0
- package/dist/types/navigation.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/chat/chat-nav-sidebar.tsx +17 -4
- package/src/components/navigation/account-popover.tsx +31 -2
- package/src/components/navigation/app-layout-side-panel.tsx +2 -7
- package/src/components/navigation/navigation-sidebar-grouped.tsx +37 -6
- package/src/components/navigation/navigation-sidebar-item.tsx +18 -1
- package/src/components/navigation/navigation-sidebar.tsx +116 -7
- package/src/components/ui/panel-resize-handle.tsx +50 -8
- package/src/hooks/ui/index.ts +1 -0
- package/src/hooks/ui/use-clipped-label-tooltip.ts +20 -0
- package/src/hooks/ui/use-is-truncated.ts +2 -0
- package/src/hooks/ui/use-media-query.ts +2 -0
- package/src/hooks/ui/use-resizable-panel-size.ts +7 -1
- package/src/types/navigation.ts +37 -0
|
@@ -3,13 +3,37 @@
|
|
|
3
3
|
import { type KeyboardEvent, type PointerEvent, type ReactNode, type RefObject, useEffect, useRef } from 'react';
|
|
4
4
|
|
|
5
5
|
import { cn } from '../../utils/cn';
|
|
6
|
+
import { Menu01Icon } from '../icons-v2-generated';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
|
-
* The drag-to-resize handle of a side or edge panel, shared by `Drawer
|
|
9
|
-
* `AppLayoutDrawer`. A drag writes the
|
|
10
|
-
*
|
|
9
|
+
* The drag-to-resize handle of a side or edge panel, shared by `Drawer`,
|
|
10
|
+
* `AppLayoutDrawer`, `ComposerSheet` and `NavigationSidebar`. A drag writes the
|
|
11
|
+
* panel's size to the DOM (or hands it to `onDrag`) and reports it once, on
|
|
12
|
+
* release; arrow keys, Home and End report at once; a double click asks for the
|
|
13
|
+
* default (`onReset`).
|
|
11
14
|
*/
|
|
12
15
|
|
|
16
|
+
/**
|
|
17
|
+
* The grip the design draws on a resizable edge (its `resize-handle`): a 16×32
|
|
18
|
+
* pill in the page's background astride the panel's border, with a three-line
|
|
19
|
+
* mark. `NavigationSidebar` hands it to the handle as its `grip`, and
|
|
20
|
+
* `AppLayoutSidePanel`'s own handle draws it too.
|
|
21
|
+
*/
|
|
22
|
+
export function PanelResizeGrip({ className }: { className?: string }) {
|
|
23
|
+
return (
|
|
24
|
+
<span
|
|
25
|
+
aria-hidden
|
|
26
|
+
className={cn(
|
|
27
|
+
'flex h-8 w-4 items-center justify-center rounded-sm border border-ods-border bg-ods-bg text-ods-text-secondary transition-colors',
|
|
28
|
+
'group-hover:border-ods-border-hover group-focus-visible:border-ods-accent group-focus-visible:text-ods-accent',
|
|
29
|
+
className,
|
|
30
|
+
)}
|
|
31
|
+
>
|
|
32
|
+
<Menu01Icon size={12} />
|
|
33
|
+
</span>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
13
37
|
type PanelSide = 'right' | 'left' | 'top' | 'bottom';
|
|
14
38
|
|
|
15
39
|
const HORIZONTAL_SIDES: ReadonlySet<PanelSide> = new Set(['left', 'right']);
|
|
@@ -37,8 +61,18 @@ export interface PanelResizeHandleProps {
|
|
|
37
61
|
onSize: (next: number) => void;
|
|
38
62
|
/** Clamp a candidate size to the min/max and the container. */
|
|
39
63
|
clampSize: (next: number) => number;
|
|
40
|
-
/** The panel the size applies to — written directly while dragging.
|
|
41
|
-
|
|
64
|
+
/** The panel the size applies to — written directly while dragging. Omit for a
|
|
65
|
+
* panel sized by other means (`onDrag`). */
|
|
66
|
+
panelRef?: RefObject<HTMLDivElement | null>;
|
|
67
|
+
/**
|
|
68
|
+
* Every size the drag reaches, in place of writing `panelRef`'s inline size:
|
|
69
|
+
* for a panel whose width is a custom property or a class rather than an
|
|
70
|
+
* inline style, or one that marks itself while dragged. `onSize` still
|
|
71
|
+
* reports once, on release.
|
|
72
|
+
*/
|
|
73
|
+
onDrag?: (next: number) => void;
|
|
74
|
+
/** A double click on the handle: back to the default size. */
|
|
75
|
+
onReset?: () => void;
|
|
42
76
|
/** `overlay` is the body-level `Drawer`'s handle, `inLayout` the wider one of
|
|
43
77
|
* `AppLayoutDrawer`. They differ in track width and grip colour only. */
|
|
44
78
|
variant: 'overlay' | 'inLayout';
|
|
@@ -57,6 +91,8 @@ export function PanelResizeHandle({
|
|
|
57
91
|
onSize,
|
|
58
92
|
clampSize,
|
|
59
93
|
panelRef,
|
|
94
|
+
onDrag,
|
|
95
|
+
onReset,
|
|
60
96
|
variant,
|
|
61
97
|
ariaLabel,
|
|
62
98
|
className,
|
|
@@ -95,12 +131,17 @@ export function PanelResizeHandle({
|
|
|
95
131
|
// the size is unchanged, so it leaves the style alone.
|
|
96
132
|
const handlePointerMove = (e: PointerEvent<HTMLDivElement>) => {
|
|
97
133
|
const start = startRef.current;
|
|
98
|
-
|
|
99
|
-
if (!
|
|
134
|
+
if (!start) return;
|
|
135
|
+
if (!onDrag && !panelRef?.current) return;
|
|
100
136
|
const delta = isHorizontal ? e.clientX - start.x : e.clientY - start.y;
|
|
101
137
|
const next = clampSize(start.size + delta * direction);
|
|
102
138
|
dragSizeRef.current = next;
|
|
103
|
-
|
|
139
|
+
if (onDrag) {
|
|
140
|
+
onDrag(next);
|
|
141
|
+
} else if (panelRef) {
|
|
142
|
+
const panel = panelRef.current;
|
|
143
|
+
if (panel) panel.style[isHorizontal ? 'width' : 'height'] = `${next}px`;
|
|
144
|
+
}
|
|
104
145
|
e.currentTarget.setAttribute('aria-valuenow', String(Math.round(next)));
|
|
105
146
|
};
|
|
106
147
|
|
|
@@ -174,6 +215,7 @@ export function PanelResizeHandle({
|
|
|
174
215
|
onPointerCancel={endDrag}
|
|
175
216
|
onLostPointerCapture={endDrag}
|
|
176
217
|
onKeyDown={handleKeyDown}
|
|
218
|
+
onDoubleClick={onReset}
|
|
177
219
|
className={cn(
|
|
178
220
|
'group absolute z-20 flex touch-none select-none',
|
|
179
221
|
'outline-none ring-0 focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0',
|
package/src/hooks/ui/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ export * from './use-header-height';
|
|
|
9
9
|
export * from './use-sticky-toolbar';
|
|
10
10
|
export * from './use-horizontal-scrollbar';
|
|
11
11
|
export * from './use-image-edge-color';
|
|
12
|
+
export * from './use-clipped-label-tooltip';
|
|
12
13
|
export * from './use-is-truncated';
|
|
13
14
|
export * from './use-isomorphic-layout-effect';
|
|
14
15
|
export * from './use-keyboard-collision-padding';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useIsTruncated } from './use-is-truncated';
|
|
4
|
+
import { useMediaQuery } from './use-media-query';
|
|
5
|
+
|
|
6
|
+
/** A pointer that can hover: where a tooltip on a clipped label is reachable. A touch screen has none. */
|
|
7
|
+
export const HOVER_MEDIA_QUERY = '(hover: hover) and (pointer: fine)';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A clipped label's "full text" tooltip: `ref` goes on the clipped element (see
|
|
11
|
+
* {@link useIsTruncated}), `enabled` says whether the tooltip may open — only
|
|
12
|
+
* while the text IS clipped, and only on a device whose pointer can hover. A
|
|
13
|
+
* phone or tablet has no hover to reach it with, so it offers none there; the
|
|
14
|
+
* rows keep their accessible names. Pass the rendered text as `value`.
|
|
15
|
+
*/
|
|
16
|
+
export function useClippedLabelTooltip<T extends HTMLElement>(value: unknown) {
|
|
17
|
+
const { ref, isTruncated } = useIsTruncated<T>(value);
|
|
18
|
+
const canHover = useMediaQuery(HOVER_MEDIA_QUERY) === true;
|
|
19
|
+
return { ref, enabled: isTruncated && canHover };
|
|
20
|
+
}
|
|
@@ -52,6 +52,8 @@ export function useIsTruncated<T extends HTMLElement>(value: unknown, options?:
|
|
|
52
52
|
);
|
|
53
53
|
};
|
|
54
54
|
check();
|
|
55
|
+
// An environment without ResizeObserver (jsdom in a consumer's tests) measures once.
|
|
56
|
+
if (typeof ResizeObserver === 'undefined') return undefined;
|
|
55
57
|
const observer = new ResizeObserver(check);
|
|
56
58
|
observer.observe(element);
|
|
57
59
|
return () => observer.disconnect();
|
|
@@ -13,6 +13,8 @@ export function useMediaQuery(query: string): boolean | undefined {
|
|
|
13
13
|
const [matches, setMatches] = useState<boolean | undefined>(undefined);
|
|
14
14
|
|
|
15
15
|
useIsomorphicLayoutEffect(() => {
|
|
16
|
+
// An environment without matchMedia (jsdom in a consumer's tests) never answers: `undefined` throughout.
|
|
17
|
+
if (typeof window.matchMedia !== 'function') return undefined;
|
|
16
18
|
const matchMedia = window.matchMedia(query);
|
|
17
19
|
|
|
18
20
|
const handleChange = () => {
|
|
@@ -110,5 +110,11 @@ export function useResizablePanelSize({
|
|
|
110
110
|
[clampSize, storage],
|
|
111
111
|
);
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
/** Back to `defaultSize`: the choice is forgotten and its stored entry removed. */
|
|
114
|
+
const resetSize = useCallback(() => {
|
|
115
|
+
setChosen({ storage, size: null });
|
|
116
|
+
storage?.clear();
|
|
117
|
+
}, [storage]);
|
|
118
|
+
|
|
119
|
+
return { size, setSize, resetSize, clampSize };
|
|
114
120
|
}
|
package/src/types/navigation.ts
CHANGED
|
@@ -115,6 +115,35 @@ export interface SlidingSidebarConfig {
|
|
|
115
115
|
className?: string;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
/**
|
|
119
|
+
* `NavigationSidebarConfig.resizable`: the user drags the expanded sidebar's
|
|
120
|
+
* right edge on desktop (`lg` and up). The 56px rail is not resizable, nor are
|
|
121
|
+
* the tablet overlay and the burger menu; the overlay opens to the chosen width.
|
|
122
|
+
*/
|
|
123
|
+
export interface NavigationSidebarResizeConfig {
|
|
124
|
+
/**
|
|
125
|
+
* Narrowest expanded width, in px. Raised to 141px when lower: the rows read
|
|
126
|
+
* 140px and up as expanded (`@[140px]/of-nav-sidebar`).
|
|
127
|
+
*/
|
|
128
|
+
minWidth: number;
|
|
129
|
+
/** Widest expanded width, in px. Also kept to the room there is (`minContentWidth`). */
|
|
130
|
+
maxWidth: number;
|
|
131
|
+
/**
|
|
132
|
+
* Px of the row the content beside the sidebar always keeps, so a wide sidebar
|
|
133
|
+
* cannot crowd the page out of a narrow desktop window. Default 720, the lib's
|
|
134
|
+
* `content-md` breakpoint.
|
|
135
|
+
*/
|
|
136
|
+
minContentWidth?: number;
|
|
137
|
+
/**
|
|
138
|
+
* `localStorage` key for the width the user chose: `{ size }` under
|
|
139
|
+
* `<storageKey>:chosen` (see `useResizablePanelSize`). Only a drag or a key
|
|
140
|
+
* press on the handle writes it, never the default or a clamped width; a double
|
|
141
|
+
* click removes it. Omit to keep the choice for the mount only. A host that seeds
|
|
142
|
+
* `NAVIGATION_SIDEBAR_WIDTH_VAR` before first paint reads the same entry.
|
|
143
|
+
*/
|
|
144
|
+
storageKey?: string;
|
|
145
|
+
}
|
|
146
|
+
|
|
118
147
|
/**
|
|
119
148
|
* Configuration for the navigation sidebar component
|
|
120
149
|
*/
|
|
@@ -237,6 +266,14 @@ export interface NavigationSidebarConfig {
|
|
|
237
266
|
* chat search in `sectionSlot`.
|
|
238
267
|
*/
|
|
239
268
|
revealSignal?: number;
|
|
269
|
+
/**
|
|
270
|
+
* Let the user resize the expanded sidebar on desktop: a drag handle astride
|
|
271
|
+
* its right edge (the grip the Mingo chat drawer had), arrow keys, Home and
|
|
272
|
+
* End on it, a double click back to the default. The default stays
|
|
273
|
+
* `expandedWidth` (grouped) or 224px (flat); both variants. Omitted: the fixed
|
|
274
|
+
* widths, as before.
|
|
275
|
+
*/
|
|
276
|
+
resizable?: NavigationSidebarResizeConfig;
|
|
240
277
|
}
|
|
241
278
|
|
|
242
279
|
/** What a slot render function is told about the place it is drawn in. */
|