@proveanything/smartlinks-utils-ui 0.2.13 → 0.3.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 +100 -64
- package/dist/components/RecordsAdmin/index.css +40 -0
- package/dist/components/RecordsAdmin/index.css.map +1 -0
- package/dist/components/RecordsAdmin/index.d.ts +1083 -0
- package/dist/components/RecordsAdmin/index.js +2833 -0
- package/dist/components/RecordsAdmin/index.js.map +1 -0
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -1,146 +1,182 @@
|
|
|
1
|
-
# @proveanything/smartlinks-ui
|
|
1
|
+
# @proveanything/smartlinks-utils-ui
|
|
2
2
|
|
|
3
|
-
Reusable React components for [SmartLinks](https://smartlinks.app) microapps
|
|
3
|
+
Reusable React components for [SmartLinks](https://smartlinks.app) microapps —
|
|
4
|
+
the headline module is **RecordsAdminShell**, a complete admin UI for the
|
|
5
|
+
`app.records` pattern (per-product / per-variant / per-batch / per-facet data
|
|
6
|
+
with scope inheritance). Also ships an Asset Picker, Icon Picker, Font Picker,
|
|
7
|
+
and Conditions Editor.
|
|
8
|
+
|
|
9
|
+
- Package: `@proveanything/smartlinks-utils-ui`
|
|
10
|
+
- Tracks: `@proveanything/smartlinks ≥ 1.9`
|
|
11
|
+
- See also: SDK docs [`ui-utils.md`](https://github.com/proveanything/smartlinks-sdk/blob/main/docs/ui-utils.md) and [`records-admin-pattern.md`](https://github.com/proveanything/smartlinks-sdk/blob/main/docs/records-admin-pattern.md)
|
|
4
12
|
|
|
5
13
|
## Installation
|
|
6
14
|
|
|
7
15
|
```bash
|
|
8
|
-
npm install @proveanything/smartlinks-ui
|
|
16
|
+
npm install @proveanything/smartlinks-utils-ui
|
|
9
17
|
```
|
|
10
18
|
|
|
11
|
-
### Peer
|
|
12
|
-
|
|
13
|
-
This package requires the following peer dependencies in your app:
|
|
19
|
+
### Peer dependencies
|
|
14
20
|
|
|
15
21
|
```bash
|
|
16
|
-
npm install react react-dom @proveanything/smartlinks
|
|
22
|
+
npm install react react-dom @proveanything/smartlinks @tanstack/react-query
|
|
17
23
|
```
|
|
18
24
|
|
|
25
|
+
`@tanstack/react-query` is required by `RecordsAdminShell` (caching, pagination,
|
|
26
|
+
optimistic save). Wrap your app in a `<QueryClientProvider>` somewhere up the
|
|
27
|
+
tree.
|
|
28
|
+
|
|
19
29
|
## Setup
|
|
20
30
|
|
|
21
|
-
Import the pre-compiled styles in your app
|
|
31
|
+
Import the pre-compiled styles **once** in your app entry (e.g. `main.tsx`):
|
|
22
32
|
|
|
23
33
|
```tsx
|
|
24
|
-
import '@proveanything/smartlinks-ui/styles.css';
|
|
25
|
-
// — OR, if you import the main barrel, CSS is included automatically:
|
|
26
|
-
import { AssetPicker } from '@proveanything/smartlinks-ui';
|
|
34
|
+
import '@proveanything/smartlinks-utils-ui/styles.css';
|
|
27
35
|
```
|
|
28
36
|
|
|
29
|
-
|
|
37
|
+
Components inherit your shadcn-compatible CSS variables (`--primary`,
|
|
38
|
+
`--background`, `--border`, …) and pick up your theme automatically.
|
|
30
39
|
|
|
31
|
-
|
|
40
|
+
## Modules
|
|
32
41
|
|
|
33
|
-
|
|
42
|
+
| Subpath | Module | Use when |
|
|
43
|
+
|---------|--------|----------|
|
|
44
|
+
| `/records-admin` | **RecordsAdminShell** + hooks (`useResolvedRecord`, `useRecordEditor`, …) | Building any per-product / per-variant / per-batch / per-facet admin |
|
|
45
|
+
| `/asset-picker` | AssetPicker | Pick / upload / paste / URL-import media assets |
|
|
46
|
+
| `/icon-picker` | IconPicker | Searchable Font Awesome 7 Pro picker |
|
|
47
|
+
| `/font-picker` | FontPicker | Google Fonts + custom uploaded fonts |
|
|
48
|
+
| `/conditions-editor` | ConditionsEditor | Recursive AND/OR rule builder (12 condition types) |
|
|
34
49
|
|
|
35
|
-
###
|
|
50
|
+
### Records Admin Shell
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import {
|
|
54
|
+
RecordsAdminShell,
|
|
55
|
+
type EditorContext,
|
|
56
|
+
} from '@proveanything/smartlinks-utils-ui/records-admin';
|
|
57
|
+
import * as SL from '@proveanything/smartlinks';
|
|
58
|
+
|
|
59
|
+
<RecordsAdminShell<NutritionData>
|
|
60
|
+
SL={SL}
|
|
61
|
+
collectionId={collectionId}
|
|
62
|
+
appId={appId}
|
|
63
|
+
recordType="nutrition"
|
|
64
|
+
label="Nutrition info"
|
|
65
|
+
scopes={['facet', 'product', 'variant', 'batch']}
|
|
66
|
+
contextScope={{ productId, variantId, batchId }} // optional, from iframe URL
|
|
67
|
+
defaultData={() => ({})}
|
|
68
|
+
renderEditor={(ctx) => <NutritionForm ctx={ctx} />}
|
|
69
|
+
renderPreview={({ resolved }) => <pre>{JSON.stringify(resolved, null, 2)}</pre>}
|
|
70
|
+
/>
|
|
71
|
+
```
|
|
36
72
|
|
|
37
|
-
|
|
73
|
+
The shell renders the browser pane (scope tabs, search, status pills), the
|
|
74
|
+
editor pane (sticky save / discard / delete footer with optimistic save), and
|
|
75
|
+
the inheritance markers — you only provide the form for one record.
|
|
76
|
+
|
|
77
|
+
On the **public widget** side, read the resolved value with `useResolvedRecord`:
|
|
38
78
|
|
|
39
79
|
```tsx
|
|
40
|
-
import {
|
|
80
|
+
import { useResolvedRecord } from '@proveanything/smartlinks-utils-ui/records-admin';
|
|
81
|
+
|
|
82
|
+
const { data, source, isLoading } = useResolvedRecord({
|
|
83
|
+
SL, appId, recordType: 'nutrition',
|
|
84
|
+
collectionId, productId, variantId, batchId,
|
|
85
|
+
});
|
|
86
|
+
// source: 'proof' | 'batch' | 'variant' | 'product' | 'facet' | 'universal' | null
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Asset Picker
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
import { AssetPicker } from '@proveanything/smartlinks-utils-ui/asset-picker';
|
|
41
93
|
|
|
42
94
|
<AssetPicker
|
|
43
95
|
scope={{ type: 'collection', collectionId: 'abc123' }}
|
|
44
96
|
mode="dialog"
|
|
45
97
|
allowUpload
|
|
46
|
-
|
|
47
|
-
|
|
98
|
+
accept={['image/*']}
|
|
99
|
+
onSelect={(asset) => setHeroUrl(asset.url)}
|
|
100
|
+
trigger={<button>Choose image</button>}
|
|
48
101
|
/>
|
|
49
102
|
```
|
|
50
103
|
|
|
51
104
|
### Conditions Editor
|
|
52
105
|
|
|
53
|
-
Visual editor for building condition rules with AND/OR logic groups.
|
|
54
|
-
|
|
55
106
|
```tsx
|
|
56
|
-
import { ConditionsEditor } from '@proveanything/smartlinks-ui/conditions-editor';
|
|
107
|
+
import { ConditionsEditor } from '@proveanything/smartlinks-utils-ui/conditions-editor';
|
|
57
108
|
|
|
58
109
|
<ConditionsEditor
|
|
59
|
-
value={
|
|
60
|
-
onChange={
|
|
61
|
-
//
|
|
62
|
-
collectionId={collectionId}
|
|
63
|
-
// …or pass them explicitly:
|
|
64
|
-
// facets={[{ key: 'colour', name: 'Colour', cardinality: 'multi',
|
|
65
|
-
// values: [{ key: 'red', name: 'Red' }] }]}
|
|
110
|
+
value={rules}
|
|
111
|
+
onChange={setRules}
|
|
112
|
+
collectionId={collectionId} // auto-loads facet definitions
|
|
66
113
|
versions={[{ title: 'Default', value: '' }]}
|
|
67
114
|
tags={['featured', 'new']}
|
|
68
115
|
/>
|
|
69
116
|
```
|
|
70
117
|
|
|
71
|
-
Supported condition types include **facet** (match against product facet
|
|
72
|
-
definitions), version, country, value, user, date, device, label, geofence,
|
|
73
|
-
product id, item status and condition reference.
|
|
74
|
-
|
|
75
118
|
### Icon Picker
|
|
76
119
|
|
|
77
|
-
Searchable Font Awesome icon picker with lazy-loaded icon index for tree shaking.
|
|
78
|
-
|
|
79
120
|
```tsx
|
|
80
|
-
import { IconPicker } from '@proveanything/smartlinks-ui/icon-picker';
|
|
121
|
+
import { IconPicker } from '@proveanything/smartlinks-utils-ui/icon-picker';
|
|
81
122
|
|
|
82
123
|
<IconPicker
|
|
83
124
|
mode="dialog"
|
|
84
125
|
value="fa-solid fa-heart"
|
|
85
|
-
onSelect={(icon) =>
|
|
86
|
-
trigger={<button>Pick
|
|
126
|
+
onSelect={(icon) => setIcon(icon.name)}
|
|
127
|
+
trigger={<button>Pick icon</button>}
|
|
87
128
|
/>
|
|
88
129
|
```
|
|
89
130
|
|
|
90
|
-
|
|
131
|
+
Requires the Font Awesome 7 Pro kit script on the host page.
|
|
91
132
|
|
|
92
|
-
|
|
133
|
+
### Font Picker
|
|
93
134
|
|
|
94
135
|
```tsx
|
|
95
|
-
import { FontPicker } from '@proveanything/smartlinks-ui/font-picker';
|
|
136
|
+
import { FontPicker } from '@proveanything/smartlinks-utils-ui/font-picker';
|
|
96
137
|
|
|
97
138
|
<FontPicker
|
|
98
139
|
mode="dialog"
|
|
99
140
|
value="Inter"
|
|
100
141
|
showPreview
|
|
101
142
|
onSelect={(font) => {
|
|
102
|
-
console.log(font.
|
|
103
|
-
console.log(font.
|
|
104
|
-
console.log(font.loadSnippet); // <link href="..." rel="stylesheet">
|
|
143
|
+
console.log(font.cssFontFamily); // ready for `font-family:` CSS
|
|
144
|
+
console.log(font.loadSnippet); // <link> or @font-face block to inject
|
|
105
145
|
}}
|
|
106
|
-
trigger={<button>Pick Font</button>}
|
|
107
|
-
/>
|
|
108
|
-
|
|
109
|
-
{/* With custom uploaded fonts from SmartLinks */}
|
|
110
|
-
<FontPicker
|
|
111
|
-
mode="dialog"
|
|
112
|
-
showCustomFonts
|
|
113
|
-
scope={{ collectionId: 'abc123' }}
|
|
114
|
-
admin
|
|
115
|
-
onSelect={(font) => console.log(font)}
|
|
116
146
|
/>
|
|
117
147
|
```
|
|
118
148
|
|
|
119
149
|
## Prerequisites
|
|
120
150
|
|
|
121
|
-
All components assume `@proveanything/smartlinks` is
|
|
151
|
+
All components assume `@proveanything/smartlinks` is initialised in your app
|
|
152
|
+
via `SL.initializeApi()`. Admin components (RecordsAdminShell, AssetPicker
|
|
153
|
+
upload, etc.) call the SDK with `admin: true` — do not render them in
|
|
154
|
+
public-facing views.
|
|
122
155
|
|
|
123
|
-
## Tree
|
|
156
|
+
## Tree shaking
|
|
124
157
|
|
|
125
|
-
Each component
|
|
158
|
+
Each component has its own subpath export — bundle only what you use:
|
|
126
159
|
|
|
127
160
|
```tsx
|
|
128
|
-
//
|
|
129
|
-
import {
|
|
161
|
+
// Bundles only RecordsAdmin
|
|
162
|
+
import { RecordsAdminShell } from '@proveanything/smartlinks-utils-ui/records-admin';
|
|
130
163
|
|
|
131
|
-
//
|
|
132
|
-
import {
|
|
164
|
+
// Barrel import — bundler tree-shakes the rest
|
|
165
|
+
import { RecordsAdminShell } from '@proveanything/smartlinks-utils-ui';
|
|
133
166
|
```
|
|
134
167
|
|
|
168
|
+
If you use subpath imports, import `styles.css` separately — subpaths do not
|
|
169
|
+
pull it in automatically.
|
|
170
|
+
|
|
135
171
|
## Development
|
|
136
172
|
|
|
137
173
|
```bash
|
|
138
174
|
cd packages/smartlinks-ui
|
|
139
175
|
npm install
|
|
140
|
-
npm run build #
|
|
141
|
-
npm run dev #
|
|
176
|
+
npm run build # tsup
|
|
177
|
+
npm run dev # watch mode
|
|
142
178
|
```
|
|
143
179
|
|
|
144
180
|
## License
|
|
145
181
|
|
|
146
|
-
MIT
|
|
182
|
+
MIT
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/* src/components/RecordsAdmin/shell/tokens.css */
|
|
2
|
+
:root {
|
|
3
|
+
--ra-status-own: var(--ra-emerald, 142 71% 45%);
|
|
4
|
+
--ra-status-shared: var(--ra-amber, 38 92% 50%);
|
|
5
|
+
--ra-status-missing: var(--muted-foreground, 0 0% 50%);
|
|
6
|
+
--ra-accent: var(--primary, 222 47% 11%);
|
|
7
|
+
--ra-surface: var(--card, 0 0% 100%);
|
|
8
|
+
--ra-border: var(--border, 0 0% 90%);
|
|
9
|
+
--ra-text: var(--foreground, 0 0% 10%);
|
|
10
|
+
--ra-muted: var(--muted, 0 0% 96%);
|
|
11
|
+
--ra-muted-text: var(--muted-foreground, 0 0% 40%);
|
|
12
|
+
--ra-radius: 0.5rem;
|
|
13
|
+
--ra-dot-size: 0.5rem;
|
|
14
|
+
}
|
|
15
|
+
.ra-shell {
|
|
16
|
+
color: hsl(var(--ra-text));
|
|
17
|
+
background: hsl(var(--ra-surface));
|
|
18
|
+
}
|
|
19
|
+
.ra-status-dot {
|
|
20
|
+
display: inline-block;
|
|
21
|
+
width: var(--ra-dot-size);
|
|
22
|
+
height: var(--ra-dot-size);
|
|
23
|
+
border-radius: 9999px;
|
|
24
|
+
flex-shrink: 0;
|
|
25
|
+
}
|
|
26
|
+
.ra-status-own {
|
|
27
|
+
background: hsl(var(--ra-status-own));
|
|
28
|
+
}
|
|
29
|
+
.ra-status-shared {
|
|
30
|
+
background: hsl(var(--ra-status-shared));
|
|
31
|
+
}
|
|
32
|
+
.ra-status-missing {
|
|
33
|
+
background: hsl(var(--ra-status-missing) / 0.4);
|
|
34
|
+
border: 1px solid hsl(var(--ra-status-missing) / 0.6);
|
|
35
|
+
}
|
|
36
|
+
.ra-row-active {
|
|
37
|
+
background: hsl(var(--ra-accent) / 0.08);
|
|
38
|
+
border-color: hsl(var(--ra-accent) / 0.4) !important;
|
|
39
|
+
}
|
|
40
|
+
/*# sourceMappingURL=index.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/RecordsAdmin/shell/tokens.css"],"sourcesContent":["/* Records Admin shell tokens — apps may override via :root */\r\n:root {\r\n --ra-status-own: var(--ra-emerald, 142 71% 45%);\r\n --ra-status-shared: var(--ra-amber, 38 92% 50%);\r\n --ra-status-missing: var(--muted-foreground, 0 0% 50%);\r\n --ra-accent: var(--primary, 222 47% 11%);\r\n --ra-surface: var(--card, 0 0% 100%);\r\n --ra-border: var(--border, 0 0% 90%);\r\n --ra-text: var(--foreground, 0 0% 10%);\r\n --ra-muted: var(--muted, 0 0% 96%);\r\n --ra-muted-text: var(--muted-foreground, 0 0% 40%);\r\n --ra-radius: 0.5rem;\r\n --ra-dot-size: 0.5rem;\r\n}\r\n\r\n.ra-shell {\r\n color: hsl(var(--ra-text));\r\n background: hsl(var(--ra-surface));\r\n}\r\n\r\n.ra-status-dot {\r\n display: inline-block;\r\n width: var(--ra-dot-size);\r\n height: var(--ra-dot-size);\r\n border-radius: 9999px;\r\n flex-shrink: 0;\r\n}\r\n.ra-status-own { background: hsl(var(--ra-status-own)); }\r\n.ra-status-shared { background: hsl(var(--ra-status-shared)); }\r\n.ra-status-missing { background: hsl(var(--ra-status-missing) / 0.4); border: 1px solid hsl(var(--ra-status-missing) / 0.6); }\r\n\r\n.ra-row-active {\r\n background: hsl(var(--ra-accent) / 0.08);\r\n border-color: hsl(var(--ra-accent) / 0.4) !important;\r\n}"],"mappings":";AACA;AACE,mBAAiB,IAAI,YAAY,EAAE,IAAI,IAAI;AAC3C,sBAAoB,IAAI,UAAU,EAAE,GAAG,IAAI;AAC3C,uBAAqB,IAAI,kBAAkB,EAAE,EAAE,GAAG;AAClD,eAAa,IAAI,SAAS,EAAE,IAAI,IAAI;AACpC,gBAAc,IAAI,MAAM,EAAE,EAAE,GAAG;AAC/B,eAAa,IAAI,QAAQ,EAAE,EAAE,GAAG;AAChC,aAAW,IAAI,YAAY,EAAE,EAAE,GAAG;AAClC,cAAY,IAAI,OAAO,EAAE,EAAE,GAAG;AAC9B,mBAAiB,IAAI,kBAAkB,EAAE,EAAE,GAAG;AAC9C,eAAa;AACb,iBAAe;AACjB;AAEA,CAAC;AACC,SAAO,IAAI,IAAI;AACf,cAAY,IAAI,IAAI;AACtB;AAEA,CAAC;AACC,WAAS;AACT,SAAO,IAAI;AACX,UAAQ,IAAI;AACZ,iBAAe;AACf,eAAa;AACf;AACA,CAAC;AAAgB,cAAY,IAAI,IAAI;AAAmB;AACxD,CAAC;AAAmB,cAAY,IAAI,IAAI;AAAsB;AAC9D,CAAC;AAAoB,cAAY,IAAI,IAAI,qBAAqB,EAAE;AAAM,UAAQ,IAAI,MAAM,IAAI,IAAI,qBAAqB,EAAE;AAAM;AAE7H,CAAC;AACC,cAAY,IAAI,IAAI,aAAa,EAAE;AACnC,gBAAc,IAAI,IAAI,aAAa,EAAE;AACvC;","names":[]}
|