smartsell-ui-kit 0.0.6 → 0.1.1
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 +16 -15
- package/README.md +170 -84
- package/dist/img/index.cjs +373 -0
- package/dist/img/index.cjs.map +1 -0
- package/dist/img/index.d.cts +170 -0
- package/dist/img/index.d.ts +170 -0
- package/dist/img/index.js +328 -0
- package/dist/img/index.js.map +1 -0
- package/dist/index.cjs +4608 -1201
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +306 -25
- package/dist/index.d.ts +306 -25
- package/dist/index.js +4952 -1094
- package/dist/index.js.map +1 -1
- package/dist/types.cjs +19 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +4 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.js +1 -0
- package/package.json +30 -19
- package/dist/chunk-UIFTQDYM.js +0 -460
- package/dist/chunk-UIFTQDYM.js.map +0 -1
- package/dist/modal-CS9SuYSC.d.cts +0 -97
- package/dist/modal-CS9SuYSC.d.ts +0 -97
- package/dist/modal.cjs +0 -486
- package/dist/modal.cjs.map +0 -1
- package/dist/modal.d.cts +0 -4
- package/dist/modal.d.ts +0 -4
- package/dist/modal.js +0 -7
- /package/dist/{modal.js.map → types.js.map} +0 -0
package/LICENSE
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
SmartSell Proprietary License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2026 SmartSell
|
|
3
|
+
Copyright (c) 2026 SmartSell. All rights reserved.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
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:
|
|
5
|
+
This source code, the published package artifacts, and all related documentation
|
|
6
|
+
are proprietary software owned by SmartSell.
|
|
11
7
|
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
Permission to access, install, and use this software is granted only to people
|
|
9
|
+
and organizations that are explicitly authorized by SmartSell under a valid
|
|
10
|
+
written agreement or commercial relationship.
|
|
11
|
+
|
|
12
|
+
Except where SmartSell has given prior written permission, you may not copy,
|
|
13
|
+
modify, merge, publish, distribute, sublicense, sell, lease, reverse engineer,
|
|
14
|
+
decompile, create derivative works from, or otherwise exploit this software or
|
|
15
|
+
any portion of it.
|
|
14
16
|
|
|
15
17
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
18
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
-
|
|
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
|
|
21
|
-
SOFTWARE.
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT. IN NO EVENT
|
|
20
|
+
SHALL SMARTSELL OR ITS LICENSORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,58 +1,133 @@
|
|
|
1
1
|
# smartsell-ui-kit
|
|
2
2
|
|
|
3
|
-
`smartsell-ui-kit` is the
|
|
3
|
+
`smartsell-ui-kit` is the shared React component package for SmartSell custom modules, tenant extensions, and isolated integrations.
|
|
4
4
|
|
|
5
|
-
It
|
|
6
|
-
The package stays on the public contract surface:
|
|
5
|
+
It provides the public UI contract that external consumers should rely on instead of importing private SmartSell app internals. The package is built around a few core goals:
|
|
7
6
|
|
|
8
|
-
- theme-aware components powered by `smartsell-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
7
|
+
- theme-aware components powered by `smartsell-theme`
|
|
8
|
+
- self-contained styling with no dependency on private SmartSell CSS files
|
|
9
|
+
- predictable APIs for forms, modals, data tables, and common surfaces
|
|
10
|
+
- async-friendly primitives for remote search and server-driven datasets
|
|
11
|
+
|
|
12
|
+
## Highlights
|
|
13
|
+
|
|
14
|
+
- React 18-first component API
|
|
15
|
+
- Consistent theme integration through `smartsell-theme`
|
|
16
|
+
- Form primitives such as `Input`, `Textarea`, `Checkbox`, `DatePicker`, `Select`, and `SelectAsync`
|
|
17
|
+
- Display and layout primitives such as `Card`, `CardSmall`, and `Separator`
|
|
18
|
+
- Modal helpers including `Modal`, `ComposableModal`, and `createModalSlotIds`
|
|
19
|
+
- Data components including `Table` and `TableAsync`
|
|
20
|
+
- Brand images published from the dedicated `smartsell-ui-kit/img` subpath
|
|
21
|
+
- Local Storybook workspace for visual QA before release
|
|
22
|
+
|
|
23
|
+
## Requirements
|
|
24
|
+
|
|
25
|
+
- React 18+
|
|
26
|
+
- React DOM 18+
|
|
27
|
+
- `smartsell-theme`
|
|
11
28
|
|
|
12
29
|
## Installation
|
|
13
30
|
|
|
14
31
|
```bash
|
|
15
|
-
npm install react smartsell-
|
|
32
|
+
npm install react@^18 react-dom@^18 smartsell-theme smartsell-ui-kit
|
|
16
33
|
```
|
|
17
34
|
|
|
18
|
-
##
|
|
35
|
+
## Quick start
|
|
36
|
+
|
|
37
|
+
Wrap your module with `ThemeProvider` from `smartsell-theme`, then consume the UI kit components normally.
|
|
19
38
|
|
|
20
39
|
```tsx
|
|
40
|
+
import { ThemeProvider } from 'smartsell-theme';
|
|
21
41
|
import { Button, Card } from 'smartsell-ui-kit';
|
|
22
|
-
import type { ModulePageProps } from 'smartsell-sales-sdk';
|
|
23
42
|
|
|
24
|
-
export default function ExamplePage(
|
|
43
|
+
export default function ExamplePage() {
|
|
25
44
|
return (
|
|
26
|
-
<
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
45
|
+
<ThemeProvider>
|
|
46
|
+
<Card title="Example" eyebrow="UI kit">
|
|
47
|
+
<Button onClick={() => window.history.back()}>
|
|
48
|
+
Go back
|
|
49
|
+
</Button>
|
|
50
|
+
</Card>
|
|
51
|
+
</ThemeProvider>
|
|
31
52
|
);
|
|
32
53
|
}
|
|
33
54
|
```
|
|
34
55
|
|
|
56
|
+
## Main exports
|
|
57
|
+
|
|
58
|
+
- `Button`, `Checkbox`, `DatePicker`, `Input`, `Textarea`, `Select`, `SelectAsync`
|
|
59
|
+
- `Card`, `CardSmall`, `Separator`
|
|
60
|
+
- `Modal`, `ComposableModal`, `createModalSlotIds`
|
|
61
|
+
- `Table`, `TableAsync`
|
|
62
|
+
- `useUiKitTheme`
|
|
63
|
+
- `smartsell-ui-kit/img` for branded logo, icon, favicon, and background image components
|
|
64
|
+
|
|
65
|
+
## Images subpath
|
|
66
|
+
|
|
67
|
+
Import brand images from the dedicated `img` subpath so the main entrypoint stays focused on UI primitives.
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { Icon192, Logo, Texture1 } from 'smartsell-ui-kit/img';
|
|
71
|
+
|
|
72
|
+
export default function BrandHeader() {
|
|
73
|
+
return (
|
|
74
|
+
<div style={{ display: 'grid', gap: 16 }}>
|
|
75
|
+
<Logo style={{ width: 240 }} />
|
|
76
|
+
<Icon192 size={72} alt="SmartSell app icon" />
|
|
77
|
+
<Texture1 decorative style={{ width: '100%', maxWidth: 420 }} />
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
All image components resolve their source from the active `smartsell-theme` context. Right now light and dark modes point to the same files, but the submodule already swaps sources by theme variant so future dark-specific images only require changing the mapped filenames.
|
|
84
|
+
|
|
35
85
|
## Composable modal pattern
|
|
36
86
|
|
|
37
|
-
Use `ComposableModal` when
|
|
87
|
+
Use `ComposableModal` when the page should own modal state and business logic, while host applications or extension layers customize the `header`, `body`, and `footer` through stable slot ids.
|
|
38
88
|
|
|
39
89
|
```tsx
|
|
40
|
-
import {
|
|
90
|
+
import { useState } from 'react';
|
|
91
|
+
|
|
92
|
+
import { Button, ComposableModal, createModalSlotIds } from 'smartsell-ui-kit';
|
|
41
93
|
|
|
42
94
|
const slotIds = createModalSlotIds('order-review');
|
|
43
95
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
>
|
|
54
|
-
|
|
55
|
-
|
|
96
|
+
export default function ExamplePage() {
|
|
97
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
98
|
+
|
|
99
|
+
const submitOrder = () => {
|
|
100
|
+
setIsOpen(false);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<>
|
|
105
|
+
<Button onClick={() => setIsOpen(true)}>Open order review</Button>
|
|
106
|
+
|
|
107
|
+
<ComposableModal
|
|
108
|
+
isOpen={isOpen}
|
|
109
|
+
onClose={() => setIsOpen(false)}
|
|
110
|
+
onConfirm={submitOrder}
|
|
111
|
+
title="Order review"
|
|
112
|
+
slotBaseId="order-review"
|
|
113
|
+
renderSlot={({ id, context, children }) => {
|
|
114
|
+
if (id === slotIds.footer) {
|
|
115
|
+
return (
|
|
116
|
+
<Button onClick={() => context.confirm?.()}>
|
|
117
|
+
Send order {context.payload?.orderNumber}
|
|
118
|
+
</Button>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return children;
|
|
123
|
+
}}
|
|
124
|
+
payload={{ orderNumber: 'SO-1001', total: 421.9 }}
|
|
125
|
+
>
|
|
126
|
+
<div>Default modal body</div>
|
|
127
|
+
</ComposableModal>
|
|
128
|
+
</>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
56
131
|
```
|
|
57
132
|
|
|
58
133
|
Slot ids generated by `createModalSlotIds('order-review')`:
|
|
@@ -61,81 +136,92 @@ Slot ids generated by `createModalSlotIds('order-review')`:
|
|
|
61
136
|
- `order-review:modal-body`
|
|
62
137
|
- `order-review:modal-footer`
|
|
63
138
|
|
|
64
|
-
|
|
139
|
+
This pattern is useful when:
|
|
140
|
+
|
|
141
|
+
- the page owns data loading, permissions, and submission flow
|
|
142
|
+
- the host app needs stable extension points instead of private imports
|
|
143
|
+
- multiple modal variants should reuse the same contract
|
|
144
|
+
|
|
145
|
+
## Async components
|
|
146
|
+
|
|
147
|
+
`SelectAsync` is designed for remote option sources while preserving the same interaction model as the regular `Select`.
|
|
65
148
|
|
|
66
149
|
```tsx
|
|
67
|
-
import {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
} from 'smartsell-ui-kit';
|
|
77
|
-
|
|
78
|
-
type OrderPayload = {
|
|
79
|
-
orderNumber: string;
|
|
80
|
-
total: number;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
function CustomFooter({ sdk, context }: SlotComponentProps<ModalSlotContext<OrderPayload>>) {
|
|
150
|
+
import { useState } from 'react';
|
|
151
|
+
|
|
152
|
+
import { SelectAsync, type SelectAsyncOption } from 'smartsell-ui-kit';
|
|
153
|
+
|
|
154
|
+
type CustomerOption = SelectAsyncOption<string>;
|
|
155
|
+
|
|
156
|
+
function CustomerField() {
|
|
157
|
+
const [value, setValue] = useState<CustomerOption | null>(null);
|
|
158
|
+
|
|
84
159
|
return (
|
|
85
|
-
<
|
|
86
|
-
|
|
87
|
-
|
|
160
|
+
<SelectAsync
|
|
161
|
+
label="Customer"
|
|
162
|
+
value={value}
|
|
163
|
+
onChange={setValue}
|
|
164
|
+
loadOptions={async (query, loadedOptions, { page, signal }) => {
|
|
165
|
+
const response = await fetch(`/api/customers?search=${query}&page=${page}`, { signal });
|
|
166
|
+
const data = await response.json();
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
options: data.items.map((item: { id: string; tradeName: string }) => ({
|
|
170
|
+
value: item.id,
|
|
171
|
+
label: item.tradeName,
|
|
172
|
+
})),
|
|
173
|
+
hasMore: data.hasMore,
|
|
174
|
+
};
|
|
175
|
+
}}
|
|
176
|
+
/>
|
|
88
177
|
);
|
|
89
178
|
}
|
|
179
|
+
```
|
|
90
180
|
|
|
91
|
-
|
|
181
|
+
`TableAsync` follows the same idea for remote datasets, with debounced search and request cancellation support built into the component flow.
|
|
92
182
|
|
|
93
|
-
|
|
94
|
-
slots: {
|
|
95
|
-
[slots.footer]: {
|
|
96
|
-
action: 'replace',
|
|
97
|
-
component: CustomFooter,
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
});
|
|
183
|
+
## Development workflow
|
|
101
184
|
|
|
102
|
-
|
|
103
|
-
```
|
|
185
|
+
Useful local commands:
|
|
104
186
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
187
|
+
```bash
|
|
188
|
+
npm run storybook
|
|
189
|
+
npm run test
|
|
190
|
+
npm run validate
|
|
191
|
+
npm run validate:release
|
|
192
|
+
```
|
|
111
193
|
|
|
112
|
-
|
|
194
|
+
Run Storybook in Docker when you want containerized local development:
|
|
113
195
|
|
|
114
196
|
```bash
|
|
115
|
-
|
|
116
|
-
npm run build
|
|
117
|
-
npm publish
|
|
197
|
+
docker compose up --build
|
|
118
198
|
```
|
|
119
199
|
|
|
120
|
-
##
|
|
200
|
+
## Storybook workspace
|
|
121
201
|
|
|
122
|
-
The repository
|
|
202
|
+
The repository includes a local Storybook workspace for component review and design QA.
|
|
123
203
|
|
|
124
|
-
- grouped
|
|
125
|
-
-
|
|
126
|
-
-
|
|
204
|
+
- grouped navigation for buttons, surfaces, forms, modals, and tables
|
|
205
|
+
- a dedicated `Images` section covering logos, icons, and backgrounds from `smartsell-ui-kit/img`
|
|
206
|
+
- live Controls for props and responsive behavior
|
|
207
|
+
- a local `ThemeProvider` preview using the same `smartsell-theme` contract expected by host apps
|
|
208
|
+
- a `Theme/Colors` playground for temporary Storybook-only token overrides
|
|
127
209
|
|
|
128
|
-
|
|
210
|
+
Storybook is development-only. It is not published to npm because the package only ships `dist`, `README.md`, and `LICENSE`.
|
|
129
211
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
```
|
|
212
|
+
Theme overrides from the `Theme/Colors` story affect only the local Storybook session. Runtime consumers still read theme values from their host application's `smartsell-theme` integration.
|
|
213
|
+
|
|
214
|
+
## Release checklist
|
|
134
215
|
|
|
135
|
-
|
|
216
|
+
Before publishing a new version:
|
|
136
217
|
|
|
137
218
|
```bash
|
|
138
|
-
|
|
219
|
+
npm run validate
|
|
220
|
+
npm run build:storybook
|
|
221
|
+
npm pack --dry-run
|
|
222
|
+
npm publish
|
|
139
223
|
```
|
|
140
224
|
|
|
141
|
-
|
|
225
|
+
## License
|
|
226
|
+
|
|
227
|
+
This package is distributed under the SmartSell proprietary license described in `LICENSE`.
|