bubble-toolbar 0.0.0-stage → 1.0.0
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/CHANGELOG.md +3 -0
- package/LICENSE +21 -0
- package/README.md +314 -2
- package/dist/index.d.mts +203 -0
- package/dist/index.d.ts +203 -0
- package/dist/index.js +615 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +586 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles.css +195 -0
- package/package.json +89 -5
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 el_jijuna
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,315 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 🫧 Bubble Toolbar
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/bubble-toolbar)
|
|
4
|
+
[](https://react.dev/)
|
|
5
|
+
[](./tsconfig.json)
|
|
6
|
+
[](./.storybook/main.ts)
|
|
7
|
+
[](./eslint.config.mjs)
|
|
8
|
+
[](./biome.json)
|
|
9
|
+
[](./LICENSE)
|
|
10
|
+
|
|
11
|
+
A responsive floating toolbar with a frosted glass effect for React 18 and 19. Built with TypeScript, it arranges content into groups that adapt from circles to pills based on their children.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **React 18 and 19 support:** typed components with forwarded refs.
|
|
16
|
+
- **Group-based composition:** pass arrays of nodes or use `BubbleToolbar.Group` children.
|
|
17
|
+
- **Adaptive shapes:** a single child creates a circle; multiple children create a pill.
|
|
18
|
+
- **Frosted glass:** background blur, subtle borders, soft shadows, and glass, light, dark, or automatic themes.
|
|
19
|
+
- **Responsive layout:** fixed or relative positioning, automatic centering, and horizontal scrolling on smaller screens.
|
|
20
|
+
- **Tests and examples:** Jest and React Testing Library tests, plus interactive Storybook stories.
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install bubble-toolbar
|
|
26
|
+
# Or use pnpm:
|
|
27
|
+
pnpm add bubble-toolbar
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick start
|
|
31
|
+
|
|
32
|
+
### Group arrays
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
import { BubbleArea, BubbleIconButton, BubbleToolbar } from 'bubble-toolbar';
|
|
36
|
+
import 'bubble-toolbar/styles.css';
|
|
37
|
+
|
|
38
|
+
const App = () => (
|
|
39
|
+
<BubbleToolbar
|
|
40
|
+
position="bottom"
|
|
41
|
+
theme="glass"
|
|
42
|
+
groups={[
|
|
43
|
+
// One child: circle.
|
|
44
|
+
[<BubbleIconButton key="logo" name="logo" />],
|
|
45
|
+
|
|
46
|
+
// Multiple children: pill.
|
|
47
|
+
[
|
|
48
|
+
<BubbleIconButton key="search" name="search" />,
|
|
49
|
+
<BubbleArea key="area">
|
|
50
|
+
<input aria-label="Search" placeholder="Search or type /" />
|
|
51
|
+
</BubbleArea>,
|
|
52
|
+
],
|
|
53
|
+
|
|
54
|
+
// Each group below becomes a circle.
|
|
55
|
+
[<BubbleIconButton key="theme" name="theme" />],
|
|
56
|
+
[<BubbleIconButton key="chat" name="chat" />],
|
|
57
|
+
[<BubbleIconButton key="notifications" name="notifications" badge={3} />],
|
|
58
|
+
]}
|
|
59
|
+
/>
|
|
60
|
+
);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Compound components
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { BubbleArea, BubbleIconButton, BubbleToolbar } from 'bubble-toolbar';
|
|
67
|
+
import 'bubble-toolbar/styles.css';
|
|
68
|
+
|
|
69
|
+
const FloatingMenu = () => (
|
|
70
|
+
<BubbleToolbar position="bottom" theme="glass">
|
|
71
|
+
<BubbleToolbar.Group>
|
|
72
|
+
<BubbleIconButton name="logo" />
|
|
73
|
+
</BubbleToolbar.Group>
|
|
74
|
+
|
|
75
|
+
<BubbleToolbar.Group>
|
|
76
|
+
<BubbleIconButton name="search" />
|
|
77
|
+
<BubbleArea>
|
|
78
|
+
<input aria-label="Search" placeholder="Search…" />
|
|
79
|
+
</BubbleArea>
|
|
80
|
+
</BubbleToolbar.Group>
|
|
81
|
+
|
|
82
|
+
<BubbleToolbar.Group>
|
|
83
|
+
<BubbleIconButton name="theme" />
|
|
84
|
+
</BubbleToolbar.Group>
|
|
85
|
+
</BubbleToolbar>
|
|
86
|
+
);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The components include inline glass styles. Import the stylesheet for additional styling, including automatic dark theme support and focus indicators.
|
|
90
|
+
|
|
91
|
+
## Async activity
|
|
92
|
+
|
|
93
|
+
Import `bubble-toolbar/styles.css` to enable the rotating border and glow. Activity is indeterminate: it does not disable controls, cancel tasks, or display success or error states.
|
|
94
|
+
|
|
95
|
+
### External control
|
|
96
|
+
|
|
97
|
+
Set `busy` on the toolbar to illuminate every group, or on a group to illuminate only that bubble:
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
<BubbleToolbar busy={isSaving}>
|
|
101
|
+
<BubbleToolbar.Group>
|
|
102
|
+
<BubbleIconButton name="logo" />
|
|
103
|
+
</BubbleToolbar.Group>
|
|
104
|
+
<BubbleToolbar.Group busy={isSearching}>
|
|
105
|
+
<BubbleIconButton name="search" />
|
|
106
|
+
<BubbleArea>Search results</BubbleArea>
|
|
107
|
+
</BubbleToolbar.Group>
|
|
108
|
+
</BubbleToolbar>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Track tasks from inside a group
|
|
112
|
+
|
|
113
|
+
`useBubbleActivity()` returns `{ isBusy, run }`. It targets the nearest group, including groups created through the `groups` prop. Calling it outside a group throws a descriptive error.
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
import { useState } from 'react';
|
|
117
|
+
import { BubbleIconButton, BubbleToolbar, useBubbleActivity } from 'bubble-toolbar';
|
|
118
|
+
import 'bubble-toolbar/styles.css';
|
|
119
|
+
|
|
120
|
+
const SaveAction = ({ save }: { save: () => Promise<void> }) => {
|
|
121
|
+
const { isBusy, run } = useBubbleActivity();
|
|
122
|
+
const [error, setError] = useState<string | null>(null);
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<BubbleIconButton
|
|
126
|
+
name="chat"
|
|
127
|
+
tooltip={error ?? (isBusy ? 'Saving…' : 'Save')}
|
|
128
|
+
onClick={async () => {
|
|
129
|
+
setError(null);
|
|
130
|
+
try {
|
|
131
|
+
await run(save);
|
|
132
|
+
} catch {
|
|
133
|
+
setError('Save failed. Try again.');
|
|
134
|
+
}
|
|
135
|
+
}}
|
|
136
|
+
/>
|
|
137
|
+
);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// Render SaveAction inside a group:
|
|
141
|
+
// <BubbleToolbar.Group><SaveAction save={saveChanges} /></BubbleToolbar.Group>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`run<T>(task: () => Promise<T>): Promise<T>` returns the task's result and propagates synchronous exceptions and rejected promises. Handle errors in your application. Concurrent tasks keep the group busy until the last task settles. Unmounting the group does not cancel the consumer's task.
|
|
145
|
+
|
|
146
|
+
A group is busy when **any** of the following is true: the toolbar's `busy` prop, the group's `busy` prop, or a pending local task. Passing `busy={false}` does not hide activity from another source. Each group exposes its effective state through `aria-busy`.
|
|
147
|
+
|
|
148
|
+
Both toolbar and group accept these props; group appearance overrides the toolbar defaults:
|
|
149
|
+
|
|
150
|
+
| Prop | Type | Default | Description |
|
|
151
|
+
| :--- | :--- | :--- | :--- |
|
|
152
|
+
| `busy` | `boolean` | `false` | Adds externally managed activity. |
|
|
153
|
+
| `activityColors` | `readonly [string, string, string]` | `['#22d3ee', '#8b5cf6', '#ec4899']` | Three CSS colors for the gradient. |
|
|
154
|
+
| `activityDuration` | `number` | `2.4` | Seconds per rotation; non-positive or non-finite values fall back to 2.4. |
|
|
155
|
+
|
|
156
|
+
The effect follows circular and pill shapes without changing their dimensions. With `prefers-reduced-motion: reduce`, the border remains visible and static. Browsers without animated custom property support retain a static gradient; browsers without CSS masking retain a static colored border.
|
|
157
|
+
|
|
158
|
+
## Adaptive shapes
|
|
159
|
+
|
|
160
|
+
| Group content | Shape | Behavior |
|
|
161
|
+
| :--- | :--- | :--- |
|
|
162
|
+
| One child | Circle | Equal width and height, with centered content. The default diameter is 48px. |
|
|
163
|
+
| Multiple children | Pill | Fixed height, content-based width, horizontal spacing, and rounded ends. |
|
|
164
|
+
|
|
165
|
+
Use the `shape` prop on a group to override its automatic shape.
|
|
166
|
+
|
|
167
|
+
## API reference
|
|
168
|
+
|
|
169
|
+
### `<BubbleToolbar />`
|
|
170
|
+
|
|
171
|
+
| Prop | Type | Default | Description |
|
|
172
|
+
| :--- | :--- | :--- | :--- |
|
|
173
|
+
| `groups` | `ReactNode[][]` | `undefined` | Arrays of grouped nodes. |
|
|
174
|
+
| `children` | `ReactNode` | `undefined` | Children such as `<BubbleToolbar.Group>`. |
|
|
175
|
+
| `position` | `'bottom' \| 'top' \| 'static' \| 'custom'` | `'bottom'` | Toolbar placement. Use `style` to set custom positioning. |
|
|
176
|
+
| `theme` | `'glass' \| 'light' \| 'dark' \| 'auto'` | `'glass'` | Visual theme. |
|
|
177
|
+
| `size` | `'sm' \| 'md' \| 'lg' \| number` | `'md'` | Group height and circle diameter: 40px, 48px, 56px, or a custom pixel value. |
|
|
178
|
+
| `blurred` | `boolean` | `true` | Enables background blur. |
|
|
179
|
+
| `blurAmount` | `number \| string` | `16` | Blur radius in pixels or a CSS length. |
|
|
180
|
+
| `groupGap` | `number \| string` | `8` | Space between groups, in pixels or a CSS length. |
|
|
181
|
+
| `itemGap` | `number \| string` | `8` | Space between children within a pill. |
|
|
182
|
+
| `bordered` | `boolean` | `true` | Shows subtle borders. |
|
|
183
|
+
| `shadow` | `boolean \| string` | `true` | Enables the default shadow or supplies a custom CSS shadow. |
|
|
184
|
+
| `ariaLabel` | `string` | `'Toolbar'` | Accessible toolbar label. |
|
|
185
|
+
|
|
186
|
+
### `<BubbleGroup />` / `<BubbleToolbar.Group />`
|
|
187
|
+
|
|
188
|
+
| Prop | Type | Default | Description |
|
|
189
|
+
| :--- | :--- | :--- | :--- |
|
|
190
|
+
| `children` | `ReactNode` | `undefined` | Group content. |
|
|
191
|
+
| `shape` | `'circle' \| 'pill'` | Automatic | Overrides the shape inferred from the child count. |
|
|
192
|
+
| `size` | `'sm' \| 'md' \| 'lg' \| number` | Inherited | Overrides the toolbar's group size. |
|
|
193
|
+
| `itemGap` | `number \| string` | Inherited | Overrides spacing between children. |
|
|
194
|
+
|
|
195
|
+
### `<BubbleIconButton />`
|
|
196
|
+
|
|
197
|
+
| Prop | Type | Default | Description |
|
|
198
|
+
| :--- | :--- | :--- | :--- |
|
|
199
|
+
| `name` | `string` | `undefined` | Built-in icon: `search`, `theme`, `chat`, `notifications`, `logo`, or `close`. |
|
|
200
|
+
| `icon` | `ReactNode` | `undefined` | Custom icon content. |
|
|
201
|
+
| `badge` | `ReactNode` | `undefined` | Notification indicator or count. |
|
|
202
|
+
| `active` | `boolean` | `false` | Applies active styling. |
|
|
203
|
+
| `tooltip` | `string` | `undefined` | Tooltip and fallback accessible label. |
|
|
204
|
+
| `ariaLabel` | `string` | Derived | Explicit accessible label; falls back to the tooltip or icon name. |
|
|
205
|
+
|
|
206
|
+
### `<BubbleArea />`
|
|
207
|
+
|
|
208
|
+
| Prop | Type | Default | Description |
|
|
209
|
+
| :--- | :--- | :--- | :--- |
|
|
210
|
+
| `children` | `ReactNode` | `undefined` | Content such as a search input, label, or slider. |
|
|
211
|
+
| `minWidth` | `number \| string` | `120` | Minimum width in pixels or a CSS length. |
|
|
212
|
+
| `maxWidth` | `number \| string` | `undefined` | Maximum width in pixels or a CSS length. |
|
|
213
|
+
|
|
214
|
+
All components accept `className`, `style`, and standard attributes for their underlying element. Toolbar, group, and area refs point to a `div`; icon button refs point to a `button`.
|
|
215
|
+
|
|
216
|
+
## Development
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
npm ci
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
ESLint 10 uses `createEslintConfig` from `super-configs/eslint` with the React and Jest presets. Biome extends `super-configs/biome` for linting, formatting, and import organization.
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
npm run lint # Run ESLint with zero warnings allowed
|
|
226
|
+
npm run lint:fix # Apply ESLint fixes
|
|
227
|
+
npm run format:check # Check with Biome
|
|
228
|
+
npm run format # Apply Biome fixes
|
|
229
|
+
npm run typecheck # Check TypeScript types
|
|
230
|
+
npm test # Run Jest tests
|
|
231
|
+
npm run test:coverage # Generate a coverage report
|
|
232
|
+
npm run check # Run ESLint, Biome, TypeScript, and Jest
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Storybook
|
|
236
|
+
|
|
237
|
+
The story environment uses Storybook 10 and Vite 8.3.4. Explore components, themes, and adaptive shapes locally:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
npm run storybook
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Build the static Storybook site:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
npm run build-storybook
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Library build
|
|
250
|
+
|
|
251
|
+
Build the library for distribution as ESM, CommonJS, and TypeScript declarations:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
npm run build
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Preview the npm package contents:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
npm pack --dry-run
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Releases and deployment
|
|
264
|
+
|
|
265
|
+
The workflows follow the same release pattern as `react-dockbar` and `super-configs`:
|
|
266
|
+
|
|
267
|
+
- **CI:** pull requests and pushes to branches other than `main` run type checks, tests, and builds with React 18 and 19. React 19 also runs ESLint, Biome, Storybook, and a package-content check. Pull request commits are validated with commitlint.
|
|
268
|
+
- **npm:** after CI passes on `main`, semantic-release calculates the version, generates `CHANGELOG.md` and GitHub release notes, updates package versions, creates a `vX.Y.Z` tag, and publishes `bubble-toolbar` with provenance.
|
|
269
|
+
- **GitHub Packages:** each new npm release is mirrored as `@eljijuna/bubble-toolbar` from its release tag. The name change happens only in the publishing job.
|
|
270
|
+
- **GitHub Pages:** every validated push to `main` deploys Storybook to [eljijuna.github.io/bubble-toolbar](https://eljijuna.github.io/bubble-toolbar/), even when there is no new package release. Deployment is independent of npm publishing.
|
|
271
|
+
|
|
272
|
+
### Conventional Commits
|
|
273
|
+
|
|
274
|
+
Use `type(optional-scope): description` for commits and squash-merge titles:
|
|
275
|
+
|
|
276
|
+
| Commit | Version change |
|
|
277
|
+
| :--- | :--- |
|
|
278
|
+
| `fix: correct activity cleanup` | Patch |
|
|
279
|
+
| `perf: reduce activity renders` | Patch |
|
|
280
|
+
| `feat: add activity colors` | Minor |
|
|
281
|
+
| `feat!: replace the group API` | Major |
|
|
282
|
+
| Any type with a `BREAKING CHANGE:` footer | Major |
|
|
283
|
+
| `docs:`, `test:`, `chore:`, `ci:`, `build:`, `refactor:`, `style:` without breaking changes | No release by themselves |
|
|
284
|
+
|
|
285
|
+
The highest applicable change determines the release. Without a previous release tag, semantic-release starts at **1.0.0**. Release commits use `chore(release): X.Y.Z [skip ci]` to avoid a release loop. Do not edit release versions or changelog entries manually.
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
printf 'feat: add activity colors\n' | npm run commitlint
|
|
289
|
+
npm run release:dry-run
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
The dry run needs access to the GitHub repository and publishing credentials to verify permissions. It does not publish a version. Release tooling uses Node.js 24 in CI; use Node.js 24.15 or newer for local release tooling.
|
|
293
|
+
|
|
294
|
+
### Repository configuration
|
|
295
|
+
|
|
296
|
+
- Set the Actions secret `NPM_TOKEN` to an npm granular token with publish access to `bubble-toolbar`, allowing the CI publishing workflow to bypass 2FA. It must belong to an account authorized to publish the package name.
|
|
297
|
+
- Keep **Settings → Pages → Build and deployment → Source** set to **GitHub Actions**.
|
|
298
|
+
- The workflows declare the required `GITHUB_TOKEN` permissions for releases, package publishing, and Pages. If branch protection blocks release commits, allow the release automation to update `main` using an appropriate GitHub App token.
|
|
299
|
+
- The **Release** workflow can also be dispatched manually on `main`. To retry a failed mirror after npm succeeded, rerun the failed GitHub Packages job.
|
|
300
|
+
|
|
301
|
+
Install the mirror with an npm configuration that routes its scope to GitHub Packages:
|
|
302
|
+
|
|
303
|
+
```ini
|
|
304
|
+
@eljijuna:registry=https://npm.pkg.github.com
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
npm install @eljijuna/bubble-toolbar
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
GitHub Packages installation requires GitHub authentication with package read access. Publishing and deployment happen when the workflows run on GitHub; local setup does not publish packages.
|
|
312
|
+
|
|
313
|
+
## License
|
|
314
|
+
|
|
315
|
+
[MIT](./LICENSE) © ElJijuna
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes, ReactNode, CSSProperties, ButtonHTMLAttributes, ForwardRefExoticComponent, RefAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
interface BubbleActivityValue {
|
|
5
|
+
isBusy: boolean;
|
|
6
|
+
run: <T>(task: () => Promise<T>) => Promise<T>;
|
|
7
|
+
}
|
|
8
|
+
declare const useBubbleActivity: () => BubbleActivityValue;
|
|
9
|
+
|
|
10
|
+
type BubbleToolbarTheme = 'light' | 'dark' | 'auto' | 'glass';
|
|
11
|
+
type BubbleToolbarPosition = 'bottom' | 'top' | 'static' | 'custom';
|
|
12
|
+
type BubbleToolbarSize = 'sm' | 'md' | 'lg' | number;
|
|
13
|
+
type BubbleShape = 'circle' | 'pill';
|
|
14
|
+
/** Activity appearance inherited by each bubble group. */
|
|
15
|
+
interface BubbleActivityProps {
|
|
16
|
+
/** Adds external activity; false does not hide pending local tasks. */
|
|
17
|
+
busy?: boolean;
|
|
18
|
+
/** Three CSS colors used by the rotating activity border. */
|
|
19
|
+
activityColors?: readonly [string, string, string];
|
|
20
|
+
/** Seconds per rotation. Defaults to 2.4. */
|
|
21
|
+
activityDuration?: number;
|
|
22
|
+
}
|
|
23
|
+
interface BubbleToolbarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'>, BubbleActivityProps {
|
|
24
|
+
/**
|
|
25
|
+
* Definition of items by groups.
|
|
26
|
+
* Example:
|
|
27
|
+
* [
|
|
28
|
+
* [<Logo />],
|
|
29
|
+
* [<IconButton name="search" />, <ToolbarArea />],
|
|
30
|
+
* [<IconButton name="theme" />],
|
|
31
|
+
* [<IconButton name="chat" />],
|
|
32
|
+
* [<IconButton name="notifications" />]
|
|
33
|
+
* ]
|
|
34
|
+
*/
|
|
35
|
+
groups?: ReactNode[][];
|
|
36
|
+
/**
|
|
37
|
+
* Alternatively, declarative composition using BubbleToolbar.Group children.
|
|
38
|
+
*/
|
|
39
|
+
children?: ReactNode;
|
|
40
|
+
/**
|
|
41
|
+
* Placement on the screen.
|
|
42
|
+
* @default 'bottom'
|
|
43
|
+
*/
|
|
44
|
+
position?: BubbleToolbarPosition;
|
|
45
|
+
/**
|
|
46
|
+
* Visual theme styling.
|
|
47
|
+
* @default 'glass'
|
|
48
|
+
*/
|
|
49
|
+
theme?: BubbleToolbarTheme;
|
|
50
|
+
/**
|
|
51
|
+
* Toolbar height / bubble diameter.
|
|
52
|
+
* Preset 'sm' (40px), 'md' (48px), 'lg' (56px) or numeric pixels.
|
|
53
|
+
* @default 'md'
|
|
54
|
+
*/
|
|
55
|
+
size?: BubbleToolbarSize;
|
|
56
|
+
/**
|
|
57
|
+
* Whether to apply the blurred frosted glass effect (backdrop-filter: blur).
|
|
58
|
+
* @default true
|
|
59
|
+
*/
|
|
60
|
+
blurred?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Amount of backdrop blur in pixels or CSS string.
|
|
63
|
+
* @default 16
|
|
64
|
+
*/
|
|
65
|
+
blurAmount?: number | string;
|
|
66
|
+
/**
|
|
67
|
+
* Spacing between bubble groups.
|
|
68
|
+
* @default 8
|
|
69
|
+
*/
|
|
70
|
+
groupGap?: number | string;
|
|
71
|
+
/**
|
|
72
|
+
* Spacing between elements inside a multi-node pill group.
|
|
73
|
+
* @default 8
|
|
74
|
+
*/
|
|
75
|
+
itemGap?: number | string;
|
|
76
|
+
/**
|
|
77
|
+
* Whether to display subtle borders around bubbles.
|
|
78
|
+
* @default true
|
|
79
|
+
*/
|
|
80
|
+
bordered?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Whether to render floating shadow, or custom shadow CSS string.
|
|
83
|
+
* @default true
|
|
84
|
+
*/
|
|
85
|
+
shadow?: boolean | string;
|
|
86
|
+
/**
|
|
87
|
+
* Custom CSS class name for toolbar container.
|
|
88
|
+
*/
|
|
89
|
+
className?: string;
|
|
90
|
+
/**
|
|
91
|
+
* Inline CSS styles for toolbar container.
|
|
92
|
+
*/
|
|
93
|
+
style?: CSSProperties;
|
|
94
|
+
/**
|
|
95
|
+
* Accessible ARIA label for toolbar.
|
|
96
|
+
* @default 'Toolbar'
|
|
97
|
+
*/
|
|
98
|
+
ariaLabel?: string;
|
|
99
|
+
}
|
|
100
|
+
interface BubbleGroupProps extends HTMLAttributes<HTMLDivElement>, BubbleActivityProps {
|
|
101
|
+
/**
|
|
102
|
+
* Elements inside this group.
|
|
103
|
+
* 1 node renders as a circle.
|
|
104
|
+
* More than 1 node renders as a pill / rounded rectangle.
|
|
105
|
+
*/
|
|
106
|
+
children?: ReactNode;
|
|
107
|
+
/**
|
|
108
|
+
* Force shape instead of auto-calculating from children count.
|
|
109
|
+
*/
|
|
110
|
+
shape?: BubbleShape;
|
|
111
|
+
/**
|
|
112
|
+
* Override bubble size / height for this specific group.
|
|
113
|
+
*/
|
|
114
|
+
size?: BubbleToolbarSize;
|
|
115
|
+
/**
|
|
116
|
+
* Gap between items in this group.
|
|
117
|
+
*/
|
|
118
|
+
itemGap?: number | string;
|
|
119
|
+
/**
|
|
120
|
+
* Custom CSS class name.
|
|
121
|
+
*/
|
|
122
|
+
className?: string;
|
|
123
|
+
/**
|
|
124
|
+
* Inline CSS styles.
|
|
125
|
+
*/
|
|
126
|
+
style?: CSSProperties;
|
|
127
|
+
}
|
|
128
|
+
interface BubbleIconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
129
|
+
/**
|
|
130
|
+
* Icon identifier or label for standard icons.
|
|
131
|
+
*/
|
|
132
|
+
name?: string;
|
|
133
|
+
/**
|
|
134
|
+
* Custom icon element or SVG.
|
|
135
|
+
*/
|
|
136
|
+
icon?: ReactNode;
|
|
137
|
+
/**
|
|
138
|
+
* Active or toggled state.
|
|
139
|
+
* @default false
|
|
140
|
+
*/
|
|
141
|
+
active?: boolean;
|
|
142
|
+
/**
|
|
143
|
+
* Optional badge count or indicator.
|
|
144
|
+
*/
|
|
145
|
+
badge?: ReactNode | number | string;
|
|
146
|
+
/**
|
|
147
|
+
* Tooltip text.
|
|
148
|
+
*/
|
|
149
|
+
tooltip?: string;
|
|
150
|
+
/**
|
|
151
|
+
* Explicit accessible label.
|
|
152
|
+
*/
|
|
153
|
+
ariaLabel?: string;
|
|
154
|
+
}
|
|
155
|
+
interface BubbleAreaProps extends HTMLAttributes<HTMLDivElement> {
|
|
156
|
+
/**
|
|
157
|
+
* Content inside the toolbar area (e.g. search input, label, sliders).
|
|
158
|
+
*/
|
|
159
|
+
children?: ReactNode;
|
|
160
|
+
/**
|
|
161
|
+
* Minimum width for the area.
|
|
162
|
+
*/
|
|
163
|
+
minWidth?: number | string;
|
|
164
|
+
/**
|
|
165
|
+
* Maximum width for the area.
|
|
166
|
+
*/
|
|
167
|
+
maxWidth?: number | string;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
declare const BubbleGroup: react.ForwardRefExoticComponent<BubbleGroupProps & react.RefAttributes<HTMLDivElement>>;
|
|
171
|
+
|
|
172
|
+
interface BubbleToolbarComponent extends ForwardRefExoticComponent<BubbleToolbarProps & RefAttributes<HTMLDivElement>> {
|
|
173
|
+
Group: typeof BubbleGroup;
|
|
174
|
+
}
|
|
175
|
+
declare const BubbleToolbar: BubbleToolbarComponent;
|
|
176
|
+
|
|
177
|
+
declare const BubbleArea: react.ForwardRefExoticComponent<BubbleAreaProps & react.RefAttributes<HTMLDivElement>>;
|
|
178
|
+
|
|
179
|
+
declare const BubbleIconButton: react.ForwardRefExoticComponent<BubbleIconButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
180
|
+
|
|
181
|
+
interface BubbleToolbarContextValue extends BubbleActivityProps {
|
|
182
|
+
size: BubbleToolbarSize;
|
|
183
|
+
theme: BubbleToolbarTheme;
|
|
184
|
+
blurred: boolean;
|
|
185
|
+
blurAmount: number | string;
|
|
186
|
+
itemGap: number | string;
|
|
187
|
+
bordered: boolean;
|
|
188
|
+
shadow: boolean | string;
|
|
189
|
+
}
|
|
190
|
+
declare const BubbleToolbarContext: react.Context<BubbleToolbarContextValue>;
|
|
191
|
+
declare const useBubbleToolbar: () => BubbleToolbarContextValue;
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Returns an array of non-null, non-undefined, non-boolean child elements.
|
|
195
|
+
* Unpacks Fragment if encountered at the top level.
|
|
196
|
+
*/
|
|
197
|
+
declare function getValidChildren(children: ReactNode): ReactNode[];
|
|
198
|
+
|
|
199
|
+
declare function resolveSize(size: BubbleToolbarSize): number;
|
|
200
|
+
declare function formatPx(val: number | string): string;
|
|
201
|
+
declare function getGlassStyles(theme: BubbleToolbarTheme, blurred: boolean, blurAmount: number | string, bordered: boolean, shadow: boolean | string): CSSProperties;
|
|
202
|
+
|
|
203
|
+
export { type BubbleActivityProps, type BubbleActivityValue, BubbleArea, type BubbleAreaProps, BubbleGroup, type BubbleGroupProps, BubbleIconButton, type BubbleIconButtonProps, type BubbleShape, BubbleToolbar, type BubbleToolbarComponent, BubbleToolbarContext, type BubbleToolbarPosition, type BubbleToolbarProps, type BubbleToolbarSize, type BubbleToolbarTheme, formatPx, getGlassStyles, getValidChildren, resolveSize, useBubbleActivity, useBubbleToolbar };
|