jattac.libs.web.zest-button 1.4.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.
@@ -0,0 +1,165 @@
1
+ ---
2
+ [⬅️ Previous: Features Showcase](./features.md)
3
+
4
+ # API Reference: The Technical Blueprint
5
+
6
+ This document provides an exhaustive reference for all `ZestButton` props and type definitions.
7
+
8
+ ---
9
+
10
+ ## Table of Contents
11
+
12
+ - [ZestButtonProps](#zestbuttonprops)
13
+ - [Type Definitions](#type-definitions)
14
+ - [ZestCustomProps](#zestcustomprops)
15
+ - [ZestGlobalConfig](#zestglobalconfig)
16
+ - [VisualOptions](#visualoptions)
17
+ - [BusyOptions](#busyoptions)
18
+ - [SuccessOptions](#successoptions)
19
+ - [ConfirmOptions](#confirmoptions)
20
+ - [SemanticType](#semantictype)
21
+ - [ZestDropdownOption](#zestdropdownoption)
22
+
23
+ ---
24
+
25
+ ### `ZestButtonProps`
26
+
27
+ The `ZestButton` component accepts all standard HTML `<button>` attributes (e.g., `disabled`, `type`, `name`, `className`) in addition to its own custom configuration prop, `zest`.
28
+
29
+ | Prop Name | Type | Default | Description |
30
+ | :--- | :--- | :--- | :--- |
31
+ | `zest` | `ZestCustomProps` | `{}` | An object containing all custom configuration for the button's behavior and appearance. See `ZestCustomProps` below for details. |
32
+ | `...rest`| `React.ButtonHTMLAttributes` | | All other standard button props are passed directly to the underlying `<button>` element. |
33
+
34
+ ---
35
+
36
+ ### Type Definitions
37
+
38
+ The `zest` prop is a configuration object that follows the `ZestCustomProps` interface. Its properties are detailed below.
39
+
40
+ #### `ZestCustomProps`
41
+
42
+ This is the main configuration object passed to the `zest` prop.
43
+
44
+ | Prop Name | Type | Default | Description |
45
+ | :--- | :--- | :--- | :--- |
46
+ | `visualOptions` | `VisualOptions` | `{}` | Controls the button's appearance, including variant, size, and icons. |
47
+ | `busyOptions` | `BusyOptions` | `{}` | Configures behavior for asynchronous operations. |
48
+ | `successOptions` | `SuccessOptions` | `{}` | Configures feedback after a successful or failed operation. |
49
+ | `confirmOptions` | `ConfirmOptions` | `undefined` | If provided, enables the "click-to-confirm" workflow. |
50
+ | `isDefault` | `boolean` | `false` | If true, the button can be triggered by the `Enter` key. |
51
+ | `theme` | `'light' \| 'dark' \| 'system'` | `'system'` | Overrides the automatic theme detection. |
52
+ | `buttonStyle` | `'solid' \| 'outline' \| 'text' \| 'dashed'`| `'solid'` | Defines the visual style of the button. |
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. |
58
+
59
+ ---
60
+
61
+ #### `ZestGlobalConfig`
62
+
63
+ This is the configuration object passed to the `config` prop of the `ZestButtonConfigProvider`.
64
+
65
+ | Prop Name | Type | Default | Description |
66
+ | :--- | :--- | :--- | :--- |
67
+ | `defaultProps` | `ZestCustomProps` | `{}` | A set of `ZestCustomProps` that will be applied to all `ZestButton` instances within the provider's scope. |
68
+ | `semanticTypeDefaults` | `Partial<Record<string, Partial<ZestCustomProps>>>` | `{}` | A map of semantic types to `ZestCustomProps`. This allows you to define defaults for custom semantic types or override the library's built-in defaults. |
69
+
70
+ ---
71
+
72
+ #### `VisualOptions`
73
+
74
+ Controls the button's appearance.
75
+
76
+ | Prop Name | Type | Default | Description |
77
+ | :--- | :--- | :--- | :--- |
78
+ | `variant` | `'standard' \| 'success' \| 'danger'` | `'standard'`| The color scheme of the button. |
79
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | The size of the button, affecting padding and font size. |
80
+ | `stretch` | `boolean` | `false` | If true, the button expands to the full width of its parent. |
81
+ | `iconLeft` | `React.ReactNode` | `undefined` | A React node (e.g., an icon component) to display on the left. |
82
+ | `iconRight` | `React.ReactNode` | `undefined` | A React node to display on the right. |
83
+
84
+ ---
85
+
86
+ #### `BusyOptions`
87
+
88
+ Configures behavior during asynchronous `onClick` operations.
89
+
90
+ | Prop Name | Type | Default | Description |
91
+ | :--- | :--- | :--- | :--- |
92
+ | `handleInternally` | `boolean` | `true` | If true, automatically manages busy state when `onClick` returns a Promise. |
93
+ | `preventRageClick` | `boolean` | `true` | If true, disables the button while it is in a busy, success, or fail state. |
94
+ | `minBusyDurationMs`| `number` | `500` | Ensures the spinner is shown for at least this long (in ms) to prevent visual flickering on fast network requests. |
95
+
96
+ ---
97
+
98
+ #### `SuccessOptions`
99
+
100
+ Configures the visual feedback after an operation completes.
101
+
102
+ | Prop Name | Type | Default | Description |
103
+ | :--- | :--- | :--- | :--- |
104
+ | `showCheckmark` | `boolean` | `true` | If true, displays an animated checkmark when the `onClick` Promise resolves successfully. |
105
+ | `showFailIcon` | `boolean` | `true` | If true, displays an animated 'X' when the `onClick` Promise rejects or the confirmation timer expires. |
106
+ | `autoResetAfterMs`| `number` | `2000` | The duration (in ms) to show the success/fail icon before the button resets to its normal state. |
107
+
108
+ ---
109
+
110
+ #### `ConfirmOptions`
111
+
112
+ If this object is provided, the button will require two clicks to fire the `onClick` event.
113
+
114
+ | Prop Name | Type | Default | Description |
115
+ | :--- | :--- | :--- | :--- |
116
+ | `displayLabel` | `string` | **(Required)**| The text to show during the confirmation phase (e.g., "Confirm?"). The countdown timer is appended automatically. |
117
+ | `timeoutSecs` | `number` | **(Required)**| The number of seconds the user has to click the button a second time to confirm the action. |
118
+
119
+ ---
120
+
121
+ #### `SemanticType`
122
+
123
+ The `SemanticType` defines common button actions, allowing `ZestButton` to automatically apply default visuals (e.g., icons, variants) and behaviors (e.g., confirmation prompts). This type is extensible through TypeScript module augmentation.
124
+
125
+ **Built-in Semantic Types:**
126
+ `'add'`, `'save'`, `'submit'`, `'edit'`, `'update'`, `'delete'`, `'remove'`, `'cancel'`, `'close'`, `'view'`, `'details'`, `'download'`, `'upload'`, `'refresh'`, `'reload'`, `'print'`, `'share'`, `'confirm'`.
127
+
128
+ **Extensibility:** Developers can extend this list to include custom semantic types by augmenting the `CustomZestSemanticTypes` interface in their project. For example:
129
+
130
+ ```typescript
131
+ // your-project/src/typings/zest-button.d.ts
132
+ import 'jattac.libs.web.zest-button';
133
+
134
+ declare module 'jattac.libs.web.zest-button' {
135
+ export interface CustomZestSemanticTypes {
136
+ archive: 'archive';
137
+ publish: 'publish';
138
+ }
139
+ }
140
+ ```
141
+ After augmentation, `'archive'` and `'publish'` would be valid `SemanticType` values, available for autocompletion and type-checking.
142
+
143
+ ---
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
+
165
+ [⬅️ Previous: Features Showcase](./features.md) | [Next: Configuration Guide ➡️](./configuration.md)
@@ -0,0 +1,143 @@
1
+ ---
2
+ [⬅️ Previous: Development Guide](./development.md)
3
+
4
+ # Breaking Changes: The Upgrade Path
5
+
6
+ This document lists significant changes between versions that might require modifications to your existing codebase.
7
+
8
+ ---
9
+
10
+ ## Table of Contents
11
+
12
+ - [Version 1.2.7](#version-127)
13
+ - [Version 1.2.6](#version-126)
14
+ - [Version 1.2.0](#version-120)
15
+
16
+ ---
17
+
18
+ ## Version 1.2.7
19
+
20
+ ### Renamed `ZestProvider` to `ZestButtonConfigProvider`
21
+
22
+ To provide more explicit naming and better context within the API, the `ZestProvider` component has been renamed to `ZestButtonConfigProvider`. Additionally, its associated context is now `ZestButtonConfigContext`, and the consumption hook is `useZestButtonConfig`.
23
+
24
+ This is a breaking change that requires updating all imports and usages of the provider, context, and hook in your application.
25
+
26
+ **Before:**
27
+
28
+ ```tsx
29
+ import { ZestProvider, useZest } from 'jattac.libs.web.zest-button';
30
+
31
+ const App = () => (
32
+ <ZestProvider config={myConfig}>...</ZestProvider>
33
+ );
34
+
35
+ const MyComponent = () => {
36
+ const config = useZest();
37
+ // ...
38
+ }
39
+ ```
40
+
41
+ **After:**
42
+
43
+ ```tsx
44
+ import { ZestButtonConfigProvider, useZestButtonConfig } from 'jattac.libs.web.zest-button';
45
+
46
+ const App = () => (
47
+ <ZestButtonConfigProvider config={myConfig}>...</ZestButtonConfigProvider>
48
+ );
49
+
50
+ const MyComponent = () => {
51
+ const config = useZestButtonConfig();
52
+ // ...
53
+ }
54
+ ```
55
+
56
+ ---
57
+
58
+ ## Version 1.2.6
59
+
60
+ ### Renamed `fullWidth` prop to `stretch`
61
+
62
+ To better reflect its behavior and avoid potential confusion with other layout properties, the `fullWidth` prop within `visualOptions` has been renamed to `stretch`. This means any usage of `fullWidth` in your `ZestButton` configurations must be updated.
63
+
64
+ **Before:**
65
+
66
+ ```tsx
67
+ <ZestButton
68
+ zest={{
69
+ visualOptions: {
70
+ fullWidth: true,
71
+ },
72
+ }}
73
+ >
74
+ Stretched Button
75
+ </ZestButton>
76
+ ```
77
+
78
+ **After:**
79
+
80
+ ```tsx
81
+ <ZestButton
82
+ zest={{
83
+ visualOptions: {
84
+ stretch: true,
85
+ },
86
+ }}
87
+ >
88
+ Stretched Button
89
+ </ZestButton>
90
+ ```
91
+
92
+ ---
93
+
94
+ ## Version 1.2.0
95
+
96
+ ### Encapsulated Custom Props under `zest` Object
97
+
98
+ To improve maintainability, reduce prop-drilling, and provide a clearer API surface, all custom `ZestButton` properties have been consolidated under a single `zest` prop. Previously, these properties were passed directly to the `ZestButton` component.
99
+
100
+ This change allows for better organization of configuration options (e.g., `visualOptions`, `busyOptions`, `confirmOptions`) and prepares the component for future global configuration contexts.
101
+
102
+ **Before:**
103
+
104
+ ```tsx
105
+ <ZestButton
106
+ variant="success"
107
+ size="lg"
108
+ fullWidth={true}
109
+ minBusyDurationMs={1000}
110
+ preventRageClick={false}
111
+ confirmOptions={{ displayLabel: "Delete?", timeoutSecs: 5 }}
112
+ >
113
+ My Button
114
+ </ZestButton>
115
+ ```
116
+
117
+ **After:**
118
+
119
+ ```tsx
120
+ <ZestButton
121
+ zest={{
122
+ visualOptions: {
123
+ variant: "success",
124
+ size: "lg",
125
+ fullWidth: true,
126
+ },
127
+ busyOptions: {
128
+ minBusyDurationMs: 1000,
129
+ preventRageClick: false,
130
+ },
131
+ confirmOptions: {
132
+ displayLabel: "Delete?",
133
+ timeoutSecs: 5,
134
+ },
135
+ }}
136
+ >
137
+ My Button
138
+ </ZestButton>
139
+ ```
140
+
141
+ ---
142
+
143
+ [⬅️ Previous: Development Guide](./development.md) | [Next: README ➡️](../README.md)
@@ -0,0 +1,214 @@
1
+ ---
2
+ [⬅️ Previous: API Reference](./api.md)
3
+
4
+ # Configuration: The Control Panel
5
+
6
+ This document explains how to configure `ZestButton` on a component and global level.
7
+
8
+ ---
9
+
10
+ ## Table of Contents
11
+
12
+ - [Overview](#overview)
13
+ - [Theme Configuration](#theme-configuration)
14
+ - [Order of Precedence](#order-of-precedence)
15
+ - [Example: Forcing a Theme](#example-forcing-a-theme)
16
+ - [Global Configuration with ZestButtonConfigProvider](#global-configuration-with-zestbuttonconfigprovider)
17
+ - [Usage](#usage)
18
+ - [Precedence with the ZestButtonConfigProvider](#precedence-with-the-zestbuttonconfigprovider)
19
+ - [Advanced: Customizing Semantic Defaults](#advanced-customizing-semantic-defaults)
20
+ - [Example: Defining a Custom 'archive' Type](#example-defining-a-custom-archive-type)
21
+ - [Example: Overriding a Built-in 'delete' Default](#example-overriding-a-built-in-delete-default)
22
+
23
+ ---
24
+
25
+ ### Overview
26
+
27
+ Currently, `ZestButton` is primarily configured on a per-component basis via the `zest` prop. This provides the most explicit and direct control over each button's behavior and appearance.
28
+
29
+ However, there are ways to manage themes and a clear path for future global configuration.
30
+
31
+ ---
32
+
33
+ ### Theme Configuration
34
+
35
+ One of the most powerful configuration options is theme control. `ZestButton` can automatically adapt to the user's operating system preferences, or you can lock it to a specific theme.
36
+
37
+ The `theme` prop within the `zest` object accepts one of three values:
38
+
39
+ - `'system'` (Default): The button listens for the system's color scheme (`prefers-color-scheme`) and applies the `light` or `dark` theme automatically.
40
+ - `'light'`: Forces the button to use the light theme, regardless of system settings.
41
+ - `'dark'`: Forces the button to use the dark theme, regardless of system settings.
42
+
43
+ #### Order of Precedence
44
+
45
+ The `zest.theme` prop has the highest precedence.
46
+
47
+ 1. **`zest.theme` Prop (`light` or `dark`)**: If set, this value is always used.
48
+ 2. **`zest.theme` Prop (`system`)**: If set to `system` (or if undefined), the button will defer to the user's OS-level preference.
49
+
50
+ #### Example: Forcing a Theme
51
+
52
+ This is useful for sections of your UI that have a fixed background color, where you need the button's theme to match its immediate parent rather than the overall page theme.
53
+
54
+ ```tsx
55
+ import ZestButton from 'jattac.libs.web.zest-button';
56
+
57
+ const PinnedFooter = () => (
58
+ <div style={{ background: '#333', padding: '1rem' }}>
59
+ {/* This button's text will be light, matching the dark background */}
60
+ <ZestButton zest={{ theme: 'dark' }}>
61
+ Action in Dark Footer
62
+ </ZestButton>
63
+ </div>
64
+ );
65
+ ```
66
+
67
+ ---
68
+
69
+ ### Global Configuration with `ZestButtonConfigProvider`
70
+
71
+ The `ZestButtonConfigProvider` component is now implemented, allowing you to streamline `ZestButton` configuration across your entire application. You can define a set of default `zest` properties that all `ZestButton` instances within its scope will inherit.
72
+
73
+ #### Usage
74
+
75
+ Wrap your application (or specific sections) with the `ZestButtonConfigProvider` and pass a configuration object to its `config` prop. The `config` prop expects an object of type `ZestGlobalConfig`, which contains a `defaultProps` field of type `ZestCustomProps`.
76
+
77
+ ```tsx
78
+ // In your main App.tsx file
79
+
80
+ import { ZestButtonConfigProvider } from 'jattac.libs.web.zest-button';
81
+ import MyRoutes from './MyRoutes';
82
+
83
+ const appZestConfig = {
84
+ defaultProps: {
85
+ visualOptions: {
86
+ size: 'sm', // Make all buttons small by default
87
+ },
88
+ busyOptions: {
89
+ minBusyDurationMs: 300, // Shorten the busy duration app-wide
90
+ },
91
+ },
92
+ };
93
+
94
+ const App = () => (
95
+ <ZestButtonConfigProvider config={appZestConfig}>
96
+ <MyRoutes />
97
+ </ZestButtonConfigProvider>
98
+ );
99
+ ```
100
+
101
+ #### Precedence with the `ZestButtonConfigProvider`
102
+
103
+ Property configurations are merged in a "deep merge" fashion with the following order of precedence (where the last one wins):
104
+
105
+ 1. **Global `defaultProps`**: Props defined in the `ZestButtonConfigProvider`'s `config.defaultProps` object. This is the base layer of styling.
106
+ 2. **Built-in Semantic Defaults**: The library's own defaults for a given `semanticType` (e.g., the `success` variant for `save`).
107
+ 3. **Custom Semantic Defaults**: **(New!)** Defaults for a `semanticType` that you provide in the `ZestButtonConfigProvider`'s `config.semanticTypeDefaults` object. This allows you to override the library's defaults or create new ones.
108
+ 4. **Local `zest` Props**: The props passed directly to a specific `<ZestButton>` instance. This gives you the ultimate granular control.
109
+
110
+ ---
111
+
112
+ ### Advanced: Customizing Semantic Defaults
113
+
114
+ This is one of the most powerful features of the `ZestButtonConfigProvider`. You can define application-wide styles and behaviors for any `semanticType`. This is perfect for creating a consistent design system.
115
+
116
+ The `ZestButtonConfigProvider`'s `config` prop accepts a `semanticTypeDefaults` object. You can use this to **override** built-in defaults or **define** defaults for your own custom types.
117
+
118
+ #### Example: Defining a Custom 'archive' Type
119
+
120
+ First, let's imagine you've used module augmentation to create a new `semanticType` called `'archive'`, as explained in the [Development Guide](./development.md). Now, you want all `'archive'` buttons to have a specific look and feel across your app.
121
+
122
+ ```tsx
123
+ // your-project/src/typings/zest-button-extensions.d.ts
124
+ import 'jattac.libs.web.zest-button';
125
+
126
+ declare module 'jattac.libs.web.zest-button' {
127
+ export interface CustomZestSemanticTypes {
128
+ archive: 'archive';
129
+ }
130
+ }
131
+ ```
132
+
133
+ Now, configure the defaults in your `ZestButtonConfigProvider`:
134
+
135
+ ```tsx
136
+ // In your main App.tsx file
137
+ import { ZestButtonConfigProvider } from 'jattac.libs.web.zest-button';
138
+ import { FaArchive } from 'react-icons/fa';
139
+ import MyRoutes from './MyRoutes';
140
+
141
+ const appZestConfig = {
142
+ // Define defaults for our new custom semantic type
143
+ semanticTypeDefaults: {
144
+ archive: {
145
+ buttonStyle: 'outline',
146
+ visualOptions: {
147
+ iconLeft: <FaArchive />,
148
+ variant: 'standard',
149
+ },
150
+ confirmOptions: {
151
+ displayLabel: 'Confirm Archive?',
152
+ timeoutSecs: 10,
153
+ }
154
+ }
155
+ }
156
+ };
157
+
158
+ const App = () => (
159
+ <ZestButtonConfigProvider config={appZestConfig}>
160
+ <MyRoutes />
161
+ </ZestButtonConfigProvider>
162
+ );
163
+
164
+ // --- Later, in some other component ---
165
+
166
+ // This button will automatically get the icon, style, and confirmation behavior!
167
+ <ZestButton zest={{ semanticType: 'archive' }} onClick={handleArchiveAction}>
168
+ Archive Record
169
+ </ZestButton>
170
+ ```
171
+
172
+ #### Example: Overriding a Built-in 'delete' Default
173
+
174
+ Let's say you like the built-in `delete` type, but for your application, you want the button style to be `outline` instead of `solid`, and you want a shorter confirmation time.
175
+
176
+ ```tsx
177
+ // In your main App.tsx file
178
+ import { ZestButtonConfigProvider } from 'jattac.libs.web.zest-button';
179
+ import MyRoutes from './MyRoutes';
180
+
181
+ const appZestConfig = {
182
+ // Override specific props for a built-in semantic type
183
+ semanticTypeDefaults: {
184
+ delete: {
185
+ // We only specify what we want to change.
186
+ // The icon and 'danger' variant will still be inherited from the built-in default.
187
+ buttonStyle: 'outline',
188
+ confirmOptions: {
189
+ // We must provide the full object to override, not just one property.
190
+ displayLabel: 'Confirm Deletion',
191
+ timeoutSecs: 3, // Shorter timeout
192
+ }
193
+ }
194
+ }
195
+ };
196
+
197
+ const App = () => (
198
+ <ZestButtonConfigProvider config={appZestConfig}>
199
+ <MyRoutes />
200
+ </ZestButtonConfigProvider>
201
+ );
202
+
203
+ // --- Later, in some other component ---
204
+
205
+ // This button will now be an 'outline' button with a 3-second confirmation.
206
+ <ZestButton zest={{ semanticType: 'delete' }} onClick={handleDeleteAction}>
207
+ Delete Record
208
+ </ZestButton>
209
+ ```
210
+
211
+ ---
212
+
213
+ [⬅️ Previous: API Reference](./api.md) | [Next: Development Guide ➡️](./development.md)
214
+
@@ -0,0 +1,93 @@
1
+ ---
2
+ [⬅️ Previous: Configuration Guide](./configuration.md)
3
+
4
+ # Development: The Contributor's Guide
5
+
6
+ This guide provides an overview of the project's internal structure and instructions for setting up your development environment.
7
+
8
+ ---
9
+
10
+ ## Table of Contents
11
+
12
+ - [Internal Architecture](#internal-architecture)
13
+ - [Setup Instructions](#setup-instructions)
14
+ - [Scripts](#scripts)
15
+ - [Extending Semantic Types](#extending-semantic-types)
16
+
17
+ ---
18
+
19
+ ### Internal Architecture
20
+
21
+ The `jattac.libs.web.zest-button` project is structured to be a self-contained React component library.
22
+
23
+ - **`UI/ZestButton.tsx`**: This is the heart of the component. It contains the main React functional component, state management logic, event handlers, and renders the button's UI based on its props and internal state. Auxiliary components like `AnimatedCheckmark` and `AnimatedX` are also defined here.
24
+ - **`UI/SpinnerIcon.tsx`**: A small, dedicated component for rendering the loading spinner, utilizing `react-icons`.
25
+ - **`Styles/ZestButton.module.css`**: All the CSS for the component is defined in this file. It leverages CSS Modules to ensure styles are scoped and prevent conflicts. It also includes global CSS variables for theming and animations.
26
+ - **`dist/`**: This directory is the output of the build process. It contains the compiled JavaScript files (CommonJS and ES Modules), the TypeScript declaration file (`index.d.ts`), and potentially source maps. This is the content that gets published to npm.
27
+ - **`rollup.config.mjs`**: The configuration file for Rollup, the module bundler used for this project. It defines how the TypeScript and CSS are transpiled, bundled, and how the declaration files are generated.
28
+ - **`tsconfig.json`**: The TypeScript compiler configuration. It specifies compiler options, such as target JavaScript version, module resolution strategy, JSX factory, and files to include/exclude from compilation.
29
+
30
+ ---
31
+
32
+ ### Setup Instructions
33
+
34
+ To get the development environment running on your local machine, follow these steps:
35
+
36
+ 1. **Clone the repository:**
37
+ ```bash
38
+ git clone https://github.com/jattac/jattac.libs.web.zest-button.git
39
+ cd jattac.libs.web.zest-button
40
+ ```
41
+ 2. **Install dependencies:**
42
+ ```bash
43
+ npm install
44
+ ```
45
+ This command will install all the necessary `devDependencies` listed in `package.json`.
46
+
47
+ ---
48
+
49
+ ### Scripts
50
+
51
+ The `package.json` includes several scripts to help with development and building the package:
52
+
53
+ - **`npm run build`**:
54
+ * **Purpose**: Compiles the TypeScript code, processes CSS Modules, and bundles the component into production-ready CommonJS and ES Module formats. It also generates the TypeScript declaration file (`index.d.ts`).
55
+ * **Output**: Creates the `dist/` directory with all the necessary files for publishing.
56
+ * **Command**: `rollup -c rollup.config.mjs`
57
+
58
+ - **`npm run dev`**:
59
+ * **Purpose**: Starts Rollup in watch mode. This command is ideal for development as it automatically recompiles the component whenever source files are changed, allowing for rapid iteration.
60
+ * **Output**: Similar to `build`, but also keeps the process running to watch for changes.
61
+ * **Command**: `rollup -c rollup.config.mjs -w`
62
+
63
+ ---
64
+
65
+ ### Extending Semantic Types
66
+
67
+ The `ZestButton` provides a mechanism for developers to extend the built-in `SemanticType` union with their own custom semantic types. This is achieved through TypeScript's [module augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation) feature.
68
+
69
+ To add your own custom semantic types:
70
+
71
+ 1. Create a TypeScript declaration file in your project (e.g., `your-project/src/typings/zest-button-extensions.d.ts`).
72
+ 2. Augment the `jattac.libs.web.zest-button` module and define your custom semantic types within the `CustomZestSemanticTypes` interface. The keys of this interface will become available as new `SemanticType` values.
73
+
74
+ ```typescript
75
+ // your-project/src/typings/zest-button-extensions.d.ts
76
+ import 'jattac.libs.web.zest-button'; // Important: Extend the module
77
+
78
+ declare module 'jattac.libs.web.zest-button' {
79
+ export interface CustomZestSemanticTypes {
80
+ archive: 'archive';
81
+ publish: 'publish';
82
+ // Add any other custom semantic types here
83
+ }
84
+ }
85
+ ```
86
+
87
+ Once augmented, these new semantic types (`'archive'`, `'publish'`) will be available for autocompletion and type-checking when using the `semanticType` prop on your `ZestButton` instances.
88
+
89
+ *(Note: Currently, there are no dedicated test scripts defined in `package.json`. Testing is typically done manually in a consuming project during development, or through dedicated test runners that would be added in the future.)*
90
+
91
+ ---
92
+
93
+ [⬅️ Previous: Configuration Guide](./configuration.md) | [Next: Breaking Changes ➡️](./breaking-changes.md)