@flamingo-stack/openframe-frontend-core 0.0.458 → 0.0.459

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.
Files changed (122) hide show
  1. package/dist/{chunk-YV2YA3QH.cjs → chunk-6XYHSDCL.cjs} +31 -31
  2. package/dist/{chunk-YV2YA3QH.cjs.map → chunk-6XYHSDCL.cjs.map} +1 -1
  3. package/dist/{chunk-VTQSB6QB.cjs → chunk-A2RF7ZG6.cjs} +5 -5
  4. package/dist/{chunk-VTQSB6QB.cjs.map → chunk-A2RF7ZG6.cjs.map} +1 -1
  5. package/dist/{chunk-KQGFKG6Y.js → chunk-AS5B343N.js} +2 -2
  6. package/dist/{chunk-WGJPTFRH.js → chunk-CBNHSXTR.js} +2 -2
  7. package/dist/{chunk-7IRPMNRL.cjs → chunk-DMU3BSPR.cjs} +59 -59
  8. package/dist/{chunk-7IRPMNRL.cjs.map → chunk-DMU3BSPR.cjs.map} +1 -1
  9. package/dist/{chunk-QL7ODLJA.js → chunk-EFGFAVOI.js} +4 -4
  10. package/dist/{chunk-YQBPIUZU.js → chunk-GSKLTMIY.js} +2 -2
  11. package/dist/{chunk-DQ3EHM6G.cjs → chunk-IG4QVZSP.cjs} +9 -9
  12. package/dist/{chunk-DQ3EHM6G.cjs.map → chunk-IG4QVZSP.cjs.map} +1 -1
  13. package/dist/{chunk-ZHQQRYMB.js → chunk-JGSBLQLE.js} +4 -4
  14. package/dist/{chunk-6B27O3ZB.js → chunk-JWXOZRZ6.js} +4 -4
  15. package/dist/{chunk-R5QYMUKN.js → chunk-KW33TBQX.js} +2 -2
  16. package/dist/{chunk-IDKDOQZL.js → chunk-LDVQIOS7.js} +2 -2
  17. package/dist/{chunk-H7ETLG65.js → chunk-MRKRE54X.js} +4 -4
  18. package/dist/{chunk-L676XVP4.cjs → chunk-O5E7ZWHK.cjs} +7 -7
  19. package/dist/{chunk-L676XVP4.cjs.map → chunk-O5E7ZWHK.cjs.map} +1 -1
  20. package/dist/{chunk-LDAOPWXZ.cjs → chunk-OFPHMNRL.cjs} +11 -11
  21. package/dist/{chunk-LDAOPWXZ.cjs.map → chunk-OFPHMNRL.cjs.map} +1 -1
  22. package/dist/{chunk-ZDJ4ZUQ4.cjs → chunk-OJ5ROJSS.cjs} +37 -37
  23. package/dist/{chunk-ZDJ4ZUQ4.cjs.map → chunk-OJ5ROJSS.cjs.map} +1 -1
  24. package/dist/{chunk-HWTUVLYB.js → chunk-Q74TSDZY.js} +2 -2
  25. package/dist/{chunk-U2YDR5DT.js → chunk-RTQ57HC5.js} +2 -2
  26. package/dist/{chunk-5USSSRAL.cjs → chunk-T2EBDVMZ.cjs} +26 -26
  27. package/dist/{chunk-5USSSRAL.cjs.map → chunk-T2EBDVMZ.cjs.map} +1 -1
  28. package/dist/{chunk-TNLFAJPA.js → chunk-TP5MVWQ2.js} +4721 -4901
  29. package/dist/chunk-TP5MVWQ2.js.map +1 -0
  30. package/dist/{chunk-KIIOBK7G.cjs → chunk-WVC627C7.cjs} +26 -26
  31. package/dist/{chunk-KIIOBK7G.cjs.map → chunk-WVC627C7.cjs.map} +1 -1
  32. package/dist/{chunk-XUNJILJT.cjs → chunk-X5TAAOE7.cjs} +62 -62
  33. package/dist/{chunk-XUNJILJT.cjs.map → chunk-X5TAAOE7.cjs.map} +1 -1
  34. package/dist/{chunk-FTXDIDNX.cjs → chunk-XVHNAMAL.cjs} +15 -15
  35. package/dist/{chunk-FTXDIDNX.cjs.map → chunk-XVHNAMAL.cjs.map} +1 -1
  36. package/dist/{chunk-MKLP2SOZ.cjs → chunk-YFPZLP63.cjs} +1196 -1376
  37. package/dist/chunk-YFPZLP63.cjs.map +1 -0
  38. package/dist/components/case-studies/index.cjs +8 -8
  39. package/dist/components/case-studies/index.js +2 -2
  40. package/dist/components/chart.d.ts +1 -1
  41. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  42. package/dist/components/chat/chat-sidebar.d.ts.map +1 -1
  43. package/dist/components/chat/chat-ticket-list.d.ts.map +1 -1
  44. package/dist/components/chat/guide-welcome.d.ts.map +1 -1
  45. package/dist/components/chat/index.cjs +2 -2
  46. package/dist/components/chat/index.js +1 -1
  47. package/dist/components/chat/mingo-chat-history.d.ts.map +1 -1
  48. package/dist/components/chat/mingo-welcome.d.ts.map +1 -1
  49. package/dist/components/contact/index.cjs +3 -3
  50. package/dist/components/contact/index.js +2 -2
  51. package/dist/components/docs/index.cjs +5 -5
  52. package/dist/components/docs/index.js +4 -4
  53. package/dist/components/embeds/index.cjs +3 -3
  54. package/dist/components/embeds/index.js +2 -2
  55. package/dist/components/faq/index.cjs +3 -3
  56. package/dist/components/faq/index.js +2 -2
  57. package/dist/components/features/index.cjs +2 -2
  58. package/dist/components/features/index.js +1 -1
  59. package/dist/components/features/notifications/notification-drawer.d.ts.map +1 -1
  60. package/dist/components/features/time-tracker/time-tracker-panel.d.ts.map +1 -1
  61. package/dist/components/help-center-pages/index.cjs +20 -20
  62. package/dist/components/help-center-pages/index.js +11 -11
  63. package/dist/components/index.cjs +129 -135
  64. package/dist/components/index.cjs.map +1 -1
  65. package/dist/components/index.js +9 -15
  66. package/dist/components/index.js.map +1 -1
  67. package/dist/components/layout/page-container.d.ts.map +1 -1
  68. package/dist/components/navigation/app-layout-drawer.d.ts +1 -1
  69. package/dist/components/navigation/index.cjs +2 -2
  70. package/dist/components/navigation/index.js +1 -1
  71. package/dist/components/onboarding-guides/index.cjs +5 -5
  72. package/dist/components/onboarding-guides/index.js +4 -4
  73. package/dist/components/related-content/index.cjs +3 -3
  74. package/dist/components/related-content/index.js +2 -2
  75. package/dist/components/tickets/index.cjs +5 -5
  76. package/dist/components/tickets/index.js +4 -4
  77. package/dist/components/ui/drawer.d.ts +1 -1
  78. package/dist/components/ui/drawer.d.ts.map +1 -1
  79. package/dist/components/ui/index.cjs +2 -8
  80. package/dist/components/ui/index.cjs.map +1 -1
  81. package/dist/components/ui/index.d.ts +0 -1
  82. package/dist/components/ui/index.d.ts.map +1 -1
  83. package/dist/components/ui/index.js +1 -7
  84. package/dist/components/ui/modal-v2.d.ts.map +1 -1
  85. package/dist/components/ui/modal.d.ts.map +1 -1
  86. package/dist/index.cjs +2 -8
  87. package/dist/index.cjs.map +1 -1
  88. package/dist/index.js +1 -7
  89. package/package.json +1 -3
  90. package/src/components/chat/chat-message-list.tsx +6 -7
  91. package/src/components/chat/chat-sidebar.tsx +4 -9
  92. package/src/components/chat/chat-ticket-list.tsx +2 -8
  93. package/src/components/chat/guide-welcome.tsx +4 -6
  94. package/src/components/chat/mingo-chat-history.tsx +4 -6
  95. package/src/components/chat/mingo-welcome.tsx +4 -6
  96. package/src/components/features/notifications/notification-drawer.tsx +4 -8
  97. package/src/components/features/time-tracker/time-tracker-panel.tsx +3 -11
  98. package/src/components/layout/page-container.tsx +5 -17
  99. package/src/components/ui/drawer.tsx +3 -8
  100. package/src/components/ui/index.ts +0 -1
  101. package/src/components/ui/modal-v2.tsx +2 -12
  102. package/src/components/ui/modal.tsx +2 -9
  103. package/src/styles/index.css +0 -2
  104. package/dist/chunk-MKLP2SOZ.cjs.map +0 -1
  105. package/dist/chunk-TNLFAJPA.js.map +0 -1
  106. package/dist/components/ui/overlay-scroll-area.d.ts +0 -59
  107. package/dist/components/ui/overlay-scroll-area.d.ts.map +0 -1
  108. package/src/components/ui/overlay-scroll-area.tsx +0 -219
  109. package/src/stories/OverlayScrollArea.stories.tsx +0 -52
  110. package/src/styles/overlay-scrollbars-theme.css +0 -19
  111. package/src/styles/vendor-overlayscrollbars.css +0 -673
  112. /package/dist/{chunk-KQGFKG6Y.js.map → chunk-AS5B343N.js.map} +0 -0
  113. /package/dist/{chunk-WGJPTFRH.js.map → chunk-CBNHSXTR.js.map} +0 -0
  114. /package/dist/{chunk-QL7ODLJA.js.map → chunk-EFGFAVOI.js.map} +0 -0
  115. /package/dist/{chunk-YQBPIUZU.js.map → chunk-GSKLTMIY.js.map} +0 -0
  116. /package/dist/{chunk-ZHQQRYMB.js.map → chunk-JGSBLQLE.js.map} +0 -0
  117. /package/dist/{chunk-6B27O3ZB.js.map → chunk-JWXOZRZ6.js.map} +0 -0
  118. /package/dist/{chunk-R5QYMUKN.js.map → chunk-KW33TBQX.js.map} +0 -0
  119. /package/dist/{chunk-IDKDOQZL.js.map → chunk-LDVQIOS7.js.map} +0 -0
  120. /package/dist/{chunk-H7ETLG65.js.map → chunk-MRKRE54X.js.map} +0 -0
  121. /package/dist/{chunk-HWTUVLYB.js.map → chunk-Q74TSDZY.js.map} +0 -0
  122. /package/dist/{chunk-U2YDR5DT.js.map → chunk-RTQ57HC5.js.map} +0 -0
@@ -1,59 +0,0 @@
1
- import * as React from 'react';
2
- import { type PartialOptions } from 'overlayscrollbars';
3
- /** True once mounted on a device with a mouse/trackpad-grade pointer. */
4
- export declare function useFinePointer(): boolean;
5
- export interface OverlayScrollAreaProps extends React.HTMLAttributes<HTMLDivElement> {
6
- /** Sizing/box classes of the scroll container (`flex-1 min-h-0`, `max-h-…`,
7
- * borders, background) — AND paddings. Do NOT include `overflow-*` here.
8
- *
9
- * PADDING BELONGS HERE, NOT ON `contentClassName`: OverlayScrollbars owns
10
- * the viewport's box and writes `padding: 0` inline on it, so a padding
11
- * class on the viewport is silently dropped (measured — this is why the
12
- * wrapper components keep passing their consumer `className` to the host). */
13
- className?: string;
14
- /** Layout classes for the scrolling element itself (`flex flex-col gap-…`).
15
- * Children are its direct children, so `gap`/`flex` applies exactly as it
16
- * did on the old single `overflow-auto` div. Paddings do NOT work here —
17
- * see `className`. */
18
- contentClassName?: string;
19
- /** Receives the actual scrolling element — use for scrollTop/scrollHeight
20
- * logic and as IntersectionObserver root. Set from the first commit, valid
21
- * on both the overlay and the native fallback path. */
22
- viewportRef?: React.Ref<HTMLDivElement>;
23
- /** Extra OverlayScrollbars options merged over the ODS defaults. */
24
- options?: PartialOptions;
25
- children?: React.ReactNode;
26
- }
27
- /**
28
- * Replacement for an `overflow-auto` scroll container with the standardized
29
- * ODS overlay scrollbar. Split the old scroller's classes: sizing goes to
30
- * `className`, content layout to `contentClassName`. The inner scroller div
31
- * is stable across pointer modes — refs and `onScroll` (via the standard
32
- * HTML props) keep working like on the plain div it replaces.
33
- *
34
- * On touch devices (no fine pointer) the overlay layer is never initialized
35
- * and the inner div scrolls with its native (already overlay) scrollbar.
36
- */
37
- export declare function OverlayScrollArea({ className, contentClassName, viewportRef, options, children, ...props }: OverlayScrollAreaProps): React.JSX.Element;
38
- export interface GlobalOverlayScrollbarsProps {
39
- /** Extra OverlayScrollbars options merged over the ODS defaults. */
40
- options?: PartialOptions;
41
- }
42
- /**
43
- * Applies the same overlay scrollbar to the PAGE scroller (`<body>`).
44
- * Render once near the app root (client side). No-op on touch devices.
45
- *
46
- * ONLY mount this on APP-SHELL pages whose body barely scrolls — the real
47
- * scrolling happens in inner `OverlayScrollArea` containers (openframe-frontend,
48
- * openframe-chat). Do NOT mount it on long scroll-driven documents: the thumb is
49
- * repositioned from JS on every scroll frame, so on a page whose main thread is
50
- * already busy with reveal-on-scroll sections, tickers and marquees the scroll
51
- * visibly stutters. Measured on multi-platform-hub; raising the update debounce
52
- * (`update.debounce.mutation`/`resize`) did NOT help, which rules out the
53
- * observer re-measurement and points at the per-frame cost itself — i.e. it is
54
- * inherent to any JS-drawn scrollbar, not to this library. Such pages keep the
55
- * native page scrollbar, styled by the ODS `scrollbar-width`/`scrollbar-color`
56
- * globals; their inner containers can still use `OverlayScrollArea`.
57
- */
58
- export declare function GlobalOverlayScrollbars({ options }?: GlobalOverlayScrollbarsProps): null;
59
- //# sourceMappingURL=overlay-scroll-area.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"overlay-scroll-area.d.ts","sourceRoot":"","sources":["../../../src/components/ui/overlay-scroll-area.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AA+B1E,yEAAyE;AACzE,wBAAgB,cAAc,IAAI,OAAO,CAWxC;AAoBD,MAAM,WAAW,sBAAuB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAClF;;;;;;mFAM+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;2BAGuB;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;4DAEwD;IACxD,WAAW,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IACvC,oEAAoE;IACpE,OAAO,CAAC,EAAE,cAAc,CAAA;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,sBAAsB,qBA8DxB;AAED,MAAM,WAAW,4BAA4B;IAC3C,oEAAoE;IACpE,OAAO,CAAC,EAAE,cAAc,CAAA;CACzB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,OAAO,EAAE,GAAE,4BAAiC,QA2BrF"}
@@ -1,219 +0,0 @@
1
- 'use client'
2
-
3
- import * as React from 'react'
4
- import { OverlayScrollbars, type PartialOptions } from 'overlayscrollbars'
5
- import { cn } from '../../utils/cn'
6
-
7
- // =============================================================================
8
- // Standardized macOS-like overlay scrollbars on every platform.
9
- //
10
- // OverlayScrollbars hides the native scrollbar and draws a styleable overlay
11
- // one on top while keeping NATIVE scrolling (wheel, touchpad momentum,
12
- // keyboard, drag-the-thumb). With `autoHide` the bar shows only while
13
- // scrolling and fades out when idle — the macOS behavior, now identical on
14
- // Windows/Linux and for mouse users.
15
- //
16
- // Touch devices keep the native scrollbars: mobile bars are already overlay
17
- // and auto-hiding, so the custom layer is initialized only on fine-pointer
18
- // devices (desktop / tablet with a mouse).
19
- // =============================================================================
20
-
21
- /** Overlay scrollbars are desktop-only; touch keeps native scrolling. */
22
- const FINE_POINTER_QUERY = '(hover: hover) and (pointer: fine)'
23
-
24
- /**
25
- * `matchMedia` for the fine-pointer query, or `null` where it doesn't exist —
26
- * jsdom (every consumer's component tests) and non-browser render paths. The
27
- * whole overlay layer is progressive enhancement, so "can't detect" degrades
28
- * to the native scrollbar instead of throwing.
29
- */
30
- const matchFinePointer = (): MediaQueryList | null =>
31
- typeof window !== 'undefined' && typeof window.matchMedia === 'function'
32
- ? window.matchMedia(FINE_POINTER_QUERY)
33
- : null
34
-
35
- /** True once mounted on a device with a mouse/trackpad-grade pointer. */
36
- export function useFinePointer(): boolean {
37
- const [fine, setFine] = React.useState(false)
38
- React.useEffect(() => {
39
- const mq = matchFinePointer()
40
- if (!mq) return
41
- setFine(mq.matches)
42
- const onChange = (e: MediaQueryListEvent) => setFine(e.matches)
43
- mq.addEventListener('change', onChange)
44
- return () => mq.removeEventListener('change', onChange)
45
- }, [])
46
- return fine
47
- }
48
-
49
- /** Shared ODS defaults: thin grey thumb, transparent track, show on scroll. */
50
- const ODS_SCROLLBAR_OPTIONS: PartialOptions = {
51
- scrollbars: {
52
- theme: 'os-theme-ods',
53
- autoHide: 'scroll',
54
- autoHideDelay: 800,
55
- // Keep the bar visible until the first scroll so keyboard/AT users still
56
- // get the affordance on freshly opened views.
57
- autoHideSuspend: true,
58
- },
59
- }
60
-
61
- const setRef = <T,>(ref: React.Ref<T> | undefined, value: T | null) => {
62
- if (!ref) return
63
- if (typeof ref === 'function') ref(value)
64
- else (ref as React.MutableRefObject<T | null>).current = value
65
- }
66
-
67
- export interface OverlayScrollAreaProps extends React.HTMLAttributes<HTMLDivElement> {
68
- /** Sizing/box classes of the scroll container (`flex-1 min-h-0`, `max-h-…`,
69
- * borders, background) — AND paddings. Do NOT include `overflow-*` here.
70
- *
71
- * PADDING BELONGS HERE, NOT ON `contentClassName`: OverlayScrollbars owns
72
- * the viewport's box and writes `padding: 0` inline on it, so a padding
73
- * class on the viewport is silently dropped (measured — this is why the
74
- * wrapper components keep passing their consumer `className` to the host). */
75
- className?: string
76
- /** Layout classes for the scrolling element itself (`flex flex-col gap-…`).
77
- * Children are its direct children, so `gap`/`flex` applies exactly as it
78
- * did on the old single `overflow-auto` div. Paddings do NOT work here —
79
- * see `className`. */
80
- contentClassName?: string
81
- /** Receives the actual scrolling element — use for scrollTop/scrollHeight
82
- * logic and as IntersectionObserver root. Set from the first commit, valid
83
- * on both the overlay and the native fallback path. */
84
- viewportRef?: React.Ref<HTMLDivElement>
85
- /** Extra OverlayScrollbars options merged over the ODS defaults. */
86
- options?: PartialOptions
87
- children?: React.ReactNode
88
- }
89
-
90
- /**
91
- * Replacement for an `overflow-auto` scroll container with the standardized
92
- * ODS overlay scrollbar. Split the old scroller's classes: sizing goes to
93
- * `className`, content layout to `contentClassName`. The inner scroller div
94
- * is stable across pointer modes — refs and `onScroll` (via the standard
95
- * HTML props) keep working like on the plain div it replaces.
96
- *
97
- * On touch devices (no fine pointer) the overlay layer is never initialized
98
- * and the inner div scrolls with its native (already overlay) scrollbar.
99
- */
100
- export function OverlayScrollArea({
101
- className,
102
- contentClassName,
103
- viewportRef,
104
- options,
105
- children,
106
- ...props
107
- }: OverlayScrollAreaProps) {
108
- const hostRef = React.useRef<HTMLDivElement>(null)
109
- const scrollerRef = React.useRef<HTMLDivElement>(null)
110
-
111
- // Serialize to keep the effect dep stable for inline `options` objects.
112
- const optionsJson = JSON.stringify(options ?? null)
113
-
114
- // Layout effect so the viewport is upgraded before consumers' own layout
115
- // effects (scroll-fade hooks, observers) measure it.
116
- React.useLayoutEffect(() => {
117
- const host = hostRef.current
118
- const viewport = scrollerRef.current
119
- if (!host || !viewport) return
120
- const extra = (JSON.parse(optionsJson) ?? {}) as PartialOptions
121
- const mq = matchFinePointer()
122
- if (!mq) return
123
- let instance: ReturnType<typeof OverlayScrollbars> | null = null
124
-
125
- const sync = () => {
126
- if (mq.matches && !instance) {
127
- // Our own div is passed as the viewport: children stay inside it and
128
- // it remains the scrolling element; the library only suppresses its
129
- // native scrollbar and appends the overlay handles to the host.
130
- instance = OverlayScrollbars(
131
- { target: host, elements: { viewport } },
132
- // `scrollbars` merges one level deep: a caller overriding a single
133
- // key (e.g. `autoHide`) must not drop the ODS theme and the other
134
- // defaults with it.
135
- {
136
- ...ODS_SCROLLBAR_OPTIONS,
137
- ...extra,
138
- scrollbars: { ...ODS_SCROLLBAR_OPTIONS.scrollbars, ...extra.scrollbars },
139
- },
140
- )
141
- } else if (!mq.matches && instance) {
142
- instance.destroy()
143
- instance = null
144
- }
145
- }
146
-
147
- sync()
148
- mq.addEventListener('change', sync)
149
- return () => {
150
- mq.removeEventListener('change', sync)
151
- instance?.destroy()
152
- }
153
- }, [optionsJson])
154
-
155
- return (
156
- <div ref={hostRef} className={cn('relative', className)}>
157
- <div
158
- ref={(el) => {
159
- scrollerRef.current = el
160
- setRef(viewportRef, el)
161
- }}
162
- className={cn('h-full w-full overflow-auto', contentClassName)}
163
- {...props}
164
- >
165
- {children}
166
- </div>
167
- </div>
168
- )
169
- }
170
-
171
- export interface GlobalOverlayScrollbarsProps {
172
- /** Extra OverlayScrollbars options merged over the ODS defaults. */
173
- options?: PartialOptions
174
- }
175
-
176
- /**
177
- * Applies the same overlay scrollbar to the PAGE scroller (`<body>`).
178
- * Render once near the app root (client side). No-op on touch devices.
179
- *
180
- * ONLY mount this on APP-SHELL pages whose body barely scrolls — the real
181
- * scrolling happens in inner `OverlayScrollArea` containers (openframe-frontend,
182
- * openframe-chat). Do NOT mount it on long scroll-driven documents: the thumb is
183
- * repositioned from JS on every scroll frame, so on a page whose main thread is
184
- * already busy with reveal-on-scroll sections, tickers and marquees the scroll
185
- * visibly stutters. Measured on multi-platform-hub; raising the update debounce
186
- * (`update.debounce.mutation`/`resize`) did NOT help, which rules out the
187
- * observer re-measurement and points at the per-frame cost itself — i.e. it is
188
- * inherent to any JS-drawn scrollbar, not to this library. Such pages keep the
189
- * native page scrollbar, styled by the ODS `scrollbar-width`/`scrollbar-color`
190
- * globals; their inner containers can still use `OverlayScrollArea`.
191
- */
192
- export function GlobalOverlayScrollbars({ options }: GlobalOverlayScrollbarsProps = {}) {
193
- const fine = useFinePointer()
194
- // Serialize to keep the effect dep stable for inline `options` objects.
195
- const optionsJson = JSON.stringify(options ?? null)
196
-
197
- React.useEffect(() => {
198
- if (!fine) return
199
- const extra = (JSON.parse(optionsJson) ?? {}) as PartialOptions
200
- // Required by OverlayScrollbars for body initialization — suppresses the
201
- // native scrollbars on both scroll roots before the overlay takes over.
202
- document.documentElement.setAttribute('data-overlayscrollbars-initialize', '')
203
- document.body.setAttribute('data-overlayscrollbars-initialize', '')
204
- const instance = OverlayScrollbars(document.body, {
205
- ...ODS_SCROLLBAR_OPTIONS,
206
- ...extra,
207
- // Same one-level-deep merge as OverlayScrollArea: a caller overriding a
208
- // single key must not drop the ODS theme (or a tuning preset's siblings).
209
- scrollbars: { ...ODS_SCROLLBAR_OPTIONS.scrollbars, ...extra.scrollbars },
210
- })
211
- return () => {
212
- instance.destroy()
213
- document.documentElement.removeAttribute('data-overlayscrollbars-initialize')
214
- document.body.removeAttribute('data-overlayscrollbars-initialize')
215
- }
216
- }, [fine, optionsJson])
217
-
218
- return null
219
- }
@@ -1,52 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/nextjs-vite'
2
- import { OverlayScrollArea } from '../components/ui/overlay-scroll-area'
3
-
4
- // POC: standardized macOS-like overlay scrollbar (OverlayScrollbars) — the
5
- // bar appears while scrolling / hovering and fades out when idle, on every
6
- // platform. Native scrolling (wheel, touchpad momentum, thumb drag) is kept.
7
-
8
- const meta: Meta<typeof OverlayScrollArea> = {
9
- title: 'UI/OverlayScrollArea',
10
- component: OverlayScrollArea,
11
- parameters: { layout: 'centered' },
12
- }
13
-
14
- export default meta
15
- type Story = StoryObj<typeof OverlayScrollArea>
16
-
17
- const rows = (count: number) =>
18
- Array.from({ length: count }, (_, i) => (
19
- <div key={i} className="border-b border-ods-border px-[var(--spacing-system-m)] py-[var(--spacing-system-s)] text-ods-text-primary">
20
- Row {i + 1} — scrollable content
21
- </div>
22
- ))
23
-
24
- export const Vertical: Story = {
25
- render: () => (
26
- <OverlayScrollArea className="h-72 w-96 rounded-lg border border-ods-border bg-ods-card">
27
- {rows(40)}
28
- </OverlayScrollArea>
29
- ),
30
- }
31
-
32
- export const Horizontal: Story = {
33
- render: () => (
34
- <OverlayScrollArea className="h-24 w-96 rounded-lg border border-ods-border bg-ods-card">
35
- <div className="flex w-max gap-[var(--spacing-system-s)] p-[var(--spacing-system-m)]">
36
- {Array.from({ length: 30 }, (_, i) => (
37
- <div key={i} className="flex h-12 w-28 shrink-0 items-center justify-center rounded-md bg-ods-bg text-ods-text-secondary">
38
- Chip {i + 1}
39
- </div>
40
- ))}
41
- </div>
42
- </OverlayScrollArea>
43
- ),
44
- }
45
-
46
- export const Both: Story = {
47
- render: () => (
48
- <OverlayScrollArea className="h-72 w-96 rounded-lg border border-ods-border bg-ods-card">
49
- <div className="w-[800px]">{rows(40)}</div>
50
- </OverlayScrollArea>
51
- ),
52
- }
@@ -1,19 +0,0 @@
1
- /* ODS theme for OverlayScrollbars (see components/ui/overlay-scroll-area.tsx).
2
- Thin grey draggable thumb on a transparent track — matches the global
3
- elevator scrollbar styling, but with macOS-like auto-hide on all platforms. */
4
- .os-theme-ods {
5
- --os-size: 8px;
6
- --os-padding-perpendicular: 2px;
7
- --os-padding-axis: 2px;
8
- --os-track-bg: transparent;
9
- --os-track-bg-hover: transparent;
10
- --os-track-bg-active: transparent;
11
- --os-handle-bg: var(--ods-system-greys-grey);
12
- --os-handle-bg-hover: var(--ods-system-greys-grey-hover);
13
- --os-handle-bg-active: var(--ods-system-greys-grey-action);
14
- --os-handle-border-radius: 4px;
15
- --os-handle-perpendicular-size: 100%;
16
- --os-handle-perpendicular-size-hover: 100%;
17
- --os-handle-perpendicular-size-active: 100%;
18
- --os-handle-min-size: 33px;
19
- }