jattac.libs.web.zest-button 1.3.0 → 1.5.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/LICENSE +21 -0
- package/README.md +10 -9
- package/dist/ZestButton.d.ts +23 -2
- package/dist/ZestDropdownMenu.d.ts +20 -0
- package/dist/ZestDropdownMenuItem.d.ts +9 -0
- package/dist/index.cjs.js +192 -7
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.esm.js +175 -9
- package/dist/index.esm.js.map +1 -1
- package/{docs → documentation}/api.md +25 -0
- package/{docs → documentation}/examples.md +62 -0
- package/{docs → documentation}/features.md +24 -0
- package/package.json +79 -69
- package/dist/ZestContext.d.ts +0 -9
- package/dist/ZestProvider.d.ts +0 -8
- package/dist/semanticTypeDefaults.d.ts +0 -4
- /package/{docs → documentation}/breaking-changes.md +0 -0
- /package/{docs → documentation}/configuration.md +0 -0
- /package/{docs → documentation}/development.md +0 -0
|
@@ -18,6 +18,7 @@ This document provides an exhaustive reference for all `ZestButton` props and ty
|
|
|
18
18
|
- [SuccessOptions](#successoptions)
|
|
19
19
|
- [ConfirmOptions](#confirmoptions)
|
|
20
20
|
- [SemanticType](#semantictype)
|
|
21
|
+
- [ZestDropdownOption](#zestdropdownoption)
|
|
21
22
|
|
|
22
23
|
---
|
|
23
24
|
|
|
@@ -50,6 +51,10 @@ This is the main configuration object passed to the `zest` prop.
|
|
|
50
51
|
| `theme` | `'light' \| 'dark' \| 'system'` | `'system'` | Overrides the automatic theme detection. |
|
|
51
52
|
| `buttonStyle` | `'solid' \| 'outline' \| 'text' \| 'dashed'`| `'solid'` | Defines the visual style of the button. |
|
|
52
53
|
| `semanticType` | `SemanticType` | `undefined` | Defines the semantic type of the button, providing default visuals and behaviors. Extensible via module augmentation. |
|
|
54
|
+
| `dropdownOptions` | `ZestDropdownOption[]` | `undefined` | If provided (non-empty), renders the button as a split button: the main action on the left, and a chevron on the right that opens a menu of these options. See [`ZestDropdownOption`](#zestdropdownoption). |
|
|
55
|
+
| `dropdownAriaLabel` | `string` | `'More options'` | Accessible name for the chevron trigger button (it has no visible text). |
|
|
56
|
+
| `dropdownTheme` | `'light' \| 'dark' \| 'system'` | `'light'` | Theme for the dropdown menu panel, independent of the button's own `theme`. Menus default to light regardless of the button's theme; set this to theme the menu to match. |
|
|
57
|
+
| `dropdownWidth` | `number \| string` | `undefined` | Minimum width for the dropdown menu panel — a number is treated as pixels, a string is used as a raw CSS length (e.g. `'18rem'`). When unset, the menu's minimum width tracks the rendered width of the whole split button control. |
|
|
53
58
|
|
|
54
59
|
---
|
|
55
60
|
|
|
@@ -137,4 +142,24 @@ After augmentation, `'archive'` and `'publish'` would be valid `SemanticType` va
|
|
|
137
142
|
|
|
138
143
|
---
|
|
139
144
|
|
|
145
|
+
#### `ZestDropdownOption`
|
|
146
|
+
|
|
147
|
+
Describes a single secondary action in a split button's dropdown menu (see [`dropdownOptions`](#zestcustomprops)). Each option runs through the same busy/confirm machinery as the main button, independently per item.
|
|
148
|
+
|
|
149
|
+
| Prop Name | Type | Default | Description |
|
|
150
|
+
| :--- | :--- | :--- | :--- |
|
|
151
|
+
| `key` | `string` | index | Stable React key. Defaults to the option's index in the array if omitted. |
|
|
152
|
+
| `label` | `React.ReactNode` | **(Required)** | The menu item's visible content. |
|
|
153
|
+
| `icon` | `React.ReactNode` | `undefined` | An icon to display to the left of the label. |
|
|
154
|
+
| `disabled` | `boolean` | `false` | If true, the item cannot be selected. |
|
|
155
|
+
| `semanticType` | `SemanticType` | `undefined` | Same as the main button's `semanticType` — provides default icon/behavior for this item. |
|
|
156
|
+
| `onClick` | `(e: Event) => void \| Promise<void>` | `undefined` | Handler invoked when the item is selected. |
|
|
157
|
+
| `busyOptions` | `BusyOptions` | `{}` | Same shape as the main button's `busyOptions`, scoped to this item. |
|
|
158
|
+
| `successOptions` | `SuccessOptions` | `{}` | Same shape as the main button's `successOptions`, scoped to this item. |
|
|
159
|
+
| `confirmOptions` | `ConfirmOptions` | `undefined` | Same shape as the main button's `confirmOptions`, scoped to this item. |
|
|
160
|
+
|
|
161
|
+
*See the [Split Button with Overflow Actions recipe](./examples.md#recipe-5-a-split-button-with-overflow-actions) for a full example.*
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
140
165
|
[⬅️ Previous: Features Showcase](./features.md) | [Next: Configuration Guide ➡️](./configuration.md)
|
|
@@ -10,6 +10,7 @@ Welcome to the ZestButton Cookbook! This is the core learning path for mastering
|
|
|
10
10
|
- [Recipe 2: The Safe "Delete" Button](#recipe-2-the-safe-delete-button)
|
|
11
11
|
- [Recipe 3: Standardizing Your Buttons with a Global Config](#recipe-3-standardizing-your-buttons-with-a-global-config)
|
|
12
12
|
- [Recipe 4: Creating a Custom "Archive" Button](#recipe-4-creating-a-custom-archive-button)
|
|
13
|
+
- [Recipe 5: A Split Button with Overflow Actions](#recipe-5-a-split-button-with-overflow-actions)
|
|
13
14
|
|
|
14
15
|
---
|
|
15
16
|
|
|
@@ -224,4 +225,65 @@ This powerful pattern allows you to build a complete, consistent design system f
|
|
|
224
225
|
|
|
225
226
|
---
|
|
226
227
|
|
|
228
|
+
### Recipe 5: A Split Button with Overflow Actions
|
|
229
|
+
|
|
230
|
+
**Goal:** Create a button with one obvious default action ("Export as CSV") plus a few situational alternatives ("Export as PDF", "Export as JSON"), without cluttering the UI with three separate buttons.
|
|
231
|
+
|
|
232
|
+
**Problem:** You have a primary action and a handful of related, less-common actions. Placing them all as top-level buttons crowds the UI; hiding all of them behind a menu makes the primary action less discoverable and adds an extra click for the common case.
|
|
233
|
+
|
|
234
|
+
**Solution:** Pass `dropdownOptions` in `zest`. `ZestButton` renders as two visually-fused segments: the main action (left) fires immediately on click, exactly like a normal `ZestButton`, while the chevron (right) opens a menu of the extra options. Each option is independent — it can have its own icon, `busyOptions`, `successOptions`, or `confirmOptions`, running through the same machinery as the main button.
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
import React from 'react';
|
|
238
|
+
import ZestButton from 'jattac.libs.web.zest-button';
|
|
239
|
+
import { FaFileCsv, FaFilePdf, FaFileCode, FaTrash } from 'react-icons/fa6';
|
|
240
|
+
|
|
241
|
+
const ExportButton = () => {
|
|
242
|
+
const exportAs = (format: string) => async () => {
|
|
243
|
+
await new Promise((resolve) => setTimeout(resolve, 800));
|
|
244
|
+
alert(`Exported as ${format}!`);
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
return (
|
|
248
|
+
<ZestButton
|
|
249
|
+
onClick={exportAs('CSV')}
|
|
250
|
+
zest={{
|
|
251
|
+
visualOptions: { iconLeft: <FaFileCsv /> },
|
|
252
|
+
dropdownOptions: [
|
|
253
|
+
{ label: 'Export as PDF', icon: <FaFilePdf />, onClick: exportAs('PDF') },
|
|
254
|
+
{ label: 'Export as JSON', icon: <FaFileCode />, onClick: exportAs('JSON') },
|
|
255
|
+
{
|
|
256
|
+
label: 'Delete export history',
|
|
257
|
+
icon: <FaTrash />,
|
|
258
|
+
onClick: async () => alert('History cleared.'),
|
|
259
|
+
confirmOptions: { displayLabel: 'Confirm Delete', timeoutSecs: 5 },
|
|
260
|
+
},
|
|
261
|
+
],
|
|
262
|
+
}}
|
|
263
|
+
>
|
|
264
|
+
Export as CSV
|
|
265
|
+
</ZestButton>
|
|
266
|
+
);
|
|
267
|
+
};
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Theming and sizing the menu independently:** the dropdown menu panel defaults to a light theme and a minimum width matching the whole split button, regardless of the main button's own `theme`. Both are configurable, either per-button or app-wide via `ZestButtonConfigProvider`'s `defaultProps`:
|
|
271
|
+
|
|
272
|
+
```tsx
|
|
273
|
+
<ZestButton
|
|
274
|
+
zest={{
|
|
275
|
+
theme: 'dark',
|
|
276
|
+
dropdownTheme: 'dark', // theme the menu to match, instead of the light default
|
|
277
|
+
dropdownWidth: '16rem', // force a specific minimum width instead of matching the button
|
|
278
|
+
dropdownOptions: [{ label: 'Export as PDF', onClick: exportAs('PDF') }],
|
|
279
|
+
}}
|
|
280
|
+
>
|
|
281
|
+
Export as CSV
|
|
282
|
+
</ZestButton>
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
*For the full prop reference, see [`dropdownOptions`](./api.md#zestcustomprops) and [`ZestDropdownOption`](./api.md#zestdropdownoption) in our API reference.*
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
227
289
|
[⬅️ Previous: README](../README.md) | [Next: Features Showcase ➡️](./features.md)
|
|
@@ -11,6 +11,7 @@ This document provides a high-level showcase of what's possible with `ZestButton
|
|
|
11
11
|
- [Semantic Types](#semantic-types)
|
|
12
12
|
- [Global Configuration](#global-configuration)
|
|
13
13
|
- [Rich Styling](#rich-styling)
|
|
14
|
+
- [Split Buttons & Overflow Menus](#split-buttons--overflow-menus)
|
|
14
15
|
|
|
15
16
|
---
|
|
16
17
|
|
|
@@ -123,4 +124,27 @@ const MyComponent = () => (
|
|
|
123
124
|
|
|
124
125
|
---
|
|
125
126
|
|
|
127
|
+
### Split Buttons & Overflow Menus
|
|
128
|
+
|
|
129
|
+
**What it does:** Attaches a set of secondary actions to a button that already has one obvious default action, via a chevron segment that opens a menu — a discoverable place for "there's more here" without cluttering the UI with extra buttons. Each menu item gets its own independent busy/success/fail/confirm feedback, and the menu can be themed and sized independently of the main button.
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
const MyComponent = () => (
|
|
133
|
+
<ZestButton
|
|
134
|
+
onClick={() => alert('Exported as CSV!')}
|
|
135
|
+
zest={{
|
|
136
|
+
dropdownOptions: [
|
|
137
|
+
{ label: 'Export as PDF', onClick: () => alert('Exported as PDF!') },
|
|
138
|
+
{ label: 'Export as JSON', onClick: () => alert('Exported as JSON!') },
|
|
139
|
+
],
|
|
140
|
+
}}
|
|
141
|
+
>
|
|
142
|
+
Export as CSV
|
|
143
|
+
</ZestButton>
|
|
144
|
+
);
|
|
145
|
+
```
|
|
146
|
+
*__Learn more in the [Split Button with Overflow Actions recipe](./examples.md#recipe-5-a-split-button-with-overflow-actions).__*
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
126
150
|
[⬅️ Previous: The Cookbook (Examples)](./examples.md) | [Next: API Reference ➡️](./api.md)
|
package/package.json
CHANGED
|
@@ -1,69 +1,79 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "jattac.libs.web.zest-button",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "A highly customizable and production-ready React button component featuring robust asynchronous handling, rich visual feedback, and built-in confirmation flows for enhanced user experience",
|
|
5
|
-
"homepage": "https://github.com/nyingimaina/jattac.libs.web.zest-button#readme",
|
|
6
|
-
"repository": {
|
|
7
|
-
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/nyingimaina/jattac.libs.web.zest-button.git"
|
|
9
|
-
},
|
|
10
|
-
"bugs": {
|
|
11
|
-
"url": "https://github.com/nyingimaina/jattac.libs.web.zest-button/issues"
|
|
12
|
-
},
|
|
13
|
-
"main": "dist/index.cjs.js",
|
|
14
|
-
"module": "dist/index.esm.js",
|
|
15
|
-
"types": "dist/index.d.ts",
|
|
16
|
-
"files": [
|
|
17
|
-
"dist",
|
|
18
|
-
"README.md",
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
"react-
|
|
50
|
-
"react
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"@
|
|
56
|
-
"@
|
|
57
|
-
"@
|
|
58
|
-
"@
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "jattac.libs.web.zest-button",
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"description": "A highly customizable and production-ready React button component featuring robust asynchronous handling, rich visual feedback, and built-in confirmation flows for enhanced user experience",
|
|
5
|
+
"homepage": "https://github.com/nyingimaina/jattac.libs.web.zest-button#readme",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/nyingimaina/jattac.libs.web.zest-button.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/nyingimaina/jattac.libs.web.zest-button/issues"
|
|
12
|
+
},
|
|
13
|
+
"main": "dist/index.cjs.js",
|
|
14
|
+
"module": "dist/index.esm.js",
|
|
15
|
+
"types": "dist/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"documentation"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "rollup -c rollup.config.mjs",
|
|
24
|
+
"dev": "rollup -c rollup.config.mjs -w",
|
|
25
|
+
"test": "jest --coverage"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"react",
|
|
29
|
+
"button",
|
|
30
|
+
"ui",
|
|
31
|
+
"component",
|
|
32
|
+
"interactive",
|
|
33
|
+
"react-button",
|
|
34
|
+
"form",
|
|
35
|
+
"web",
|
|
36
|
+
"async",
|
|
37
|
+
"loading",
|
|
38
|
+
"confirmation",
|
|
39
|
+
"feedback",
|
|
40
|
+
"animation",
|
|
41
|
+
"transitions",
|
|
42
|
+
"ux",
|
|
43
|
+
"zest",
|
|
44
|
+
"jattac"
|
|
45
|
+
],
|
|
46
|
+
"author": "Jattac",
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"@radix-ui/react-dropdown-menu": "^2.1.24",
|
|
50
|
+
"react": ">=16.8.0",
|
|
51
|
+
"react-dom": ">=16.8.0",
|
|
52
|
+
"react-icons": "^5.0.1"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@radix-ui/react-dropdown-menu": "^2.1.24",
|
|
56
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
57
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
58
|
+
"@rollup/plugin-typescript": "^11.1.6",
|
|
59
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
60
|
+
"@testing-library/react": "^16.3.2",
|
|
61
|
+
"@types/jest": "^30.0.0",
|
|
62
|
+
"@types/node": "^25.1.0",
|
|
63
|
+
"@types/react": "^18.2.67",
|
|
64
|
+
"@types/react-dom": "^18.2.22",
|
|
65
|
+
"identity-obj-proxy": "^3.0.0",
|
|
66
|
+
"jest": "^30.4.2",
|
|
67
|
+
"jest-environment-jsdom": "^30.4.1",
|
|
68
|
+
"postcss": "^8.4.38",
|
|
69
|
+
"postcss-modules": "6.0.1",
|
|
70
|
+
"react": "^18.2.0",
|
|
71
|
+
"react-dom": "^18.2.0",
|
|
72
|
+
"rollup": "^4.13.0",
|
|
73
|
+
"rollup-plugin-dts": "^6.1.0",
|
|
74
|
+
"rollup-plugin-postcss": "^4.0.2",
|
|
75
|
+
"ts-jest": "^29.4.12",
|
|
76
|
+
"tslib": "^2.6.2",
|
|
77
|
+
"typescript": "^5.4.2"
|
|
78
|
+
}
|
|
79
|
+
}
|
package/dist/ZestContext.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { ZestCustomProps } from './ZestButton';
|
|
3
|
-
export interface ZestGlobalConfig {
|
|
4
|
-
defaultProps?: ZestCustomProps;
|
|
5
|
-
semanticTypeDefaults?: Partial<Record<string, Partial<ZestCustomProps>>>;
|
|
6
|
-
}
|
|
7
|
-
declare const ZestContext: React.Context<ZestGlobalConfig | undefined>;
|
|
8
|
-
export declare const useZest: () => ZestGlobalConfig | undefined;
|
|
9
|
-
export default ZestContext;
|
package/dist/ZestProvider.d.ts
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|