@emiketic/lib-mantine 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/README.md +319 -0
- package/dist/index.cjs +663 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +113 -0
- package/dist/index.d.ts +113 -0
- package/dist/index.js +625 -0
- package/dist/index.js.map +1 -0
- package/package.json +77 -0
package/README.md
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# @emiketic/lib-mantine
|
|
2
|
+
|
|
3
|
+
A collection of handy components built on [Mantine v9](https://mantine.dev) components.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @emiketic/lib-mantine
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Peer dependencies
|
|
12
|
+
|
|
13
|
+
Make sure the following are installed in your project:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install react react-dom @mantine/core @tabler/icons-react
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### CSS
|
|
20
|
+
|
|
21
|
+
Import Mantine's base CSS in your app entry point (e.g. `_app.tsx` or `layout.tsx`):
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import '@mantine/core/styles.css';
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
For `TextEditor`, also import:
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import '@mantine/tiptap/styles.css';
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Components
|
|
36
|
+
|
|
37
|
+
### `ClientOnly`
|
|
38
|
+
|
|
39
|
+
Prevents SSR hydration mismatches by rendering children only after the component mounts on the client.
|
|
40
|
+
|
|
41
|
+
| Prop | Type | Default | Description |
|
|
42
|
+
|---|---|---|---|
|
|
43
|
+
| `children` | `ReactNode` | — | Content to render |
|
|
44
|
+
| `withLoader` | `boolean` | `false` | Show a `LoadingOverlay` while waiting for mount |
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { ClientOnly } from '@emiketic/lib-mantine';
|
|
48
|
+
|
|
49
|
+
<ClientOnly>
|
|
50
|
+
<MyClientSideWidget />
|
|
51
|
+
</ClientOnly>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
### `ConfirmBar`
|
|
57
|
+
|
|
58
|
+
A form action bar with Confirm and Cancel buttons, typically placed at the bottom of a form.
|
|
59
|
+
|
|
60
|
+
| Prop | Type | Default | Description |
|
|
61
|
+
|---|---|---|---|
|
|
62
|
+
| `onConfirm` | `() => void` | — | Called when the confirm button is clicked |
|
|
63
|
+
| `onCancel` | `() => void` | `() => {}` | Called when the cancel button is clicked |
|
|
64
|
+
| `disabled` | `boolean` | `false` | Disables the confirm button |
|
|
65
|
+
| `loading` | `boolean` | `false` | Shows a loading spinner on the confirm button |
|
|
66
|
+
| `color` | `MantineColor` | — | Color of the confirm button |
|
|
67
|
+
| `withCancel` | `boolean` | `true` | Whether to show the cancel button |
|
|
68
|
+
| `labelProps` | `{ confirm?: string; cancel?: string }` | — | Custom button labels |
|
|
69
|
+
|
|
70
|
+
Also accepts all `BoxProps` from Mantine.
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
import { ConfirmBar } from '@emiketic/lib-mantine';
|
|
74
|
+
|
|
75
|
+
<ConfirmBar
|
|
76
|
+
onConfirm={handleSubmit}
|
|
77
|
+
onCancel={handleReset}
|
|
78
|
+
labelProps={{ confirm: 'Save', cancel: 'Discard' }}
|
|
79
|
+
color="blue"
|
|
80
|
+
/>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### `ContentLoader`
|
|
86
|
+
|
|
87
|
+
A skeleton loading placeholder made up of animated skeleton bars. Useful as a page-level or section-level loading state.
|
|
88
|
+
|
|
89
|
+
| Prop | Type | Default | Description |
|
|
90
|
+
|---|---|---|---|
|
|
91
|
+
| `numberOfBars` | `number` | `3` | Total skeleton bars across all groups |
|
|
92
|
+
| `numberOfBarGroups` | `number` | `3` | Number of bar groups (adds spacing between groups) |
|
|
93
|
+
| `barHeight` | `number` | `15` | Height of each skeleton bar in px |
|
|
94
|
+
| `barSpacing` | `number` | `6` | Vertical spacing between bars in px |
|
|
95
|
+
| `barGroupSpacing` | `MantineSpacing` | `'lg'` | Space between bar groups |
|
|
96
|
+
| `visible` | `boolean` | `true` | When `false`, renders nothing |
|
|
97
|
+
| `withCircle` | `boolean` | `false` | Add a circular skeleton (e.g. for avatar) at the top |
|
|
98
|
+
|
|
99
|
+
Also accepts all `StackProps` from Mantine.
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
import { ContentLoader } from '@emiketic/lib-mantine';
|
|
103
|
+
|
|
104
|
+
<ContentLoader visible={isLoading} withCircle />
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
### `ImageInput`
|
|
110
|
+
|
|
111
|
+
A file input with an inline image preview. Supports both `File` objects and URL strings as value.
|
|
112
|
+
|
|
113
|
+
| Prop | Type | Default | Description |
|
|
114
|
+
|---|---|---|---|
|
|
115
|
+
| `value` | `File \| string \| null` | — | Current value (controlled) |
|
|
116
|
+
| `withPreview` | `boolean` | `true` | Show image thumbnail next to the input |
|
|
117
|
+
| `previewProps` | `ImageProps` | — | Props forwarded to the preview `<Image>` |
|
|
118
|
+
| `disabledPlaceholderProps` | `AvatarProps` | — | Props for the `<Avatar>` shown when disabled |
|
|
119
|
+
| `maxFileSizeBytes` | `number` | `500_000` | Max file size before showing a warning (bytes) |
|
|
120
|
+
|
|
121
|
+
Also accepts all `FileInputProps` from Mantine (except `value`).
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
import { ImageInput } from '@emiketic/lib-mantine';
|
|
125
|
+
|
|
126
|
+
const [file, setFile] = useState<File | null>(null);
|
|
127
|
+
|
|
128
|
+
<ImageInput
|
|
129
|
+
label="Logo"
|
|
130
|
+
value={file}
|
|
131
|
+
onChange={setFile}
|
|
132
|
+
maxFileSizeBytes={2_000_000}
|
|
133
|
+
/>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
### `Logo`
|
|
139
|
+
|
|
140
|
+
An avatar-style component for displaying a business/brand logo. Optionally extracts the dominant color from the image and uses it as a background, creating a visually consistent color pair. Falls back to a building icon when no image is provided.
|
|
141
|
+
|
|
142
|
+
Requires `@emiketic/lib-utils` (installed automatically as a dependency).
|
|
143
|
+
|
|
144
|
+
| Prop | Type | Default | Description |
|
|
145
|
+
|---|---|---|---|
|
|
146
|
+
| `withColorPair` | `boolean` | `true` | Extract dominant color from image for background |
|
|
147
|
+
|
|
148
|
+
Also accepts all `AvatarProps` from Mantine.
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
import { Logo } from '@emiketic/lib-mantine';
|
|
152
|
+
|
|
153
|
+
<Logo src="https://example.com/logo.png" withColorPair />
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
### `NativePDFViewer`
|
|
159
|
+
|
|
160
|
+
Renders a PDF file using the browser's native `<object>` tag with per-browser toolbar height correction. Handles Safari, Edge, Firefox, and Chromium-based browsers.
|
|
161
|
+
|
|
162
|
+
| Prop | Type | Default | Description |
|
|
163
|
+
|---|---|---|---|
|
|
164
|
+
| `mediaUrl` | `string` | — | URL of the PDF file |
|
|
165
|
+
| `title` | `string` | — | Accessible title for the object element |
|
|
166
|
+
| `zoomLevel` | `number` | — | Initial zoom percentage |
|
|
167
|
+
| `withToolbar` | `boolean` | `true` | Whether to show the browser's PDF toolbar |
|
|
168
|
+
| `fallback` | `ReactNode \| () => ReactNode` | Default message | Shown when the browser can't render PDFs |
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
import { NativePDFViewer } from '@emiketic/lib-mantine';
|
|
172
|
+
|
|
173
|
+
<div style={{ height: '600px' }}>
|
|
174
|
+
<NativePDFViewer mediaUrl="/files/report.pdf" withToolbar={false} />
|
|
175
|
+
</div>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
### `NoData`
|
|
181
|
+
|
|
182
|
+
A centered empty-state component using Mantine's `Alert`. Useful for lists, tables, or search results with no entries.
|
|
183
|
+
|
|
184
|
+
| Prop | Type | Default | Description |
|
|
185
|
+
|---|---|---|---|
|
|
186
|
+
| `title` | `string` | `'No data'` | Title shown in the alert |
|
|
187
|
+
| `alertProps` | `AlertProps` | — | Props forwarded to the `<Alert>` |
|
|
188
|
+
| `children` | `ReactNode` | — | Optional content below the title (e.g. a CTA) |
|
|
189
|
+
|
|
190
|
+
Also accepts all `CenterProps` from Mantine.
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import { NoData } from '@emiketic/lib-mantine';
|
|
194
|
+
|
|
195
|
+
<NoData title="No reviews yet">
|
|
196
|
+
<Button>Be the first to review</Button>
|
|
197
|
+
</NoData>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
### `PageContainer`
|
|
203
|
+
|
|
204
|
+
A flexible page layout wrapper with optional title, header, right section, and scrollable content area. Useful for panel/dashboard-style pages.
|
|
205
|
+
|
|
206
|
+
| Prop | Type | Default | Description |
|
|
207
|
+
|---|---|---|---|
|
|
208
|
+
| `title` | `string` | — | Page title rendered as `<h2>` |
|
|
209
|
+
| `titleProps` | `TitleProps` | — | Props forwarded to `<Title>` |
|
|
210
|
+
| `header` | `ReactNode` | — | Custom header — overrides the default title + right section layout |
|
|
211
|
+
| `headerProps` | `GroupProps` | — | Props for the default header `<Group>` |
|
|
212
|
+
| `rightSection` | `ReactNode` | `null` | Rendered in the top-right corner of the header |
|
|
213
|
+
| `fullPage` | `boolean` | `false` | Removes the header and padding — just wraps content in a `<Box>` |
|
|
214
|
+
| `withContentScroll` | `boolean` | `false` | Makes the container a full-height `ScrollArea` |
|
|
215
|
+
| `contentProps` | `StackProps \| BoxProps` | — | Props for the inner content wrapper |
|
|
216
|
+
| `outerContentProps` | `StackProps` | — | Props for the outer content wrapper |
|
|
217
|
+
|
|
218
|
+
Also accepts all `ScrollAreaProps` from Mantine (used when `withContentScroll` is `true`).
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
import { PageContainer } from '@emiketic/lib-mantine';
|
|
222
|
+
|
|
223
|
+
<PageContainer title="Users" rightSection={<Button>Add user</Button>}>
|
|
224
|
+
<UserTable />
|
|
225
|
+
</PageContainer>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
### `PhoneInput`
|
|
231
|
+
|
|
232
|
+
An international phone number input combining a searchable country code selector with a phone number text input. Validates and normalizes to E.164 format using `libphonenumber-js`.
|
|
233
|
+
|
|
234
|
+
| Prop | Type | Default | Description |
|
|
235
|
+
|---|---|---|---|
|
|
236
|
+
| `value` | `string` | — | Phone number in E.164 format (e.g. `+21698765432`) |
|
|
237
|
+
| `defaultValue` | `string` | — | Uncontrolled initial value |
|
|
238
|
+
| `defaultCountryCode` | `CountryCode` | — | Pre-select a country code (e.g. `'TN'`, `'FR'`) |
|
|
239
|
+
| `onChange` | `(value: string) => void` | — | Called with the full E.164 number when valid |
|
|
240
|
+
|
|
241
|
+
Also accepts all `TextInputProps` from Mantine (except `onChange`).
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
import { PhoneInput } from '@emiketic/lib-mantine';
|
|
245
|
+
|
|
246
|
+
const [phone, setPhone] = useState('');
|
|
247
|
+
|
|
248
|
+
<PhoneInput
|
|
249
|
+
label="Mobile"
|
|
250
|
+
defaultCountryCode="FR"
|
|
251
|
+
value={phone}
|
|
252
|
+
onChange={setPhone}
|
|
253
|
+
/>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
### `TextEditor`
|
|
259
|
+
|
|
260
|
+
A rich text editor built on [Tiptap](https://tiptap.dev) and [`@mantine/tiptap`](https://mantine.dev/x/tiptap/). Includes a sticky toolbar with formatting controls (bold, italic, headings, lists, links, alignment, etc.).
|
|
261
|
+
|
|
262
|
+
Requires importing `@mantine/tiptap/styles.css` in your app.
|
|
263
|
+
|
|
264
|
+
| Prop | Type | Default | Description |
|
|
265
|
+
|---|---|---|---|
|
|
266
|
+
| `content` | `string` | — | Initial HTML content |
|
|
267
|
+
| `value` | `string` | — | Alias for `content` |
|
|
268
|
+
| `onChangeEditorHTML` | `(html?: string) => void` | `() => {}` | Called with the current HTML on every change |
|
|
269
|
+
| `onChange` | `(html?: string) => void` | `() => {}` | Alias for `onChangeEditorHTML` |
|
|
270
|
+
|
|
271
|
+
Also accepts all `RichTextEditorProps` from `@mantine/tiptap` (except `editor`).
|
|
272
|
+
|
|
273
|
+
```tsx
|
|
274
|
+
import { TextEditor } from '@emiketic/lib-mantine';
|
|
275
|
+
import '@mantine/tiptap/styles.css';
|
|
276
|
+
|
|
277
|
+
<TextEditor
|
|
278
|
+
content="<p>Initial content</p>"
|
|
279
|
+
onChangeEditorHTML={(html) => setBody(html)}
|
|
280
|
+
/>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
### `ThemeToggle`
|
|
286
|
+
|
|
287
|
+
A dark/light mode switch using Mantine's color scheme system. Wraps a `Switch` in a tooltip and a `ClientOnly` boundary.
|
|
288
|
+
|
|
289
|
+
| Prop | Type | Default | Description |
|
|
290
|
+
|---|---|---|---|
|
|
291
|
+
| `size` | `MantineSize` | `'md'` | Size of the switch and icon |
|
|
292
|
+
|
|
293
|
+
Also accepts all `SwitchProps` from Mantine.
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
import { ThemeToggle } from '@emiketic/lib-mantine';
|
|
297
|
+
|
|
298
|
+
<ThemeToggle />
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
> Requires your app to use Mantine's `MantineProvider` with `colorSchemeManager` configured.
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Storybook
|
|
306
|
+
|
|
307
|
+
Run the local Storybook to preview all components interactively:
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
npm run storybook
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Opens at [http://localhost:6007](http://localhost:6007).
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## License
|
|
318
|
+
|
|
319
|
+
MIT © [Emiketic](https://emiketic.com)
|