@object-ui/layout 0.1.1 → 2.0.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/.turbo/turbo-build.log +21 -0
- package/CHANGELOG.md +14 -0
- package/dist/index.js +279 -218
- package/dist/index.umd.cjs +2 -2
- package/dist/layout/src/AppShell.d.ts +24 -1
- package/dist/layout/src/Page.d.ts +5 -1
- package/dist/layout/src/PageCard.d.ts +2 -0
- package/dist/layout/src/SidebarNav.d.ts +2 -1
- package/dist/layout/src/index.d.ts +1 -0
- package/package.json +9 -8
- package/src/AppShell.tsx +113 -4
- package/src/Page.tsx +7 -2
- package/src/PageCard.tsx +12 -0
- package/src/SidebarNav.tsx +3 -2
- package/src/index.ts +17 -8
- package/vite.config.ts +3 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
> @object-ui/layout@2.0.0 build /home/runner/work/objectui/objectui/packages/layout
|
|
3
|
+
> vite build
|
|
4
|
+
|
|
5
|
+
[36mvite v7.3.1 [32mbuilding client environment for production...[36m[39m
|
|
6
|
+
transforming...
|
|
7
|
+
[32m✓[39m 15 modules transformed.
|
|
8
|
+
rendering chunks...
|
|
9
|
+
[32m
|
|
10
|
+
[36m[vite:dts][32m Start generate declaration files...[39m
|
|
11
|
+
computing gzip size...
|
|
12
|
+
[2mdist/[22m[36mindex.js [39m[1m[2m14.99 kB[22m[1m[22m[2m │ gzip: 4.61 kB[22m
|
|
13
|
+
[32m[36m[vite:dts][32m Declaration files built in 21839ms.
|
|
14
|
+
[39m
|
|
15
|
+
[33mNo name was provided for external module "@object-ui/core" in "output.globals" – guessing "core".[39m
|
|
16
|
+
[33mNo name was provided for external module "react" in "output.globals" – guessing "require$$0".[39m
|
|
17
|
+
[33mNo name was provided for external module "@object-ui/components" in "output.globals" – guessing "components".[39m
|
|
18
|
+
[33mNo name was provided for external module "@object-ui/react" in "output.globals" – guessing "react".[39m
|
|
19
|
+
[33mNo name was provided for external module "react-router-dom" in "output.globals" – guessing "reactRouterDom".[39m
|
|
20
|
+
[2mdist/[22m[36mindex.umd.cjs [39m[1m[2m10.67 kB[22m[1m[22m[2m │ gzip: 4.12 kB[22m
|
|
21
|
+
[32m✓ built in 23.26s[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @object-ui/layout
|
|
2
2
|
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- b859617: Release v1.0.0 — unify all package versions to 1.0.0
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [b859617]
|
|
12
|
+
- @object-ui/types@2.0.0
|
|
13
|
+
- @object-ui/core@2.0.0
|
|
14
|
+
- @object-ui/react@2.0.0
|
|
15
|
+
- @object-ui/components@2.0.0
|
|
16
|
+
|
|
3
17
|
## 0.1.1
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -1,152 +1,152 @@
|
|
|
1
|
-
import { ComponentRegistry as
|
|
2
|
-
import
|
|
3
|
-
import { cn as
|
|
4
|
-
import { SchemaRenderer as
|
|
5
|
-
import { useLocation as
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
function
|
|
9
|
-
if (
|
|
10
|
-
|
|
11
|
-
var
|
|
12
|
-
function
|
|
13
|
-
var
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
for (var
|
|
17
|
-
|
|
18
|
-
} else
|
|
19
|
-
return
|
|
20
|
-
$$typeof:
|
|
21
|
-
type:
|
|
22
|
-
key:
|
|
23
|
-
ref:
|
|
24
|
-
props:
|
|
1
|
+
import { ComponentRegistry as R } from "@object-ui/core";
|
|
2
|
+
import ne, { useEffect as oe } from "react";
|
|
3
|
+
import { cn as T, SidebarProvider as se, SidebarInset as le, SidebarTrigger as ce, Sidebar as ie, SidebarContent as ue, SidebarGroup as fe, SidebarGroupLabel as de, SidebarGroupContent as me, SidebarMenu as pe, SidebarMenuItem as be, SidebarMenuButton as xe } from "@object-ui/components";
|
|
4
|
+
import { SchemaRenderer as ye } from "@object-ui/react";
|
|
5
|
+
import { useLocation as ve, NavLink as he } from "react-router-dom";
|
|
6
|
+
var j = { exports: {} }, x = {};
|
|
7
|
+
var W;
|
|
8
|
+
function Ee() {
|
|
9
|
+
if (W) return x;
|
|
10
|
+
W = 1;
|
|
11
|
+
var r = /* @__PURE__ */ Symbol.for("react.transitional.element"), c = /* @__PURE__ */ Symbol.for("react.fragment");
|
|
12
|
+
function a(o, l, n) {
|
|
13
|
+
var d = null;
|
|
14
|
+
if (n !== void 0 && (d = "" + n), l.key !== void 0 && (d = "" + l.key), "key" in l) {
|
|
15
|
+
n = {};
|
|
16
|
+
for (var m in l)
|
|
17
|
+
m !== "key" && (n[m] = l[m]);
|
|
18
|
+
} else n = l;
|
|
19
|
+
return l = n.ref, {
|
|
20
|
+
$$typeof: r,
|
|
21
|
+
type: o,
|
|
22
|
+
key: d,
|
|
23
|
+
ref: l !== void 0 ? l : null,
|
|
24
|
+
props: n
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
-
return
|
|
27
|
+
return x.Fragment = c, x.jsx = a, x.jsxs = a, x;
|
|
28
28
|
}
|
|
29
|
-
var
|
|
30
|
-
var
|
|
31
|
-
function
|
|
32
|
-
return
|
|
33
|
-
function
|
|
29
|
+
var y = {};
|
|
30
|
+
var q;
|
|
31
|
+
function _e() {
|
|
32
|
+
return q || (q = 1, process.env.NODE_ENV !== "production" && (function() {
|
|
33
|
+
function r(e) {
|
|
34
34
|
if (e == null) return null;
|
|
35
35
|
if (typeof e == "function")
|
|
36
|
-
return e.$$typeof ===
|
|
36
|
+
return e.$$typeof === re ? null : e.displayName || e.name || null;
|
|
37
37
|
if (typeof e == "string") return e;
|
|
38
38
|
switch (e) {
|
|
39
|
-
case
|
|
39
|
+
case g:
|
|
40
40
|
return "Fragment";
|
|
41
|
-
case
|
|
41
|
+
case z:
|
|
42
42
|
return "Profiler";
|
|
43
|
-
case
|
|
43
|
+
case V:
|
|
44
44
|
return "StrictMode";
|
|
45
|
-
case B:
|
|
46
|
-
return "Suspense";
|
|
47
45
|
case Z:
|
|
46
|
+
return "Suspense";
|
|
47
|
+
case Q:
|
|
48
48
|
return "SuspenseList";
|
|
49
|
-
case
|
|
49
|
+
case ee:
|
|
50
50
|
return "Activity";
|
|
51
51
|
}
|
|
52
52
|
if (typeof e == "object")
|
|
53
53
|
switch (typeof e.tag == "number" && console.error(
|
|
54
54
|
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
|
|
55
55
|
), e.$$typeof) {
|
|
56
|
-
case
|
|
56
|
+
case J:
|
|
57
57
|
return "Portal";
|
|
58
58
|
case X:
|
|
59
59
|
return e.displayName || "Context";
|
|
60
|
-
case z:
|
|
61
|
-
return (e._context.displayName || "Context") + ".Consumer";
|
|
62
60
|
case H:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return
|
|
67
|
-
case
|
|
68
|
-
|
|
61
|
+
return (e._context.displayName || "Context") + ".Consumer";
|
|
62
|
+
case B:
|
|
63
|
+
var t = e.render;
|
|
64
|
+
return e = e.displayName, e || (e = t.displayName || t.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e;
|
|
65
|
+
case K:
|
|
66
|
+
return t = e.displayName || null, t !== null ? t : r(e.type) || "Memo";
|
|
67
|
+
case S:
|
|
68
|
+
t = e._payload, e = e._init;
|
|
69
69
|
try {
|
|
70
|
-
return
|
|
70
|
+
return r(e(t));
|
|
71
71
|
} catch {
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
return null;
|
|
75
75
|
}
|
|
76
|
-
function
|
|
76
|
+
function c(e) {
|
|
77
77
|
return "" + e;
|
|
78
78
|
}
|
|
79
|
-
function
|
|
79
|
+
function a(e) {
|
|
80
80
|
try {
|
|
81
|
-
|
|
82
|
-
var
|
|
81
|
+
c(e);
|
|
82
|
+
var t = !1;
|
|
83
83
|
} catch {
|
|
84
|
-
|
|
84
|
+
t = !0;
|
|
85
85
|
}
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
var
|
|
89
|
-
return
|
|
90
|
-
|
|
86
|
+
if (t) {
|
|
87
|
+
t = console;
|
|
88
|
+
var i = t.error, u = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object";
|
|
89
|
+
return i.call(
|
|
90
|
+
t,
|
|
91
91
|
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
|
|
92
|
-
|
|
93
|
-
),
|
|
92
|
+
u
|
|
93
|
+
), c(e);
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
-
function
|
|
97
|
-
if (e ===
|
|
98
|
-
if (typeof e == "object" && e !== null && e.$$typeof ===
|
|
96
|
+
function o(e) {
|
|
97
|
+
if (e === g) return "<>";
|
|
98
|
+
if (typeof e == "object" && e !== null && e.$$typeof === S)
|
|
99
99
|
return "<...>";
|
|
100
100
|
try {
|
|
101
|
-
var
|
|
102
|
-
return
|
|
101
|
+
var t = r(e);
|
|
102
|
+
return t ? "<" + t + ">" : "<...>";
|
|
103
103
|
} catch {
|
|
104
104
|
return "<...>";
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
|
-
function
|
|
108
|
-
var e =
|
|
107
|
+
function l() {
|
|
108
|
+
var e = P.A;
|
|
109
109
|
return e === null ? null : e.getOwner();
|
|
110
110
|
}
|
|
111
|
-
function
|
|
111
|
+
function n() {
|
|
112
112
|
return Error("react-stack-top-frame");
|
|
113
113
|
}
|
|
114
|
-
function
|
|
115
|
-
if (
|
|
116
|
-
var
|
|
117
|
-
if (
|
|
114
|
+
function d(e) {
|
|
115
|
+
if (I.call(e, "key")) {
|
|
116
|
+
var t = Object.getOwnPropertyDescriptor(e, "key").get;
|
|
117
|
+
if (t && t.isReactWarning) return !1;
|
|
118
118
|
}
|
|
119
119
|
return e.key !== void 0;
|
|
120
120
|
}
|
|
121
|
-
function
|
|
122
|
-
function
|
|
123
|
-
|
|
121
|
+
function m(e, t) {
|
|
122
|
+
function i() {
|
|
123
|
+
Y || (Y = !0, console.error(
|
|
124
124
|
"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
|
|
125
|
-
|
|
125
|
+
t
|
|
126
126
|
));
|
|
127
127
|
}
|
|
128
|
-
|
|
129
|
-
get:
|
|
128
|
+
i.isReactWarning = !0, Object.defineProperty(e, "key", {
|
|
129
|
+
get: i,
|
|
130
130
|
configurable: !0
|
|
131
131
|
});
|
|
132
132
|
}
|
|
133
|
-
function
|
|
134
|
-
var e =
|
|
135
|
-
return
|
|
133
|
+
function v() {
|
|
134
|
+
var e = r(this.type);
|
|
135
|
+
return L[e] || (L[e] = !0, console.error(
|
|
136
136
|
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
|
|
137
137
|
)), e = this.props.ref, e !== void 0 ? e : null;
|
|
138
138
|
}
|
|
139
|
-
function
|
|
140
|
-
var
|
|
139
|
+
function h(e, t, i, u, _, A) {
|
|
140
|
+
var f = i.ref;
|
|
141
141
|
return e = {
|
|
142
|
-
$$typeof:
|
|
142
|
+
$$typeof: $,
|
|
143
143
|
type: e,
|
|
144
|
-
key:
|
|
145
|
-
props:
|
|
146
|
-
_owner:
|
|
147
|
-
}, (
|
|
144
|
+
key: t,
|
|
145
|
+
props: i,
|
|
146
|
+
_owner: u
|
|
147
|
+
}, (f !== void 0 ? f : null) !== null ? Object.defineProperty(e, "ref", {
|
|
148
148
|
enumerable: !1,
|
|
149
|
-
get:
|
|
149
|
+
get: v
|
|
150
150
|
}) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", {
|
|
151
151
|
configurable: !1,
|
|
152
152
|
enumerable: !1,
|
|
@@ -166,197 +166,258 @@ function Ee() {
|
|
|
166
166
|
configurable: !1,
|
|
167
167
|
enumerable: !1,
|
|
168
168
|
writable: !0,
|
|
169
|
-
value:
|
|
169
|
+
value: A
|
|
170
170
|
}), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e;
|
|
171
171
|
}
|
|
172
|
-
function
|
|
173
|
-
var
|
|
174
|
-
if (
|
|
175
|
-
if (
|
|
176
|
-
if (
|
|
177
|
-
for (
|
|
178
|
-
|
|
179
|
-
Object.freeze && Object.freeze(
|
|
172
|
+
function p(e, t, i, u, _, A) {
|
|
173
|
+
var f = t.children;
|
|
174
|
+
if (f !== void 0)
|
|
175
|
+
if (u)
|
|
176
|
+
if (te(f)) {
|
|
177
|
+
for (u = 0; u < f.length; u++)
|
|
178
|
+
O(f[u]);
|
|
179
|
+
Object.freeze && Object.freeze(f);
|
|
180
180
|
} else
|
|
181
181
|
console.error(
|
|
182
182
|
"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
|
|
183
183
|
);
|
|
184
|
-
else
|
|
185
|
-
if (
|
|
186
|
-
|
|
187
|
-
var
|
|
188
|
-
return
|
|
184
|
+
else O(f);
|
|
185
|
+
if (I.call(t, "key")) {
|
|
186
|
+
f = r(e);
|
|
187
|
+
var b = Object.keys(t).filter(function(ae) {
|
|
188
|
+
return ae !== "key";
|
|
189
189
|
});
|
|
190
|
-
|
|
190
|
+
u = 0 < b.length ? "{key: someKey, " + b.join(": ..., ") + ": ...}" : "{key: someKey}", D[f + u] || (b = 0 < b.length ? "{" + b.join(": ..., ") + ": ...}" : "{}", console.error(
|
|
191
191
|
`A props object containing a "key" prop is being spread into JSX:
|
|
192
192
|
let props = %s;
|
|
193
193
|
<%s {...props} />
|
|
194
194
|
React keys must be passed directly to JSX without using spread:
|
|
195
195
|
let props = %s;
|
|
196
196
|
<%s key={someKey} {...props} />`,
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
),
|
|
197
|
+
u,
|
|
198
|
+
f,
|
|
199
|
+
b,
|
|
200
|
+
f
|
|
201
|
+
), D[f + u] = !0);
|
|
202
202
|
}
|
|
203
|
-
if (
|
|
204
|
-
|
|
205
|
-
for (var
|
|
206
|
-
|
|
207
|
-
} else
|
|
208
|
-
return
|
|
209
|
-
|
|
203
|
+
if (f = null, i !== void 0 && (a(i), f = "" + i), d(t) && (a(t.key), f = "" + t.key), "key" in t) {
|
|
204
|
+
i = {};
|
|
205
|
+
for (var N in t)
|
|
206
|
+
N !== "key" && (i[N] = t[N]);
|
|
207
|
+
} else i = t;
|
|
208
|
+
return f && m(
|
|
209
|
+
i,
|
|
210
210
|
typeof e == "function" ? e.displayName || e.name || "Unknown" : e
|
|
211
|
-
),
|
|
211
|
+
), h(
|
|
212
212
|
e,
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
213
|
+
f,
|
|
214
|
+
i,
|
|
215
|
+
l(),
|
|
216
216
|
_,
|
|
217
|
-
|
|
217
|
+
A
|
|
218
218
|
);
|
|
219
219
|
}
|
|
220
|
-
function
|
|
221
|
-
|
|
220
|
+
function O(e) {
|
|
221
|
+
C(e) ? e._store && (e._store.validated = 1) : typeof e == "object" && e !== null && e.$$typeof === S && (e._payload.status === "fulfilled" ? C(e._payload.value) && e._payload.value._store && (e._payload.value._store.validated = 1) : e._store && (e._store.validated = 1));
|
|
222
222
|
}
|
|
223
|
-
function
|
|
224
|
-
return typeof e == "object" && e !== null && e.$$typeof ===
|
|
223
|
+
function C(e) {
|
|
224
|
+
return typeof e == "object" && e !== null && e.$$typeof === $;
|
|
225
225
|
}
|
|
226
|
-
var
|
|
226
|
+
var E = ne, $ = /* @__PURE__ */ Symbol.for("react.transitional.element"), J = /* @__PURE__ */ Symbol.for("react.portal"), g = /* @__PURE__ */ Symbol.for("react.fragment"), V = /* @__PURE__ */ Symbol.for("react.strict_mode"), z = /* @__PURE__ */ Symbol.for("react.profiler"), H = /* @__PURE__ */ Symbol.for("react.consumer"), X = /* @__PURE__ */ Symbol.for("react.context"), B = /* @__PURE__ */ Symbol.for("react.forward_ref"), Z = /* @__PURE__ */ Symbol.for("react.suspense"), Q = /* @__PURE__ */ Symbol.for("react.suspense_list"), K = /* @__PURE__ */ Symbol.for("react.memo"), S = /* @__PURE__ */ Symbol.for("react.lazy"), ee = /* @__PURE__ */ Symbol.for("react.activity"), re = /* @__PURE__ */ Symbol.for("react.client.reference"), P = E.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, I = Object.prototype.hasOwnProperty, te = Array.isArray, k = console.createTask ? console.createTask : function() {
|
|
227
227
|
return null;
|
|
228
228
|
};
|
|
229
|
-
|
|
229
|
+
E = {
|
|
230
230
|
react_stack_bottom_frame: function(e) {
|
|
231
231
|
return e();
|
|
232
232
|
}
|
|
233
233
|
};
|
|
234
|
-
var
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
)(),
|
|
238
|
-
|
|
239
|
-
var
|
|
240
|
-
return
|
|
234
|
+
var Y, L = {}, M = E.react_stack_bottom_frame.bind(
|
|
235
|
+
E,
|
|
236
|
+
n
|
|
237
|
+
)(), F = k(o(n)), D = {};
|
|
238
|
+
y.Fragment = g, y.jsx = function(e, t, i) {
|
|
239
|
+
var u = 1e4 > P.recentlyCreatedOwnerStacks++;
|
|
240
|
+
return p(
|
|
241
241
|
e,
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
t,
|
|
243
|
+
i,
|
|
244
244
|
!1,
|
|
245
|
-
|
|
246
|
-
|
|
245
|
+
u ? Error("react-stack-top-frame") : M,
|
|
246
|
+
u ? k(o(e)) : F
|
|
247
247
|
);
|
|
248
|
-
},
|
|
249
|
-
var
|
|
250
|
-
return
|
|
248
|
+
}, y.jsxs = function(e, t, i) {
|
|
249
|
+
var u = 1e4 > P.recentlyCreatedOwnerStacks++;
|
|
250
|
+
return p(
|
|
251
251
|
e,
|
|
252
|
-
|
|
253
|
-
|
|
252
|
+
t,
|
|
253
|
+
i,
|
|
254
254
|
!0,
|
|
255
|
-
|
|
256
|
-
|
|
255
|
+
u ? Error("react-stack-top-frame") : M,
|
|
256
|
+
u ? k(o(e)) : F
|
|
257
257
|
);
|
|
258
258
|
};
|
|
259
|
-
})()),
|
|
259
|
+
})()), y;
|
|
260
260
|
}
|
|
261
|
-
var
|
|
262
|
-
function
|
|
263
|
-
return
|
|
261
|
+
var U;
|
|
262
|
+
function Re() {
|
|
263
|
+
return U || (U = 1, process.env.NODE_ENV === "production" ? j.exports = Ee() : j.exports = _e()), j.exports;
|
|
264
264
|
}
|
|
265
|
-
var
|
|
266
|
-
function
|
|
267
|
-
title:
|
|
268
|
-
description:
|
|
269
|
-
action:
|
|
270
|
-
className:
|
|
271
|
-
children:
|
|
272
|
-
...
|
|
265
|
+
var s = Re();
|
|
266
|
+
function w({
|
|
267
|
+
title: r,
|
|
268
|
+
description: c,
|
|
269
|
+
action: a,
|
|
270
|
+
className: o,
|
|
271
|
+
children: l,
|
|
272
|
+
...n
|
|
273
273
|
}) {
|
|
274
|
-
return /* @__PURE__ */
|
|
275
|
-
/* @__PURE__ */
|
|
276
|
-
/* @__PURE__ */
|
|
277
|
-
|
|
274
|
+
return /* @__PURE__ */ s.jsx("div", { className: T("flex flex-col gap-4 pb-4 md:pb-8", o), ...n, children: /* @__PURE__ */ s.jsxs("div", { className: "flex items-center justify-between gap-4", children: [
|
|
275
|
+
/* @__PURE__ */ s.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
276
|
+
/* @__PURE__ */ s.jsx("h1", { className: "text-2xl font-bold tracking-tight md:text-3xl", children: r }),
|
|
277
|
+
c && /* @__PURE__ */ s.jsx("p", { className: "text-sm text-muted-foreground", children: c })
|
|
278
278
|
] }),
|
|
279
|
-
(
|
|
280
|
-
|
|
281
|
-
|
|
279
|
+
(a || l) && /* @__PURE__ */ s.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
280
|
+
a,
|
|
281
|
+
l
|
|
282
282
|
] })
|
|
283
283
|
] }) });
|
|
284
284
|
}
|
|
285
|
-
function
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
285
|
+
function G(r) {
|
|
286
|
+
const c = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(r);
|
|
287
|
+
if (!c) return null;
|
|
288
|
+
const a = parseInt(c[1], 16) / 255, o = parseInt(c[2], 16) / 255, l = parseInt(c[3], 16) / 255, n = Math.max(a, o, l), d = Math.min(a, o, l);
|
|
289
|
+
let m = 0, v = 0;
|
|
290
|
+
const h = (n + d) / 2;
|
|
291
|
+
if (n !== d) {
|
|
292
|
+
const p = n - d;
|
|
293
|
+
switch (v = h > 0.5 ? p / (2 - n - d) : p / (n + d), n) {
|
|
294
|
+
case a:
|
|
295
|
+
m = ((o - l) / p + (o < l ? 6 : 0)) / 6;
|
|
296
|
+
break;
|
|
297
|
+
case o:
|
|
298
|
+
m = ((l - a) / p + 2) / 6;
|
|
299
|
+
break;
|
|
300
|
+
case l:
|
|
301
|
+
m = ((a - o) / p + 4) / 6;
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return `${Math.round(m * 360)} ${Math.round(v * 100)}% ${Math.round(h * 100)}%`;
|
|
306
|
+
}
|
|
307
|
+
function je(r, c) {
|
|
308
|
+
oe(() => {
|
|
309
|
+
const a = document.documentElement;
|
|
310
|
+
if (r?.primaryColor) {
|
|
311
|
+
const o = G(r.primaryColor);
|
|
312
|
+
o && (a.style.setProperty("--brand-primary", r.primaryColor), a.style.setProperty("--brand-primary-hsl", o));
|
|
313
|
+
} else
|
|
314
|
+
a.style.removeProperty("--brand-primary"), a.style.removeProperty("--brand-primary-hsl");
|
|
315
|
+
if (r?.accentColor) {
|
|
316
|
+
const o = G(r.accentColor);
|
|
317
|
+
o && (a.style.setProperty("--brand-accent", r.accentColor), a.style.setProperty("--brand-accent-hsl", o));
|
|
318
|
+
} else
|
|
319
|
+
a.style.removeProperty("--brand-accent"), a.style.removeProperty("--brand-accent-hsl");
|
|
320
|
+
if (r?.favicon) {
|
|
321
|
+
const o = document.querySelector("#favicon") || document.querySelector('link[rel="icon"]');
|
|
322
|
+
o && (o.href = r.favicon);
|
|
323
|
+
}
|
|
324
|
+
return c && (document.title = c), () => {
|
|
325
|
+
a.style.removeProperty("--brand-primary"), a.style.removeProperty("--brand-primary-hsl"), a.style.removeProperty("--brand-accent"), a.style.removeProperty("--brand-accent-hsl");
|
|
326
|
+
};
|
|
327
|
+
}, [r?.primaryColor, r?.accentColor, r?.favicon, c]);
|
|
328
|
+
}
|
|
329
|
+
function Te({
|
|
330
|
+
sidebar: r,
|
|
331
|
+
navbar: c,
|
|
332
|
+
children: a,
|
|
333
|
+
className: o,
|
|
334
|
+
defaultOpen: l = !0,
|
|
335
|
+
branding: n
|
|
291
336
|
}) {
|
|
292
|
-
return /* @__PURE__ */
|
|
293
|
-
|
|
294
|
-
/* @__PURE__ */
|
|
295
|
-
/* @__PURE__ */
|
|
296
|
-
/* @__PURE__ */
|
|
297
|
-
/* @__PURE__ */
|
|
298
|
-
|
|
337
|
+
return je(n, n?.title), /* @__PURE__ */ s.jsxs(se, { defaultOpen: l, children: [
|
|
338
|
+
r,
|
|
339
|
+
/* @__PURE__ */ s.jsxs(le, { children: [
|
|
340
|
+
/* @__PURE__ */ s.jsxs("header", { className: "flex h-14 sm:h-16 shrink-0 items-center gap-2 border-b bg-background px-2 sm:px-4", children: [
|
|
341
|
+
/* @__PURE__ */ s.jsx(ce, { className: "-ml-1" }),
|
|
342
|
+
/* @__PURE__ */ s.jsx("div", { className: "w-px h-4 bg-border mx-1 sm:mx-2" }),
|
|
343
|
+
c
|
|
299
344
|
] }),
|
|
300
|
-
/* @__PURE__ */
|
|
345
|
+
/* @__PURE__ */ s.jsx("main", { className: T("flex-1 overflow-auto p-3 sm:p-4 md:p-6", o), children: a })
|
|
301
346
|
] })
|
|
302
347
|
] });
|
|
303
348
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
349
|
+
function ge({ className: r, children: c, ...a }) {
|
|
350
|
+
return /* @__PURE__ */ s.jsx("div", { className: T("rounded-xl border bg-card text-card-foreground shadow", r), ...a, children: /* @__PURE__ */ s.jsx("div", { className: "p-6", children: c }) });
|
|
351
|
+
}
|
|
352
|
+
const Se = (r) => r ? Array.isArray(r) ? r : [r] : [];
|
|
353
|
+
function Ce({ schema: r, className: c, style: a, id: o, ...l }) {
|
|
354
|
+
const n = Se(r.children);
|
|
355
|
+
return /* @__PURE__ */ s.jsxs(
|
|
356
|
+
"div",
|
|
357
|
+
{
|
|
358
|
+
id: o || r.id,
|
|
359
|
+
className: T("flex flex-col h-full space-y-4", c),
|
|
360
|
+
style: a,
|
|
361
|
+
children: [
|
|
362
|
+
/* @__PURE__ */ s.jsx(
|
|
363
|
+
w,
|
|
364
|
+
{
|
|
365
|
+
title: r.title,
|
|
366
|
+
description: r.description
|
|
367
|
+
}
|
|
368
|
+
),
|
|
369
|
+
/* @__PURE__ */ s.jsx("div", { className: "flex-1 overflow-auto", children: n.map((d, m) => /* @__PURE__ */ s.jsx(
|
|
370
|
+
ye,
|
|
371
|
+
{
|
|
372
|
+
schema: d,
|
|
373
|
+
...l
|
|
374
|
+
},
|
|
375
|
+
d?.id || m
|
|
376
|
+
)) })
|
|
377
|
+
]
|
|
378
|
+
}
|
|
379
|
+
);
|
|
324
380
|
}
|
|
325
|
-
function
|
|
326
|
-
const
|
|
327
|
-
return /* @__PURE__ */
|
|
328
|
-
/* @__PURE__ */
|
|
329
|
-
/* @__PURE__ */
|
|
330
|
-
|
|
331
|
-
/* @__PURE__ */
|
|
332
|
-
] }) }) },
|
|
381
|
+
function $e({ items: r, title: c = "Application", className: a, collapsible: o = "icon" }) {
|
|
382
|
+
const l = ve();
|
|
383
|
+
return /* @__PURE__ */ s.jsx(ie, { className: a, collapsible: o, children: /* @__PURE__ */ s.jsx(ue, { children: /* @__PURE__ */ s.jsxs(fe, { children: [
|
|
384
|
+
/* @__PURE__ */ s.jsx(de, { children: c }),
|
|
385
|
+
/* @__PURE__ */ s.jsx(me, { children: /* @__PURE__ */ s.jsx(pe, { children: r.map((n) => /* @__PURE__ */ s.jsx(be, { children: /* @__PURE__ */ s.jsx(xe, { asChild: !0, isActive: l.pathname === n.href, children: /* @__PURE__ */ s.jsxs(he, { to: n.href, children: [
|
|
386
|
+
n.icon && /* @__PURE__ */ s.jsx(n.icon, {}),
|
|
387
|
+
/* @__PURE__ */ s.jsx("span", { children: n.title })
|
|
388
|
+
] }) }) }, n.href)) }) })
|
|
333
389
|
] }) }) });
|
|
334
390
|
}
|
|
335
|
-
function
|
|
336
|
-
|
|
391
|
+
function Pe() {
|
|
392
|
+
R.register("page-header", w, {
|
|
393
|
+
namespace: "layout",
|
|
337
394
|
label: "Page Header",
|
|
338
395
|
category: "Layout",
|
|
339
396
|
inputs: [
|
|
340
397
|
{ name: "title", type: "string" },
|
|
341
398
|
{ name: "description", type: "string" }
|
|
342
399
|
]
|
|
343
|
-
}),
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}), E.register("page", je, {
|
|
347
|
-
label: "Standard Page",
|
|
400
|
+
}), R.register("page:header", w, { namespace: "layout" }), R.register("page:card", ge, {
|
|
401
|
+
namespace: "layout",
|
|
402
|
+
label: "Page Card",
|
|
348
403
|
category: "Layout",
|
|
349
404
|
isContainer: !0
|
|
405
|
+
}), R.register("app-shell", Te, {
|
|
406
|
+
namespace: "layout",
|
|
407
|
+
label: "App Shell",
|
|
408
|
+
category: "Layout"
|
|
350
409
|
});
|
|
351
410
|
}
|
|
352
411
|
try {
|
|
353
|
-
|
|
412
|
+
Pe();
|
|
354
413
|
} catch {
|
|
355
414
|
}
|
|
356
415
|
export {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
416
|
+
Te as AppShell,
|
|
417
|
+
Ce as Page,
|
|
418
|
+
ge as PageCard,
|
|
419
|
+
w as PageHeader,
|
|
420
|
+
$e as SidebarNav,
|
|
421
|
+
Pe as registerLayout,
|
|
422
|
+
je as useAppShellBranding
|
|
362
423
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(d,y){typeof exports=="object"&&typeof module<"u"?y(exports,require("@object-ui/core"),require("react"),require("@object-ui/components"),require("@object-ui/react"),require("react-router-dom")):typeof define=="function"&&define.amd?define(["exports","@object-ui/core","react","@object-ui/components","@object-ui/react","react-router-dom"],y):(d=typeof globalThis<"u"?globalThis:d||self,y(d.ObjectUILayout={},d.core,d.require$$0,d.components,d.react,d.reactRouterDom))})(this,(function(d,y,w,m,Q,I){"use strict";var _={exports:{}},x={};var L;function K(){if(L)return x;L=1;var r=Symbol.for("react.transitional.element"),c=Symbol.for("react.fragment");function a(s,l,n){var p=null;if(n!==void 0&&(p=""+n),l.key!==void 0&&(p=""+l.key),"key"in l){n={};for(var b in l)b!=="key"&&(n[b]=l[b])}else n=l;return l=n.ref,{$$typeof:r,type:s,key:p,ref:l!==void 0?l:null,props:n}}return x.Fragment=c,x.jsx=a,x.jsxs=a,x}var E={};var M;function ee(){return M||(M=1,process.env.NODE_ENV!=="production"&&(function(){function r(e){if(e==null)return null;if(typeof e=="function")return e.$$typeof===be?null:e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case P:return"Fragment";case le:return"Profiler";case se:return"StrictMode";case fe:return"Suspense";case de:return"SuspenseList";case pe:return"Activity"}if(typeof e=="object")switch(typeof e.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),e.$$typeof){case oe:return"Portal";case ie:return e.displayName||"Context";case ce:return(e._context.displayName||"Context")+".Consumer";case ue:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case me:return t=e.displayName||null,t!==null?t:r(e.type)||"Memo";case k:t=e._payload,e=e._init;try{return r(e(t))}catch{}}return null}function c(e){return""+e}function a(e){try{c(e);var t=!1}catch{t=!0}if(t){t=console;var i=t.error,u=typeof Symbol=="function"&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object";return i.call(t,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",u),c(e)}}function s(e){if(e===P)return"<>";if(typeof e=="object"&&e!==null&&e.$$typeof===k)return"<...>";try{var t=r(e);return t?"<"+t+">":"<...>"}catch{return"<...>"}}function l(){var e=A.A;return e===null?null:e.getOwner()}function n(){return Error("react-stack-top-frame")}function p(e){if(V.call(e,"key")){var t=Object.getOwnPropertyDescriptor(e,"key").get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function b(e,t){function i(){z||(z=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}i.isReactWarning=!0,Object.defineProperty(e,"key",{get:i,configurable:!0})}function R(){var e=r(this.type);return H[e]||(H[e]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),e=this.props.ref,e!==void 0?e:null}function g(e,t,i,u,T,O){var f=i.ref;return e={$$typeof:J,type:e,key:t,props:i,_owner:u},(f!==void 0?f:null)!==null?Object.defineProperty(e,"ref",{enumerable:!1,get:R}):Object.defineProperty(e,"ref",{enumerable:!1,value:null}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:T}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:O}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function h(e,t,i,u,T,O){var f=t.children;if(f!==void 0)if(u)if(ye(f)){for(u=0;u<f.length;u++)W(f[u]);Object.freeze&&Object.freeze(f)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else W(f);if(V.call(t,"key")){f=r(e);var v=Object.keys(t).filter(function(he){return he!=="key"});u=0<v.length?"{key: someKey, "+v.join(": ..., ")+": ...}":"{key: someKey}",Z[f+u]||(v=0<v.length?"{"+v.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
|
|
2
2
|
let props = %s;
|
|
3
3
|
<%s {...props} />
|
|
4
4
|
React keys must be passed directly to JSX without using spread:
|
|
5
5
|
let props = %s;
|
|
6
|
-
<%s key={someKey} {...props} />`,
|
|
6
|
+
<%s key={someKey} {...props} />`,u,f,v,f),Z[f+u]=!0)}if(f=null,i!==void 0&&(a(i),f=""+i),p(t)&&(a(t.key),f=""+t.key),"key"in t){i={};for(var C in t)C!=="key"&&(i[C]=t[C])}else i=t;return f&&b(i,typeof e=="function"?e.displayName||e.name||"Unknown":e),g(e,f,i,l(),T,O)}function W(e){G(e)?e._store&&(e._store.validated=1):typeof e=="object"&&e!==null&&e.$$typeof===k&&(e._payload.status==="fulfilled"?G(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function G(e){return typeof e=="object"&&e!==null&&e.$$typeof===J}var S=w,J=Symbol.for("react.transitional.element"),oe=Symbol.for("react.portal"),P=Symbol.for("react.fragment"),se=Symbol.for("react.strict_mode"),le=Symbol.for("react.profiler"),ce=Symbol.for("react.consumer"),ie=Symbol.for("react.context"),ue=Symbol.for("react.forward_ref"),fe=Symbol.for("react.suspense"),de=Symbol.for("react.suspense_list"),me=Symbol.for("react.memo"),k=Symbol.for("react.lazy"),pe=Symbol.for("react.activity"),be=Symbol.for("react.client.reference"),A=S.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,V=Object.prototype.hasOwnProperty,ye=Array.isArray,N=console.createTask?console.createTask:function(){return null};S={react_stack_bottom_frame:function(e){return e()}};var z,H={},B=S.react_stack_bottom_frame.bind(S,n)(),X=N(s(n)),Z={};E.Fragment=P,E.jsx=function(e,t,i){var u=1e4>A.recentlyCreatedOwnerStacks++;return h(e,t,i,!1,u?Error("react-stack-top-frame"):B,u?N(s(e)):X)},E.jsxs=function(e,t,i){var u=1e4>A.recentlyCreatedOwnerStacks++;return h(e,t,i,!0,u?Error("react-stack-top-frame"):B,u?N(s(e)):X)}})()),E}var Y;function re(){return Y||(Y=1,process.env.NODE_ENV==="production"?_.exports=K():_.exports=ee()),_.exports}var o=re();function j({title:r,description:c,action:a,className:s,children:l,...n}){return o.jsx("div",{className:m.cn("flex flex-col gap-4 pb-4 md:pb-8",s),...n,children:o.jsxs("div",{className:"flex items-center justify-between gap-4",children:[o.jsxs("div",{className:"flex flex-col gap-1",children:[o.jsx("h1",{className:"text-2xl font-bold tracking-tight md:text-3xl",children:r}),c&&o.jsx("p",{className:"text-sm text-muted-foreground",children:c})]}),(a||l)&&o.jsxs("div",{className:"flex items-center gap-2",children:[a,l]})]})})}function $(r){const c=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(r);if(!c)return null;const a=parseInt(c[1],16)/255,s=parseInt(c[2],16)/255,l=parseInt(c[3],16)/255,n=Math.max(a,s,l),p=Math.min(a,s,l);let b=0,R=0;const g=(n+p)/2;if(n!==p){const h=n-p;switch(R=g>.5?h/(2-n-p):h/(n+p),n){case a:b=((s-l)/h+(s<l?6:0))/6;break;case s:b=((l-a)/h+2)/6;break;case l:b=((a-s)/h+4)/6;break}}return`${Math.round(b*360)} ${Math.round(R*100)}% ${Math.round(g*100)}%`}function q(r,c){w.useEffect(()=>{const a=document.documentElement;if(r?.primaryColor){const s=$(r.primaryColor);s&&(a.style.setProperty("--brand-primary",r.primaryColor),a.style.setProperty("--brand-primary-hsl",s))}else a.style.removeProperty("--brand-primary"),a.style.removeProperty("--brand-primary-hsl");if(r?.accentColor){const s=$(r.accentColor);s&&(a.style.setProperty("--brand-accent",r.accentColor),a.style.setProperty("--brand-accent-hsl",s))}else a.style.removeProperty("--brand-accent"),a.style.removeProperty("--brand-accent-hsl");if(r?.favicon){const s=document.querySelector("#favicon")||document.querySelector('link[rel="icon"]');s&&(s.href=r.favicon)}return c&&(document.title=c),()=>{a.style.removeProperty("--brand-primary"),a.style.removeProperty("--brand-primary-hsl"),a.style.removeProperty("--brand-accent"),a.style.removeProperty("--brand-accent-hsl")}},[r?.primaryColor,r?.accentColor,r?.favicon,c])}function F({sidebar:r,navbar:c,children:a,className:s,defaultOpen:l=!0,branding:n}){return q(n,n?.title),o.jsxs(m.SidebarProvider,{defaultOpen:l,children:[r,o.jsxs(m.SidebarInset,{children:[o.jsxs("header",{className:"flex h-14 sm:h-16 shrink-0 items-center gap-2 border-b bg-background px-2 sm:px-4",children:[o.jsx(m.SidebarTrigger,{className:"-ml-1"}),o.jsx("div",{className:"w-px h-4 bg-border mx-1 sm:mx-2"}),c]}),o.jsx("main",{className:m.cn("flex-1 overflow-auto p-3 sm:p-4 md:p-6",s),children:a})]})]})}function D({className:r,children:c,...a}){return o.jsx("div",{className:m.cn("rounded-xl border bg-card text-card-foreground shadow",r),...a,children:o.jsx("div",{className:"p-6",children:c})})}const te=r=>r?Array.isArray(r)?r:[r]:[];function ae({schema:r,className:c,style:a,id:s,...l}){const n=te(r.children);return o.jsxs("div",{id:s||r.id,className:m.cn("flex flex-col h-full space-y-4",c),style:a,children:[o.jsx(j,{title:r.title,description:r.description}),o.jsx("div",{className:"flex-1 overflow-auto",children:n.map((p,b)=>o.jsx(Q.SchemaRenderer,{schema:p,...l},p?.id||b))})]})}function ne({items:r,title:c="Application",className:a,collapsible:s="icon"}){const l=I.useLocation();return o.jsx(m.Sidebar,{className:a,collapsible:s,children:o.jsx(m.SidebarContent,{children:o.jsxs(m.SidebarGroup,{children:[o.jsx(m.SidebarGroupLabel,{children:c}),o.jsx(m.SidebarGroupContent,{children:o.jsx(m.SidebarMenu,{children:r.map(n=>o.jsx(m.SidebarMenuItem,{children:o.jsx(m.SidebarMenuButton,{asChild:!0,isActive:l.pathname===n.href,children:o.jsxs(I.NavLink,{to:n.href,children:[n.icon&&o.jsx(n.icon,{}),o.jsx("span",{children:n.title})]})})},n.href))})})]})})})}function U(){y.ComponentRegistry.register("page-header",j,{namespace:"layout",label:"Page Header",category:"Layout",inputs:[{name:"title",type:"string"},{name:"description",type:"string"}]}),y.ComponentRegistry.register("page:header",j,{namespace:"layout"}),y.ComponentRegistry.register("page:card",D,{namespace:"layout",label:"Page Card",category:"Layout",isContainer:!0}),y.ComponentRegistry.register("app-shell",F,{namespace:"layout",label:"App Shell",category:"Layout"})}try{U()}catch{}d.AppShell=F,d.Page=ae,d.PageCard=D,d.PageHeader=j,d.SidebarNav=ne,d.registerLayout=U,d.useAppShellBranding=q,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})}));
|
|
@@ -1,9 +1,32 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Branding configuration for the AppShell.
|
|
4
|
+
* Applies CSS custom properties to the document root for theme customization.
|
|
5
|
+
*/
|
|
6
|
+
export interface AppShellBranding {
|
|
7
|
+
/** Primary brand color (hex, e.g. "#3B82F6") */
|
|
8
|
+
primaryColor?: string;
|
|
9
|
+
/** Accent brand color (hex, e.g. "#10B981") */
|
|
10
|
+
accentColor?: string;
|
|
11
|
+
/** Favicon URL — replaces the <link rel="icon"> href */
|
|
12
|
+
favicon?: string;
|
|
13
|
+
/** Logo URL — passed to sidebar/navbar via context */
|
|
14
|
+
logo?: string;
|
|
15
|
+
/** Page title suffix (sets document.title) */
|
|
16
|
+
title?: string;
|
|
17
|
+
}
|
|
2
18
|
export interface AppShellProps {
|
|
3
19
|
sidebar?: React.ReactNode;
|
|
4
20
|
navbar?: React.ReactNode;
|
|
5
21
|
children: React.ReactNode;
|
|
6
22
|
className?: string;
|
|
7
23
|
defaultOpen?: boolean;
|
|
24
|
+
/** App branding — applies CSS custom properties for theming */
|
|
25
|
+
branding?: AppShellBranding;
|
|
8
26
|
}
|
|
9
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Apply branding CSS custom properties to the document root.
|
|
29
|
+
* This is extracted as a standalone hook so it can be re-used independently.
|
|
30
|
+
*/
|
|
31
|
+
export declare function useAppShellBranding(branding?: AppShellBranding, title?: string): void;
|
|
32
|
+
export declare function AppShell({ sidebar, navbar, children, className, defaultOpen, branding, }: AppShellProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
1
2
|
import { PageSchema } from '../../types/src';
|
|
2
|
-
export declare function Page({ schema, ...props }: {
|
|
3
|
+
export declare function Page({ schema, className, style, id, ...props }: {
|
|
3
4
|
schema: PageSchema;
|
|
5
|
+
className?: string;
|
|
6
|
+
style?: React.CSSProperties;
|
|
7
|
+
id?: string;
|
|
4
8
|
} & any): import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,5 +10,6 @@ export interface SidebarNavProps {
|
|
|
10
10
|
items: NavItem[];
|
|
11
11
|
title?: string;
|
|
12
12
|
className?: string;
|
|
13
|
+
collapsible?: "offcanvas" | "icon" | "none";
|
|
13
14
|
}
|
|
14
|
-
export declare function SidebarNav({ items, title, className }: SidebarNavProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare function SidebarNav({ items, title, className, collapsible }: SidebarNavProps): import("react/jsx-runtime").JSX.Element;
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/layout",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
5
6
|
"main": "dist/index.umd.cjs",
|
|
6
7
|
"module": "dist/index.js",
|
|
7
8
|
"types": "dist/index.d.ts",
|
|
@@ -15,13 +16,13 @@
|
|
|
15
16
|
"dependencies": {
|
|
16
17
|
"clsx": "^2.1.0",
|
|
17
18
|
"lucide-react": "^0.563.0",
|
|
18
|
-
"react": "^
|
|
19
|
-
"react-dom": "^
|
|
19
|
+
"react": "^19.2.4",
|
|
20
|
+
"react-dom": "^19.2.4",
|
|
20
21
|
"tailwind-merge": "^2.2.1",
|
|
21
|
-
"@object-ui/components": "0.
|
|
22
|
-
"@object-ui/core": "0.
|
|
23
|
-
"@object-ui/react": "0.
|
|
24
|
-
"@object-ui/types": "0.
|
|
22
|
+
"@object-ui/components": "2.0.0",
|
|
23
|
+
"@object-ui/core": "2.0.0",
|
|
24
|
+
"@object-ui/react": "2.0.0",
|
|
25
|
+
"@object-ui/types": "2.0.0"
|
|
25
26
|
},
|
|
26
27
|
"peerDependencies": {
|
|
27
28
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -30,7 +31,7 @@
|
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"react-router-dom": "^7.13.0",
|
|
33
|
-
"@vitejs/plugin-react": "^
|
|
34
|
+
"@vitejs/plugin-react": "^5.1.3",
|
|
34
35
|
"vite": "^7.3.1",
|
|
35
36
|
"vite-plugin-dts": "^4.5.4"
|
|
36
37
|
},
|
package/src/AppShell.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
SidebarProvider,
|
|
4
4
|
SidebarTrigger,
|
|
@@ -7,12 +7,117 @@ import {
|
|
|
7
7
|
} from '@object-ui/components';
|
|
8
8
|
import { cn } from '@object-ui/components';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Branding configuration for the AppShell.
|
|
12
|
+
* Applies CSS custom properties to the document root for theme customization.
|
|
13
|
+
*/
|
|
14
|
+
export interface AppShellBranding {
|
|
15
|
+
/** Primary brand color (hex, e.g. "#3B82F6") */
|
|
16
|
+
primaryColor?: string;
|
|
17
|
+
/** Accent brand color (hex, e.g. "#10B981") */
|
|
18
|
+
accentColor?: string;
|
|
19
|
+
/** Favicon URL — replaces the <link rel="icon"> href */
|
|
20
|
+
favicon?: string;
|
|
21
|
+
/** Logo URL — passed to sidebar/navbar via context */
|
|
22
|
+
logo?: string;
|
|
23
|
+
/** Page title suffix (sets document.title) */
|
|
24
|
+
title?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
10
27
|
export interface AppShellProps {
|
|
11
28
|
sidebar?: React.ReactNode;
|
|
12
29
|
navbar?: React.ReactNode; // Top navbar content
|
|
13
30
|
children: React.ReactNode;
|
|
14
31
|
className?: string;
|
|
15
32
|
defaultOpen?: boolean;
|
|
33
|
+
/** App branding — applies CSS custom properties for theming */
|
|
34
|
+
branding?: AppShellBranding;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Convert a hex color (#RRGGBB) to HSL string "H S% L%"
|
|
39
|
+
* for use in Tailwind CSS custom properties.
|
|
40
|
+
*/
|
|
41
|
+
function hexToHSL(hex: string): string | null {
|
|
42
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
43
|
+
if (!result) return null;
|
|
44
|
+
|
|
45
|
+
const r = parseInt(result[1], 16) / 255;
|
|
46
|
+
const g = parseInt(result[2], 16) / 255;
|
|
47
|
+
const b = parseInt(result[3], 16) / 255;
|
|
48
|
+
|
|
49
|
+
const max = Math.max(r, g, b);
|
|
50
|
+
const min = Math.min(r, g, b);
|
|
51
|
+
let h = 0;
|
|
52
|
+
let s = 0;
|
|
53
|
+
const l = (max + min) / 2;
|
|
54
|
+
|
|
55
|
+
if (max !== min) {
|
|
56
|
+
const d = max - min;
|
|
57
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
58
|
+
switch (max) {
|
|
59
|
+
case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;
|
|
60
|
+
case g: h = ((b - r) / d + 2) / 6; break;
|
|
61
|
+
case b: h = ((r - g) / d + 4) / 6; break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return `${Math.round(h * 360)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Apply branding CSS custom properties to the document root.
|
|
70
|
+
* This is extracted as a standalone hook so it can be re-used independently.
|
|
71
|
+
*/
|
|
72
|
+
export function useAppShellBranding(branding?: AppShellBranding, title?: string) {
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
const root = document.documentElement;
|
|
75
|
+
|
|
76
|
+
// Primary color
|
|
77
|
+
if (branding?.primaryColor) {
|
|
78
|
+
const hsl = hexToHSL(branding.primaryColor);
|
|
79
|
+
if (hsl) {
|
|
80
|
+
root.style.setProperty('--brand-primary', branding.primaryColor);
|
|
81
|
+
root.style.setProperty('--brand-primary-hsl', hsl);
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
root.style.removeProperty('--brand-primary');
|
|
85
|
+
root.style.removeProperty('--brand-primary-hsl');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Accent color
|
|
89
|
+
if (branding?.accentColor) {
|
|
90
|
+
const hsl = hexToHSL(branding.accentColor);
|
|
91
|
+
if (hsl) {
|
|
92
|
+
root.style.setProperty('--brand-accent', branding.accentColor);
|
|
93
|
+
root.style.setProperty('--brand-accent-hsl', hsl);
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
root.style.removeProperty('--brand-accent');
|
|
97
|
+
root.style.removeProperty('--brand-accent-hsl');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Favicon
|
|
101
|
+
if (branding?.favicon) {
|
|
102
|
+
const link = document.querySelector<HTMLLinkElement>('#favicon')
|
|
103
|
+
|| document.querySelector<HTMLLinkElement>('link[rel="icon"]');
|
|
104
|
+
if (link) {
|
|
105
|
+
link.href = branding.favicon;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Page title
|
|
110
|
+
if (title) {
|
|
111
|
+
document.title = title;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return () => {
|
|
115
|
+
root.style.removeProperty('--brand-primary');
|
|
116
|
+
root.style.removeProperty('--brand-primary-hsl');
|
|
117
|
+
root.style.removeProperty('--brand-accent');
|
|
118
|
+
root.style.removeProperty('--brand-accent-hsl');
|
|
119
|
+
};
|
|
120
|
+
}, [branding?.primaryColor, branding?.accentColor, branding?.favicon, title]);
|
|
16
121
|
}
|
|
17
122
|
|
|
18
123
|
export function AppShell({
|
|
@@ -21,17 +126,21 @@ export function AppShell({
|
|
|
21
126
|
children,
|
|
22
127
|
className,
|
|
23
128
|
defaultOpen = true,
|
|
129
|
+
branding,
|
|
24
130
|
}: AppShellProps) {
|
|
131
|
+
// Apply branding CSS custom properties
|
|
132
|
+
useAppShellBranding(branding, branding?.title);
|
|
133
|
+
|
|
25
134
|
return (
|
|
26
135
|
<SidebarProvider defaultOpen={defaultOpen}>
|
|
27
136
|
{sidebar}
|
|
28
137
|
<SidebarInset>
|
|
29
|
-
<header className="flex h-16 shrink-0 items-center gap-2 border-b bg-background px-4">
|
|
138
|
+
<header className="flex h-14 sm:h-16 shrink-0 items-center gap-2 border-b bg-background px-2 sm:px-4">
|
|
30
139
|
<SidebarTrigger className="-ml-1" />
|
|
31
|
-
<div className="w-px h-4 bg-border mx-2" />
|
|
140
|
+
<div className="w-px h-4 bg-border mx-1 sm:mx-2" />
|
|
32
141
|
{navbar}
|
|
33
142
|
</header>
|
|
34
|
-
<main className={cn("flex-1 overflow-auto p-4 md:p-6", className)}>
|
|
143
|
+
<main className={cn("flex-1 overflow-auto p-3 sm:p-4 md:p-6", className)}>
|
|
35
144
|
{children}
|
|
36
145
|
</main>
|
|
37
146
|
</SidebarInset>
|
package/src/Page.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import React from 'react';
|
|
|
3
3
|
import { SchemaRenderer } from '@object-ui/react';
|
|
4
4
|
import { PageSchema, SchemaNode } from '@object-ui/types';
|
|
5
5
|
import { PageHeader } from './PageHeader';
|
|
6
|
+
import { cn } from '@object-ui/components';
|
|
6
7
|
|
|
7
8
|
// Helper to ensure children is always an array
|
|
8
9
|
const getChildren = (children?: SchemaNode[] | SchemaNode): SchemaNode[] => {
|
|
@@ -11,11 +12,15 @@ const getChildren = (children?: SchemaNode[] | SchemaNode): SchemaNode[] => {
|
|
|
11
12
|
return [children];
|
|
12
13
|
};
|
|
13
14
|
|
|
14
|
-
export function Page({ schema, ...props }: { schema: PageSchema } & any) {
|
|
15
|
+
export function Page({ schema, className, style, id, ...props }: { schema: PageSchema; className?: string; style?: React.CSSProperties; id?: string } & any) {
|
|
15
16
|
const children = getChildren(schema.children);
|
|
16
17
|
|
|
17
18
|
return (
|
|
18
|
-
<div
|
|
19
|
+
<div
|
|
20
|
+
id={id || schema.id}
|
|
21
|
+
className={cn("flex flex-col h-full space-y-4", className)}
|
|
22
|
+
style={style}
|
|
23
|
+
>
|
|
19
24
|
<PageHeader
|
|
20
25
|
title={schema.title}
|
|
21
26
|
description={schema.description}
|
package/src/PageCard.tsx
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { cn } from '@object-ui/components';
|
|
3
|
+
|
|
4
|
+
export function PageCard({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
5
|
+
return (
|
|
6
|
+
<div className={cn("rounded-xl border bg-card text-card-foreground shadow", className)} {...props}>
|
|
7
|
+
<div className="p-6">
|
|
8
|
+
{children}
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
);
|
|
12
|
+
}
|
package/src/SidebarNav.tsx
CHANGED
|
@@ -21,13 +21,14 @@ export interface SidebarNavProps {
|
|
|
21
21
|
items: NavItem[];
|
|
22
22
|
title?: string;
|
|
23
23
|
className?: string;
|
|
24
|
+
collapsible?: "offcanvas" | "icon" | "none";
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
export function SidebarNav({ items, title = "Application", className }: SidebarNavProps) {
|
|
27
|
+
export function SidebarNav({ items, title = "Application", className, collapsible = "icon" }: SidebarNavProps) {
|
|
27
28
|
const location = useLocation();
|
|
28
29
|
|
|
29
30
|
return (
|
|
30
|
-
<Sidebar className={className}>
|
|
31
|
+
<Sidebar className={className} collapsible={collapsible}>
|
|
31
32
|
<SidebarContent>
|
|
32
33
|
<SidebarGroup>
|
|
33
34
|
<SidebarGroupLabel>{title}</SidebarGroupLabel>
|
package/src/index.ts
CHANGED
|
@@ -7,15 +7,18 @@ import { ComponentRegistry } from '@object-ui/core';
|
|
|
7
7
|
import { PageHeader } from './PageHeader';
|
|
8
8
|
import { AppShell } from './AppShell';
|
|
9
9
|
import { Page } from './Page';
|
|
10
|
+
import { PageCard } from './PageCard';
|
|
10
11
|
import { SidebarNav } from './SidebarNav';
|
|
11
12
|
|
|
12
13
|
export * from './PageHeader';
|
|
13
14
|
export * from './AppShell';
|
|
14
15
|
export * from './Page';
|
|
16
|
+
export * from './PageCard';
|
|
15
17
|
export * from './SidebarNav';
|
|
16
18
|
|
|
17
19
|
export function registerLayout() {
|
|
18
20
|
ComponentRegistry.register('page-header', PageHeader, {
|
|
21
|
+
namespace: 'layout',
|
|
19
22
|
label: 'Page Header',
|
|
20
23
|
category: 'Layout',
|
|
21
24
|
inputs: [
|
|
@@ -25,19 +28,25 @@ export function registerLayout() {
|
|
|
25
28
|
});
|
|
26
29
|
|
|
27
30
|
// Alias for protocol compliance
|
|
28
|
-
ComponentRegistry.register('page:header', PageHeader);
|
|
31
|
+
ComponentRegistry.register('page:header', PageHeader, { namespace: 'layout' });
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
// Page Card
|
|
34
|
+
ComponentRegistry.register('page:card', PageCard, {
|
|
35
|
+
namespace: 'layout',
|
|
36
|
+
label: 'Page Card',
|
|
37
|
+
category: 'Layout',
|
|
38
|
+
isContainer: true
|
|
33
39
|
});
|
|
34
40
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
label: '
|
|
41
|
+
ComponentRegistry.register('app-shell', AppShell, {
|
|
42
|
+
namespace: 'layout',
|
|
43
|
+
label: 'App Shell',
|
|
38
44
|
category: 'Layout',
|
|
39
|
-
isContainer: true
|
|
40
45
|
});
|
|
46
|
+
|
|
47
|
+
// NOTE: 'page' registration is handled by @object-ui/components PageRenderer.
|
|
48
|
+
// That renderer supports page types (record/home/app/utility), named regions,
|
|
49
|
+
// and PageVariablesProvider. Do NOT re-register 'page' here to avoid conflicts.
|
|
41
50
|
}
|
|
42
51
|
|
|
43
52
|
// Keep backward compatibility for now if called directly
|