@colixsystems/widget-sdk 0.170.0 → 0.173.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/README.md +69 -3
- package/dist/contract.cjs +62 -4
- package/dist/contract.js +62 -4
- package/dist/detail-parts-tokens.js +91 -0
- package/dist/detail-parts-view.js +392 -0
- package/dist/detail-parts.js +15 -0
- package/dist/detail-parts.native.js +15 -0
- package/dist/index.d.ts +129 -4
- package/dist/index.js +4 -1
- package/dist/index.native.js +4 -1
- package/dist/initials.js +17 -0
- package/dist/list-tokens.js +31 -0
- package/dist/list-view.js +84 -18
- package/dist/list.js +3 -3
- package/dist/list.native.js +4 -4
- package/dist/webbundle.js +4 -0
- package/package.json +1 -1
- package/src/webbundle.js +4 -0
package/dist/list-view.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// The ONE implementation behind the `<List>`, `<ListRow>` and
|
|
2
|
-
// SDK primitives. The platform bindings (`list.js` / `list.native.js`) differ
|
|
1
|
+
// The ONE implementation behind the `<List>`, `<ListRow>`, `<ListHeader>` and
|
|
2
|
+
// `<EmptyState>` SDK primitives. The platform bindings (`list.js` / `list.native.js`) differ
|
|
3
3
|
// only in where the primitives come from, so the hosts cannot drift.
|
|
4
4
|
//
|
|
5
5
|
// Every widget drawing a list of records used to hand-roll its rows, so two
|
|
@@ -10,7 +10,13 @@ import React from "react";
|
|
|
10
10
|
import { useHostTheme } from "./hooks.js";
|
|
11
11
|
import { DEFAULT_THEME_TOKENS } from "./_theme-tokens.js";
|
|
12
12
|
import { Icon } from "./icon.js";
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
resolveListTokens,
|
|
15
|
+
listRowFrame,
|
|
16
|
+
listSideEdgeWidth,
|
|
17
|
+
LIST_TOKEN_NAMES,
|
|
18
|
+
LIST_SELECTED_BAR_WIDTH,
|
|
19
|
+
} from "./list-tokens.js";
|
|
14
20
|
import { textRoleStyle } from "./text-roles.js";
|
|
15
21
|
|
|
16
22
|
// Outside a widget host (a test, a preview) the defaults still paint a row.
|
|
@@ -26,15 +32,49 @@ function listOverrides(props) {
|
|
|
26
32
|
return out;
|
|
27
33
|
}
|
|
28
34
|
|
|
35
|
+
function soleElement(children) {
|
|
36
|
+
const parts = React.Children.toArray(children);
|
|
37
|
+
return parts.length === 1 && React.isValidElement(parts[0]) ? parts[0] : null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const HORIZONTAL_PADDING = [
|
|
41
|
+
"padding",
|
|
42
|
+
"paddingHorizontal",
|
|
43
|
+
"paddingLeft",
|
|
44
|
+
"paddingStart",
|
|
45
|
+
"paddingInline",
|
|
46
|
+
"paddingInlineStart",
|
|
47
|
+
];
|
|
48
|
+
|
|
29
49
|
/**
|
|
30
50
|
* Bind the shared list components to one platform's primitives.
|
|
31
51
|
*
|
|
32
|
-
* @param {{View: any, Text: any, Pressable: any}} rn
|
|
52
|
+
* @param {{View: any, Text: any, Pressable: any, StyleSheet: any}} rn
|
|
33
53
|
*/
|
|
34
54
|
export function makeList(rn) {
|
|
35
|
-
const { View, Text, Pressable } = rn;
|
|
55
|
+
const { View, Text, Pressable, StyleSheet } = rn;
|
|
36
56
|
const ListContext = React.createContext(null);
|
|
37
57
|
|
|
58
|
+
function useRowTokens(props) {
|
|
59
|
+
const theme = useListTheme();
|
|
60
|
+
const inherited = React.useContext(ListContext);
|
|
61
|
+
return [theme, resolveListTokens(theme, { ...inherited, ...listOverrides(props) })];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// A lone row View spans the row, as the title block does. Anything
|
|
65
|
+
// else (cells, a component rendering cells) stays in the row as before.
|
|
66
|
+
function customBody(children) {
|
|
67
|
+
const only = soleElement(children);
|
|
68
|
+
return only && only.type === View
|
|
69
|
+
? React.createElement(View, { style: { flex: 1, minWidth: 0 } }, only)
|
|
70
|
+
: children;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function setsOwnInset(style) {
|
|
74
|
+
const flat = StyleSheet.flatten(style) || {};
|
|
75
|
+
return HORIZONTAL_PADDING.some((key) => flat[key] !== undefined);
|
|
76
|
+
}
|
|
77
|
+
|
|
38
78
|
function List(props) {
|
|
39
79
|
const { children, style, testID } = props;
|
|
40
80
|
const theme = useListTheme();
|
|
@@ -72,12 +112,7 @@ export function makeList(rn) {
|
|
|
72
112
|
testID,
|
|
73
113
|
children,
|
|
74
114
|
} = props;
|
|
75
|
-
const theme =
|
|
76
|
-
const inherited = React.useContext(ListContext);
|
|
77
|
-
const tokens = resolveListTokens(theme, {
|
|
78
|
-
...inherited,
|
|
79
|
-
...listOverrides(props),
|
|
80
|
-
});
|
|
115
|
+
const [theme, tokens] = useRowTokens(props);
|
|
81
116
|
const { colors, spacing, typography } = theme;
|
|
82
117
|
|
|
83
118
|
const pressable = typeof onPress === "function";
|
|
@@ -90,10 +125,8 @@ export function makeList(rn) {
|
|
|
90
125
|
? { borderBottomWidth: tokens.dividerWidth, borderColor: tokens.dividerColor }
|
|
91
126
|
: null;
|
|
92
127
|
const rowStyle = {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
gap: spacing.md,
|
|
96
|
-
paddingHorizontal: tokens.rowPadding,
|
|
128
|
+
// An inset the widget sets itself is left exactly as it asked.
|
|
129
|
+
...listRowFrame(tokens, spacing, selected && !setsOwnInset(style)),
|
|
97
130
|
paddingVertical: tokens.rowPadding,
|
|
98
131
|
// A dense look may shrink a static row, never a tap target.
|
|
99
132
|
minHeight: pressable ? Math.max(tokens.rowMinHeight, 44) : tokens.rowMinHeight,
|
|
@@ -104,7 +137,7 @@ export function makeList(rn) {
|
|
|
104
137
|
...(selected
|
|
105
138
|
? {
|
|
106
139
|
backgroundColor: tokens.selectedBackground,
|
|
107
|
-
borderLeftWidth:
|
|
140
|
+
borderLeftWidth: LIST_SELECTED_BAR_WIDTH,
|
|
108
141
|
borderLeftColor: tokens.selectedAccent,
|
|
109
142
|
}
|
|
110
143
|
: null),
|
|
@@ -112,7 +145,7 @@ export function makeList(rn) {
|
|
|
112
145
|
|
|
113
146
|
const body =
|
|
114
147
|
children !== undefined
|
|
115
|
-
? children
|
|
148
|
+
? customBody(children)
|
|
116
149
|
: React.createElement(
|
|
117
150
|
View,
|
|
118
151
|
{ style: { flex: 1, gap: 2 } },
|
|
@@ -174,6 +207,39 @@ export function makeList(rn) {
|
|
|
174
207
|
}
|
|
175
208
|
ListRow.displayName = "ListRow";
|
|
176
209
|
|
|
210
|
+
// A table's column labels: a ListRow's frame and body slot with none of its
|
|
211
|
+
// row chrome, so each label sits over its column.
|
|
212
|
+
function ListHeader(props) {
|
|
213
|
+
const { leading, trailing, divider = true, accessibilityLabel, style, testID, children } = props;
|
|
214
|
+
const [theme, tokens] = useRowTokens(props);
|
|
215
|
+
const { spacing } = theme;
|
|
216
|
+
// Transparent side edges stand in for a tile's outline.
|
|
217
|
+
const side = listSideEdgeWidth(tokens);
|
|
218
|
+
const headerStyle = {
|
|
219
|
+
...listRowFrame(tokens, spacing),
|
|
220
|
+
paddingVertical: Math.min(tokens.rowPadding, spacing.sm),
|
|
221
|
+
...(side > 0
|
|
222
|
+
? { borderLeftWidth: side, borderRightWidth: side, borderColor: "transparent" }
|
|
223
|
+
: null),
|
|
224
|
+
...(divider && tokens.dividerWidth > 0
|
|
225
|
+
? { borderBottomWidth: tokens.dividerWidth, borderBottomColor: tokens.dividerColor }
|
|
226
|
+
: null),
|
|
227
|
+
};
|
|
228
|
+
return React.createElement(
|
|
229
|
+
View,
|
|
230
|
+
{
|
|
231
|
+
style: [headerStyle, style],
|
|
232
|
+
testID,
|
|
233
|
+
accessibilityLabel,
|
|
234
|
+
accessible: accessibilityLabel ? true : undefined,
|
|
235
|
+
},
|
|
236
|
+
leading || null,
|
|
237
|
+
customBody(children),
|
|
238
|
+
trailing || null,
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
ListHeader.displayName = "ListHeader";
|
|
242
|
+
|
|
177
243
|
function EmptyState({ icon = "inbox", title, message, children, style, testID }) {
|
|
178
244
|
const { colors, spacing, radii, typography } = useListTheme();
|
|
179
245
|
return React.createElement(
|
|
@@ -211,5 +277,5 @@ export function makeList(rn) {
|
|
|
211
277
|
}
|
|
212
278
|
EmptyState.displayName = "EmptyState";
|
|
213
279
|
|
|
214
|
-
return { List, ListRow, EmptyState };
|
|
280
|
+
return { List, ListRow, ListHeader, EmptyState };
|
|
215
281
|
}
|
package/dist/list.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// `<List>`, `<ListRow>`, `<EmptyState>` (web). Binds
|
|
2
|
-
// react-native-web; see ./primitives.js for why not the bare specifier.
|
|
1
|
+
// `<List>`, `<ListRow>`, `<ListHeader>`, `<EmptyState>` (web). Binds
|
|
2
|
+
// ./list-view.js to react-native-web; see ./primitives.js for why not the bare specifier.
|
|
3
3
|
|
|
4
4
|
import * as ReactNative from "react-native-web";
|
|
5
5
|
import { makeList } from "./list-view.js";
|
|
6
6
|
|
|
7
|
-
export const { List, ListRow, EmptyState } = makeList(ReactNative);
|
|
7
|
+
export const { List, ListRow, ListHeader, EmptyState } = makeList(ReactNative);
|
package/dist/list.native.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// `<List>`, `<ListRow>`, `<EmptyState>` (native). Binds
|
|
2
|
-
// React Native's own primitives; only the import differs from ./list.js.
|
|
1
|
+
// `<List>`, `<ListRow>`, `<ListHeader>`, `<EmptyState>` (native). Binds
|
|
2
|
+
// ./list-view.js to React Native's own primitives; only the import differs from ./list.js.
|
|
3
3
|
|
|
4
|
-
import { View, Text, Pressable } from "react-native";
|
|
4
|
+
import { View, Text, Pressable, StyleSheet } from "react-native";
|
|
5
5
|
import { makeList } from "./list-view.js";
|
|
6
6
|
|
|
7
|
-
export const { List, ListRow, EmptyState } = makeList({ View, Text, Pressable });
|
|
7
|
+
export const { List, ListRow, ListHeader, EmptyState } = makeList({ View, Text, Pressable, StyleSheet });
|
package/dist/webbundle.js
CHANGED
|
@@ -90,12 +90,15 @@ function cssInjectPlugin() {
|
|
|
90
90
|
* packer passes the frontend's `node_modules` (where the vetted web packages
|
|
91
91
|
* are installed per the adding-vetted-packages skill) so the bundle resolves
|
|
92
92
|
* them no matter the invoking CWD.
|
|
93
|
+
* @param {boolean} [opts.minify] minify the output for production serving.
|
|
94
|
+
* Off by default so the dev server's bundle stays readable.
|
|
93
95
|
* @returns {Promise<string>} the bundled ESM source.
|
|
94
96
|
*/
|
|
95
97
|
export async function bundleWebEntry({
|
|
96
98
|
entryPath,
|
|
97
99
|
external = hostExternalSpecifiers(),
|
|
98
100
|
nodePaths = [],
|
|
101
|
+
minify = false,
|
|
99
102
|
}) {
|
|
100
103
|
const esbuild = await loadEsbuild();
|
|
101
104
|
const result = await esbuild.build({
|
|
@@ -138,6 +141,7 @@ export async function bundleWebEntry({
|
|
|
138
141
|
// adds extra roots so a packer invoked from the repo root still resolves the
|
|
139
142
|
// vetted web packages installed under frontend/node_modules.
|
|
140
143
|
nodePaths,
|
|
144
|
+
minify,
|
|
141
145
|
logLevel: "silent",
|
|
142
146
|
});
|
|
143
147
|
const out = result.outputFiles?.[0];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colixsystems/widget-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.173.1",
|
|
4
4
|
"description": "Common widget interface for AppStudio. Implements WidgetManifest, WidgetContext, property schema, and helper hooks.",
|
|
5
5
|
"homepage": "https://github.com/Colix-AB/AppStudio",
|
|
6
6
|
"type": "module",
|
package/src/webbundle.js
CHANGED
|
@@ -90,12 +90,15 @@ function cssInjectPlugin() {
|
|
|
90
90
|
* packer passes the frontend's `node_modules` (where the vetted web packages
|
|
91
91
|
* are installed per the adding-vetted-packages skill) so the bundle resolves
|
|
92
92
|
* them no matter the invoking CWD.
|
|
93
|
+
* @param {boolean} [opts.minify] minify the output for production serving.
|
|
94
|
+
* Off by default so the dev server's bundle stays readable.
|
|
93
95
|
* @returns {Promise<string>} the bundled ESM source.
|
|
94
96
|
*/
|
|
95
97
|
export async function bundleWebEntry({
|
|
96
98
|
entryPath,
|
|
97
99
|
external = hostExternalSpecifiers(),
|
|
98
100
|
nodePaths = [],
|
|
101
|
+
minify = false,
|
|
99
102
|
}) {
|
|
100
103
|
const esbuild = await loadEsbuild();
|
|
101
104
|
const result = await esbuild.build({
|
|
@@ -138,6 +141,7 @@ export async function bundleWebEntry({
|
|
|
138
141
|
// adds extra roots so a packer invoked from the repo root still resolves the
|
|
139
142
|
// vetted web packages installed under frontend/node_modules.
|
|
140
143
|
nodePaths,
|
|
144
|
+
minify,
|
|
141
145
|
logLevel: "silent",
|
|
142
146
|
});
|
|
143
147
|
const out = result.outputFiles?.[0];
|