@tailor-platform/app-shell 0.27.1 → 0.27.3

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 ADDED
@@ -0,0 +1,26 @@
1
+ # @tailor-platform/app-shell
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@tailor-platform/app-shell)](https://www.npmjs.com/package/@tailor-platform/app-shell)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@tailor-platform/app-shell)](https://www.npmjs.com/package/@tailor-platform/app-shell)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/tailor-platform/app-shell/blob/main/LICENSE.md)
6
+
7
+ An opinionated React application framework for creating applications on Tailor Platform.
8
+
9
+ ## Why AppShell?
10
+
11
+ We've made sensible default choices so you can focus on what matters most — building business-level screens. The alternative is implementing authentication, routing, navigation, layouts, and theming all by yourself. AppShell handles all of that out of the box, designed primarily for Vite-based React applications that can be deployed to Tailor Platform's static hosting.
12
+
13
+ - **Routing** — Declarative module/resource definitions or [file-based routing](https://www.npmjs.com/package/@tailor-platform/app-shell-vite-plugin) with automatic sidebar navigation and breadcrumbs
14
+ - **Authentication** — Built-in OAuth2/OIDC integration with Tailor Platform
15
+ - **Responsive layouts** — Sidebar, column layouts (1/2/3), and mobile support out of the box
16
+ - **Command Palette** — Keyboard-driven quick navigation (`Cmd+K`)
17
+ - **Route Guards** — Access control with `pass()`, `hidden()`, `redirectTo()`
18
+ - **ERP components** — Badge, DescriptionCard, and more for common business UI patterns
19
+ - **i18n** — Built-in internationalization with auto locale detection
20
+ - **Theming** — Light/dark mode with Tailwind CSS
21
+ - **Portable** — Built on react-router for full portability across React frameworks
22
+
23
+ ## Documentation
24
+
25
+ - [Quick Start](https://github.com/tailor-platform/app-shell/blob/main/docs/quickstart.md) — Installation, setup, and first steps
26
+ - [API Reference](https://github.com/tailor-platform/app-shell/blob/main/docs/api.md) — Complete reference for all components, hooks, and functions
@@ -850,7 +850,7 @@ declare type LabelValue = string | ((props: any) => string);
850
850
  * </Layout>
851
851
  * ```
852
852
  */
853
- export declare function Layout({ columns, className, gap, title, actions, children, }: LayoutProps): JSX.Element;
853
+ export declare function Layout({ columns, className, gap, title, actions, children }: LayoutProps): JSX.Element;
854
854
 
855
855
  export declare namespace Layout {
856
856
  var Column: React_2.ForwardRefExoticComponent<ColumnProps & React_2.RefAttributes<HTMLDivElement>>;
package/dist/app-shell.js CHANGED
@@ -281,10 +281,7 @@ function $s(t) {
281
281
  throw new Error(
282
282
  `Module "${e}" has no component. Either provide a \`component\` or use \`guards\` with \`redirectTo()\` or \`hidden()\` to control access. A guard that only returns \`pass()\` without a component will result in a blank page.`
283
283
  );
284
- const w = i && i.length > 0 ? Vt(i) : void 0, d = r ? Ht(
285
- { metaTitle: l, fallbackTitle: u },
286
- (h) => r({ title: h, resources: n })
287
- ) : void 0;
284
+ const w = i && i.length > 0 ? Vt(i) : void 0, d = r ? Ht({ metaTitle: l, fallbackTitle: u }, (h) => r({ title: h, resources: n })) : void 0;
288
285
  return {
289
286
  path: e,
290
287
  type: "component",
@@ -374,9 +371,7 @@ const Oe = () => {
374
371
  children: [n]
375
372
  } : {}
376
373
  };
377
- }, Ue = (t) => t.map(
378
- (e) => Gt(e, e.resources, e.errorBoundary)
379
- ), Ke = ({
374
+ }, Ue = (t) => t.map((e) => Gt(e, e.resources, e.errorBoundary)), Ke = ({
380
375
  modules: t,
381
376
  settingsResources: e,
382
377
  rootComponent: s
@@ -388,14 +383,7 @@ const Oe = () => {
388
383
  {
389
384
  path: "settings",
390
385
  index: !0,
391
- Component: () => /* @__PURE__ */ a(
392
- pe,
393
- {
394
- to: e[0].path,
395
- relative: "path",
396
- replace: !0
397
- }
398
- )
386
+ Component: () => /* @__PURE__ */ a(pe, { to: e[0].path, relative: "path", replace: !0 })
399
387
  },
400
388
  {
401
389
  path: "settings",
@@ -450,11 +438,7 @@ const Oe = () => {
450
438
  }, Yt = async (t, e, s) => (await Promise.all(
451
439
  t.map(async (n) => {
452
440
  if (n.path.startsWith(":") || (await ut(n.guards)).type !== "pass") return null;
453
- const i = `${e}/${n.path}`, l = s(n.meta.title, n.path), u = n.subResources ? await Yt(
454
- n.subResources,
455
- i,
456
- s
457
- ) : void 0;
441
+ const i = `${e}/${n.path}`, l = s(n.meta.title, n.path), u = n.subResources ? await Yt(n.subResources, i, s) : void 0;
458
442
  return {
459
443
  title: l,
460
444
  url: i,
@@ -523,17 +507,12 @@ function Qe({
523
507
  }
524
508
  const Ye = () => {
525
509
  const t = L(Xt);
526
- if (t === void 0)
527
- throw new Error("useTheme must be used within a ThemeProvider");
510
+ if (t === void 0) throw new Error("useTheme must be used within a ThemeProvider");
528
511
  return t;
529
512
  }, Xe = () => () => {
530
513
  }, Ze = () => !0, Je = () => !1;
531
514
  function ta() {
532
- return Wt(
533
- Xe,
534
- Ze,
535
- Je
536
- );
515
+ return Wt(Xe, Ze, Je);
537
516
  }
538
517
  function ea(t) {
539
518
  const e = {
@@ -631,13 +610,7 @@ const te = (t) => {
631
610
  errorBoundary: t.errorBoundary,
632
611
  locale: t.locale
633
612
  }) : null,
634
- [
635
- r,
636
- t.settingsResources,
637
- t.basePath,
638
- t.errorBoundary,
639
- t.locale
640
- ]
613
+ [r, t.settingsResources, t.basePath, t.errorBoundary, t.locale]
641
614
  ), o = B(
642
615
  () => n ? { title: t.title, icon: t.icon, configurations: n } : null,
643
616
  [t.title, t.icon, n]
@@ -668,9 +641,7 @@ function sa(t) {
668
641
  te.WithPages = sa;
669
642
  const J = 768;
670
643
  function ra() {
671
- const [t, e] = f.useState(
672
- void 0
673
- );
644
+ const [t, e] = f.useState(void 0);
674
645
  return f.useEffect(() => {
675
646
  const s = window.matchMedia(`(max-width: ${J - 1}px)`), r = () => {
676
647
  e(window.innerWidth < J);
@@ -680,9 +651,7 @@ function ra() {
680
651
  }
681
652
  const tt = 768, et = 1199;
682
653
  function na() {
683
- const [t, e] = f.useState(
684
- void 0
685
- );
654
+ const [t, e] = f.useState(void 0);
686
655
  return f.useEffect(() => {
687
656
  const s = window.matchMedia(
688
657
  `(min-width: ${tt}px) and (max-width: ${et}px)`
@@ -737,15 +706,10 @@ function ia({
737
706
  function Ct({ ...t }) {
738
707
  return /* @__PURE__ */ a(v.Root, { "data-slot": "sheet", ...t });
739
708
  }
740
- function la({
741
- ...t
742
- }) {
709
+ function la({ ...t }) {
743
710
  return /* @__PURE__ */ a(v.Portal, { "data-slot": "sheet-portal", ...t });
744
711
  }
745
- function ca({
746
- className: t,
747
- ...e
748
- }) {
712
+ function ca({ className: t, ...e }) {
749
713
  return /* @__PURE__ */ a(
750
714
  v.Backdrop,
751
715
  {
@@ -800,10 +764,7 @@ function kt({ className: t, ...e }) {
800
764
  }
801
765
  );
802
766
  }
803
- function Rt({
804
- className: t,
805
- ...e
806
- }) {
767
+ function Rt({ className: t, ...e }) {
807
768
  return /* @__PURE__ */ a(
808
769
  v.Title,
809
770
  {
@@ -831,22 +792,12 @@ function mt({
831
792
  children: e,
832
793
  ...s
833
794
  }) {
834
- return /* @__PURE__ */ a(
835
- A.Provider,
836
- {
837
- "data-slot": "tooltip-provider",
838
- delay: t,
839
- ...s,
840
- children: e
841
- }
842
- );
795
+ return /* @__PURE__ */ a(A.Provider, { "data-slot": "tooltip-provider", delay: t, ...s, children: e });
843
796
  }
844
797
  function ht({ children: t, ...e }) {
845
798
  return /* @__PURE__ */ a(mt, { children: /* @__PURE__ */ a(A.Root, { "data-slot": "tooltip", ...e, children: t }) });
846
799
  }
847
- function pt({
848
- ...t
849
- }) {
800
+ function pt({ ...t }) {
850
801
  return /* @__PURE__ */ a(A.Trigger, { "data-slot": "tooltip-trigger", ...t });
851
802
  }
852
803
  function ft({
@@ -954,15 +905,7 @@ function ha({
954
905
  children: n,
955
906
  ...o
956
907
  }) {
957
- const {
958
- isMobile: i,
959
- state: l,
960
- openMobile: u,
961
- setOpenMobile: w,
962
- isIconMode: d,
963
- openIconMode: h,
964
- setOpenIconMode: p
965
- } = K();
908
+ const { isMobile: i, state: l, openMobile: u, setOpenMobile: w, isIconMode: d, openIconMode: h, setOpenIconMode: p } = K();
966
909
  return s === "none" ? /* @__PURE__ */ a(
967
910
  "div",
968
911
  {
@@ -1108,11 +1051,7 @@ function ha({
1108
1051
  }
1109
1052
  );
1110
1053
  }
1111
- function se({
1112
- className: t,
1113
- onClick: e,
1114
- ...s
1115
- }) {
1054
+ function se({ className: t, onClick: e, ...s }) {
1116
1055
  const { toggleSidebar: r } = K();
1117
1056
  return /* @__PURE__ */ c(
1118
1057
  O,
@@ -1154,18 +1093,12 @@ function fa({ className: t, ...e }) {
1154
1093
  {
1155
1094
  "data-slot": "sidebar-header",
1156
1095
  "data-sidebar": "header",
1157
- className: m(
1158
- "astw:flex astw:flex-row astw:items-center astw:gap-0.5 astw:p-2",
1159
- t
1160
- ),
1096
+ className: m("astw:flex astw:flex-row astw:items-center astw:gap-0.5 astw:p-2", t),
1161
1097
  ...e
1162
1098
  }
1163
1099
  );
1164
1100
  }
1165
- function ga({
1166
- className: t,
1167
- ...e
1168
- }) {
1101
+ function ga({ className: t, ...e }) {
1169
1102
  return /* @__PURE__ */ a(
1170
1103
  ia,
1171
1104
  {
@@ -1210,10 +1143,7 @@ function bt({ className: t, ...e }) {
1210
1143
  {
1211
1144
  "data-slot": "sidebar-menu",
1212
1145
  "data-sidebar": "menu",
1213
- className: m(
1214
- "astw:flex astw:w-full astw:min-w-0 astw:flex-col astw:gap-1",
1215
- t
1216
- ),
1146
+ className: m("astw:flex astw:w-full astw:min-w-0 astw:flex-col astw:gap-1", t),
1217
1147
  ...e
1218
1148
  }
1219
1149
  );
@@ -1331,10 +1261,7 @@ function at({ className: t, ...e }) {
1331
1261
  }
1332
1262
  );
1333
1263
  }
1334
- function va({
1335
- className: t,
1336
- ...e
1337
- }) {
1264
+ function va({ className: t, ...e }) {
1338
1265
  return /* @__PURE__ */ a(
1339
1266
  "li",
1340
1267
  {
@@ -1386,12 +1313,7 @@ const Na = (t) => {
1386
1313
  title: r(o.meta.title, o.path),
1387
1314
  icon: o.meta.icon
1388
1315
  };
1389
- const l = ne(
1390
- n,
1391
- i,
1392
- o.resources,
1393
- r
1394
- );
1316
+ const l = ne(n, i, o.resources, r);
1395
1317
  if (l)
1396
1318
  return l;
1397
1319
  }
@@ -1399,9 +1321,7 @@ const Na = (t) => {
1399
1321
  }, re = (t, e) => {
1400
1322
  if (t === e) return !0;
1401
1323
  const s = t.split("/"), r = e.split("/");
1402
- return s.length !== r.length ? !1 : r.every(
1403
- (n, o) => n.startsWith(":") || n === s[o]
1404
- );
1324
+ return s.length !== r.length ? !1 : r.every((n, o) => n.startsWith(":") || n === s[o]);
1405
1325
  }, At = (t) => {
1406
1326
  let e = t;
1407
1327
  return e.startsWith("/") || (e = `/${e}`), e.length > 1 && e.endsWith("/") && (e = e.slice(0, -1)), e;
@@ -1414,12 +1334,7 @@ const Na = (t) => {
1414
1334
  icon: n.meta.icon
1415
1335
  };
1416
1336
  if (n.subResources) {
1417
- const i = ne(
1418
- t,
1419
- o,
1420
- n.subResources,
1421
- r
1422
- );
1337
+ const i = ne(t, o, n.subResources, r);
1423
1338
  if (i)
1424
1339
  return i;
1425
1340
  }
@@ -1484,19 +1399,13 @@ const Na = (t) => {
1484
1399
  const e = t.split("/").filter(Boolean);
1485
1400
  return (e[e.length - 1] ?? t).split("-").map((r) => r.charAt(0).toUpperCase() + r.slice(1)).join(" ");
1486
1401
  };
1487
- function st({
1488
- ...t
1489
- }) {
1402
+ function st({ ...t }) {
1490
1403
  return /* @__PURE__ */ a(lt.Root, { "data-slot": "collapsible", ...t });
1491
1404
  }
1492
- function Q({
1493
- ...t
1494
- }) {
1405
+ function Q({ ...t }) {
1495
1406
  return /* @__PURE__ */ a(lt.Trigger, { "data-slot": "collapsible-trigger", ...t });
1496
1407
  }
1497
- function rt({
1498
- ...t
1499
- }) {
1408
+ function rt({ ...t }) {
1500
1409
  return /* @__PURE__ */ a(lt.Panel, { "data-slot": "collapsible-content", ...t });
1501
1410
  }
1502
1411
  const Os = (t) => {
@@ -1553,16 +1462,7 @@ const Os = (t) => {
1553
1462
  }, js = () => /* @__PURE__ */ a(ga, {}), ka = (t) => {
1554
1463
  const { title: e, icon: s } = C(), { pathname: r } = Y(), { isIconMode: n } = K(), o = /* @__PURE__ */ c(fa, { children: [
1555
1464
  s,
1556
- /* @__PURE__ */ a(
1557
- "h1",
1558
- {
1559
- className: m(
1560
- "astw:text-sm astw:mb-2 astw:mt-2 astw:px-2",
1561
- n && "astw:hidden"
1562
- ),
1563
- children: e
1564
- }
1565
- )
1465
+ /* @__PURE__ */ a("h1", { className: m("astw:text-sm astw:mb-2 astw:mt-2 astw:px-2", n && "astw:hidden"), children: e })
1566
1466
  ] });
1567
1467
  return /* @__PURE__ */ c(ha, { variant: "inset", collapsible: n ? "icon" : "offcanvas", children: [
1568
1468
  !n && /* @__PURE__ */ c("div", { className: "astw:flex astw:justify-between astw:items-center", children: [
@@ -1583,81 +1483,66 @@ const Os = (t) => {
1583
1483
  return /* @__PURE__ */ a(zt, { resolve: e, children: (s) => /* @__PURE__ */ a(Pa, { items: s ?? [], currentPath: t }) });
1584
1484
  }, Pa = (t) => {
1585
1485
  const e = E();
1586
- return /* @__PURE__ */ a(gt, { children: /* @__PURE__ */ a(bt, { children: t.items.map((s) => /* @__PURE__ */ c(
1587
- st,
1588
- {
1589
- render: /* @__PURE__ */ a(I, {}),
1590
- defaultOpen: !0,
1591
- children: [
1592
- s.url ? /* @__PURE__ */ c(S, { children: [
1593
- /* @__PURE__ */ c(
1594
- z,
1595
- {
1596
- render: /* @__PURE__ */ a(
1597
- $,
1598
- {
1599
- to: s.url,
1600
- className: s.url === t.currentPath ? "astw:bg-sidebar-accent astw:font-medium" : void 0
1601
- }
1602
- ),
1603
- tooltip: s.title,
1604
- children: [
1605
- s.icon,
1606
- /* @__PURE__ */ a("span", { children: s.title })
1607
- ]
1608
- }
1609
- ),
1610
- !!s.items?.length && /* @__PURE__ */ c(
1611
- Q,
1612
- {
1613
- render: /* @__PURE__ */ a(q, { className: "astw:data-panel-open:rotate-90" }),
1614
- children: [
1615
- /* @__PURE__ */ a(W, {}),
1616
- /* @__PURE__ */ a("span", { className: "astw:sr-only", children: e("toggle") })
1617
- ]
1618
- }
1619
- )
1620
- ] }) : /* @__PURE__ */ a(S, { children: /* @__PURE__ */ c(Q, { className: "astw:flex astw:w-full astw:[&[data-panel-open]_.astw-rotate-target]:rotate-90", children: [
1621
- /* @__PURE__ */ c(
1622
- z,
1486
+ return /* @__PURE__ */ a(gt, { children: /* @__PURE__ */ a(bt, { children: t.items.map((s) => /* @__PURE__ */ c(st, { render: /* @__PURE__ */ a(I, {}), defaultOpen: !0, children: [
1487
+ s.url ? /* @__PURE__ */ c(S, { children: [
1488
+ /* @__PURE__ */ c(
1489
+ z,
1490
+ {
1491
+ render: /* @__PURE__ */ a(
1492
+ $,
1623
1493
  {
1624
- render: /* @__PURE__ */ a("span", { className: "astw:flex astw:w-full" }),
1625
- tooltip: s.title,
1626
- children: [
1627
- s.icon,
1628
- /* @__PURE__ */ a("span", { children: s.title })
1629
- ]
1494
+ to: s.url,
1495
+ className: s.url === t.currentPath ? "astw:bg-sidebar-accent astw:font-medium" : void 0
1630
1496
  }
1631
1497
  ),
1632
- !!s.items?.length && /* @__PURE__ */ c(
1633
- q,
1634
- {
1635
- className: "astw-rotate-target",
1636
- render: /* @__PURE__ */ a("span", {}),
1637
- children: [
1638
- /* @__PURE__ */ a(W, {}),
1639
- /* @__PURE__ */ a("span", { className: "astw:sr-only", children: e("toggle") })
1640
- ]
1641
- }
1642
- )
1643
- ] }) }),
1644
- !!s.items?.length && /* @__PURE__ */ a(rt, { children: /* @__PURE__ */ a(at, { children: s.items?.map((r) => /* @__PURE__ */ a(va, { children: /* @__PURE__ */ a(
1645
- ya,
1498
+ tooltip: s.title,
1499
+ children: [
1500
+ s.icon,
1501
+ /* @__PURE__ */ a("span", { children: s.title })
1502
+ ]
1503
+ }
1504
+ ),
1505
+ !!s.items?.length && /* @__PURE__ */ c(
1506
+ Q,
1507
+ {
1508
+ render: /* @__PURE__ */ a(q, { className: "astw:data-panel-open:rotate-90" }),
1509
+ children: [
1510
+ /* @__PURE__ */ a(W, {}),
1511
+ /* @__PURE__ */ a("span", { className: "astw:sr-only", children: e("toggle") })
1512
+ ]
1513
+ }
1514
+ )
1515
+ ] }) : /* @__PURE__ */ a(S, { children: /* @__PURE__ */ c(Q, { className: "astw:flex astw:w-full astw:[&[data-panel-open]_.astw-rotate-target]:rotate-90", children: [
1516
+ /* @__PURE__ */ c(
1517
+ z,
1518
+ {
1519
+ render: /* @__PURE__ */ a("span", { className: "astw:flex astw:w-full" }),
1520
+ tooltip: s.title,
1521
+ children: [
1522
+ s.icon,
1523
+ /* @__PURE__ */ a("span", { children: s.title })
1524
+ ]
1525
+ }
1526
+ ),
1527
+ !!s.items?.length && /* @__PURE__ */ c(q, { className: "astw-rotate-target", render: /* @__PURE__ */ a("span", {}), children: [
1528
+ /* @__PURE__ */ a(W, {}),
1529
+ /* @__PURE__ */ a("span", { className: "astw:sr-only", children: e("toggle") })
1530
+ ] })
1531
+ ] }) }),
1532
+ !!s.items?.length && /* @__PURE__ */ a(rt, { children: /* @__PURE__ */ a(at, { children: s.items?.map((r) => /* @__PURE__ */ a(va, { children: /* @__PURE__ */ a(
1533
+ ya,
1534
+ {
1535
+ render: /* @__PURE__ */ a(
1536
+ $,
1646
1537
  {
1647
- render: /* @__PURE__ */ a(
1648
- $,
1649
- {
1650
- to: r.url,
1651
- className: r.url === t.currentPath ? "astw:bg-sidebar-accent astw:font-medium" : void 0
1652
- }
1653
- ),
1654
- children: /* @__PURE__ */ a("span", { children: r.title })
1538
+ to: r.url,
1539
+ className: r.url === t.currentPath ? "astw:bg-sidebar-accent astw:font-medium" : void 0
1655
1540
  }
1656
- ) }, r.title)) }) })
1657
- ]
1658
- },
1659
- s.title
1660
- )) }) });
1541
+ ),
1542
+ children: /* @__PURE__ */ a("span", { children: r.title })
1543
+ }
1544
+ ) }, r.title)) }) })
1545
+ ] }, s.title)) }) });
1661
1546
  }, Aa = [104, 80, 112, 88, 96, 100, 84, 92], Ea = () => /* @__PURE__ */ a(gt, { children: /* @__PURE__ */ a(bt, { className: "astw:px-2", children: Aa.map((t, e) => /* @__PURE__ */ a(I, { children: /* @__PURE__ */ c("div", { className: "astw:flex astw:items-center astw:gap-2 astw:py-1.5", children: [
1662
1547
  /* @__PURE__ */ a("div", { className: "astw:h-4 astw:w-4 astw:rounded-md astw:bg-muted" }),
1663
1548
  /* @__PURE__ */ a(
@@ -1689,10 +1574,7 @@ function Bt({ className: t, ...e }) {
1689
1574
  "li",
1690
1575
  {
1691
1576
  "data-slot": "breadcrumb-item",
1692
- className: m(
1693
- "astw:inline-flex astw:items-center astw:gap-1.5",
1694
- t
1695
- ),
1577
+ className: m("astw:inline-flex astw:items-center astw:gap-1.5", t),
1696
1578
  ...e
1697
1579
  }
1698
1580
  );
@@ -1704,10 +1586,7 @@ function Dt({
1704
1586
  to: r,
1705
1587
  ...n
1706
1588
  }) {
1707
- const o = m(
1708
- "astw:hover:text-foreground astw:transition-colors",
1709
- e
1710
- );
1589
+ const o = m("astw:hover:text-foreground astw:transition-colors", e);
1711
1590
  return j({
1712
1591
  defaultTagName: "a",
1713
1592
  render: t ?? /* @__PURE__ */ a($, { to: r }),
@@ -1719,11 +1598,7 @@ function Dt({
1719
1598
  }
1720
1599
  });
1721
1600
  }
1722
- function Ma({
1723
- children: t,
1724
- className: e,
1725
- ...s
1726
- }) {
1601
+ function Ma({ children: t, className: e, ...s }) {
1727
1602
  return /* @__PURE__ */ a(
1728
1603
  "li",
1729
1604
  {
@@ -1755,18 +1630,12 @@ const Da = (t, e) => {
1755
1630
  };
1756
1631
  const i = (l, u) => {
1757
1632
  !l || l.length === 0 || l.forEach((w) => {
1758
- const d = `${u}/${w.path}`, h = s(
1759
- w.meta.title,
1760
- w.path
1761
- );
1633
+ const d = `${u}/${w.path}`, h = s(w.meta.title, w.path);
1762
1634
  r[d] = {
1763
1635
  title: h,
1764
1636
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- breadcrumbTitle exists at runtime but not in CommonPageResource type
1765
1637
  breadcrumbTitle: w.meta.breadcrumbTitle
1766
- }, w.subResources && w.subResources.length > 0 && i(
1767
- w.subResources,
1768
- d
1769
- );
1638
+ }, w.subResources && w.subResources.length > 0 && i(w.subResources, d);
1770
1639
  });
1771
1640
  };
1772
1641
  return n.resources && n.resources.length > 0 && i(n.resources, n.path), r;
@@ -1779,12 +1648,10 @@ function La(t, e, s, r) {
1779
1648
  const d = o.slice(0, w + 1).join("/");
1780
1649
  let h = i[d];
1781
1650
  if (!h) {
1782
- const g = Object.entries(i).find(
1783
- ([x]) => {
1784
- const b = x.split("/").map((R) => R.startsWith(":") ? "[^/]+" : R).join("/");
1785
- return new RegExp(`^${b}$`).test(d);
1786
- }
1787
- )?.[1];
1651
+ const g = Object.entries(i).find(([x]) => {
1652
+ const b = x.split("/").map((R) => R.startsWith(":") ? "[^/]+" : R).join("/");
1653
+ return new RegExp(`^${b}$`).test(d);
1654
+ })?.[1];
1788
1655
  g && (h = g);
1789
1656
  }
1790
1657
  let p;
@@ -1841,20 +1708,13 @@ const Ia = () => {
1841
1708
  ] })
1842
1709
  ] }) });
1843
1710
  };
1844
- function $a({
1845
- ...t
1846
- }) {
1711
+ function $a({ ...t }) {
1847
1712
  return /* @__PURE__ */ a(v.Root, { "data-slot": "dialog", ...t });
1848
1713
  }
1849
- function Wa({
1850
- ...t
1851
- }) {
1714
+ function Wa({ ...t }) {
1852
1715
  return /* @__PURE__ */ a(v.Portal, { "data-slot": "dialog-portal", ...t });
1853
1716
  }
1854
- function Fa({
1855
- className: t,
1856
- ...e
1857
- }) {
1717
+ function Fa({ className: t, ...e }) {
1858
1718
  return /* @__PURE__ */ a(
1859
1719
  v.Backdrop,
1860
1720
  {
@@ -1894,10 +1754,7 @@ function Oa({
1894
1754
  )
1895
1755
  ] });
1896
1756
  }
1897
- function ja({
1898
- className: t,
1899
- ...e
1900
- }) {
1757
+ function ja({ className: t, ...e }) {
1901
1758
  return /* @__PURE__ */ a(
1902
1759
  v.Title,
1903
1760
  {
@@ -1928,13 +1785,8 @@ function Ua(t) {
1928
1785
  }), s(r.items, r.icon, [r.title]);
1929
1786
  }), e;
1930
1787
  }
1931
- function Ka({
1932
- routes: t
1933
- }) {
1934
- const e = ye(), s = Ft(null), [r, n] = H(!1), [o, i] = H(""), [l, u] = H(0), w = B(
1935
- () => Ba(t, o),
1936
- [t, o]
1937
- ), d = M((x) => {
1788
+ function Ka({ routes: t }) {
1789
+ const e = ye(), s = Ft(null), [r, n] = H(!1), [o, i] = H(""), [l, u] = H(0), w = B(() => Ba(t, o), [t, o]), d = M((x) => {
1938
1790
  i(x), u(0);
1939
1791
  }, []);
1940
1792
  F(() => {
@@ -1959,9 +1811,7 @@ function Ka({
1959
1811
  if (!x.nativeEvent.isComposing)
1960
1812
  switch (x.key) {
1961
1813
  case "ArrowDown":
1962
- x.preventDefault(), u(
1963
- (b) => b < w.length - 1 ? b + 1 : b
1964
- );
1814
+ x.preventDefault(), u((b) => b < w.length - 1 ? b + 1 : b);
1965
1815
  break;
1966
1816
  case "ArrowUp":
1967
1817
  x.preventDefault(), u((b) => b > 0 ? b - 1 : b);
@@ -1985,9 +1835,7 @@ function Ka({
1985
1835
  listRef: s
1986
1836
  };
1987
1837
  }
1988
- function Va({
1989
- navItems: t
1990
- }) {
1838
+ function Va({ navItems: t }) {
1991
1839
  const e = E(), s = B(() => Ua(t), [t]), {
1992
1840
  open: r,
1993
1841
  handleOpenChange: n,
@@ -2020,32 +1868,25 @@ function Va({
2020
1868
  }
2021
1869
  )
2022
1870
  ] }),
2023
- /* @__PURE__ */ a(
2024
- "div",
1871
+ /* @__PURE__ */ a("div", { ref: h, className: "astw:max-h-75 astw:overflow-y-auto astw:overflow-x-hidden", children: u.length === 0 ? /* @__PURE__ */ a("div", { className: "astw:py-6 astw:text-center astw:text-sm astw:text-muted-foreground", children: e("commandPaletteNoResults") }) : /* @__PURE__ */ a("div", { className: "astw:p-1", children: u.map((p, g) => /* @__PURE__ */ c(
1872
+ "button",
2025
1873
  {
2026
- ref: h,
2027
- className: "astw:max-h-75 astw:overflow-y-auto astw:overflow-x-hidden",
2028
- children: u.length === 0 ? /* @__PURE__ */ a("div", { className: "astw:py-6 astw:text-center astw:text-sm astw:text-muted-foreground", children: e("commandPaletteNoResults") }) : /* @__PURE__ */ a("div", { className: "astw:p-1", children: u.map((p, g) => /* @__PURE__ */ c(
2029
- "button",
2030
- {
2031
- "data-index": g,
2032
- onClick: () => w(p),
2033
- className: m(
2034
- "astw:relative astw:flex astw:flex-col astw:w-full astw:cursor-pointer astw:select-none astw:items-start astw:rounded-sm astw:px-2 astw:py-2 astw:text-sm astw:outline-none astw:text-left",
2035
- g === l ? "astw:bg-accent astw:text-accent-foreground" : "astw:hover:bg-accent astw:hover:text-accent-foreground"
2036
- ),
2037
- children: [
2038
- /* @__PURE__ */ a("span", { className: "astw:truncate astw:w-full astw:text-left", children: p.breadcrumb.join(" > ") }),
2039
- /* @__PURE__ */ c("span", { className: "astw:text-[11px] astw:text-muted-foreground astw:truncate astw:w-full astw:text-left", children: [
2040
- "/",
2041
- p.path
2042
- ] })
2043
- ]
2044
- },
2045
- p.path
2046
- )) })
2047
- }
2048
- )
1874
+ "data-index": g,
1875
+ onClick: () => w(p),
1876
+ className: m(
1877
+ "astw:relative astw:flex astw:flex-col astw:w-full astw:cursor-pointer astw:select-none astw:items-start astw:rounded-sm astw:px-2 astw:py-2 astw:text-sm astw:outline-none astw:text-left",
1878
+ g === l ? "astw:bg-accent astw:text-accent-foreground" : "astw:hover:bg-accent astw:hover:text-accent-foreground"
1879
+ ),
1880
+ children: [
1881
+ /* @__PURE__ */ a("span", { className: "astw:truncate astw:w-full astw:text-left", children: p.breadcrumb.join(" > ") }),
1882
+ /* @__PURE__ */ c("span", { className: "astw:text-[11px] astw:text-muted-foreground astw:truncate astw:w-full astw:text-left", children: [
1883
+ "/",
1884
+ p.path
1885
+ ] })
1886
+ ]
1887
+ },
1888
+ p.path
1889
+ )) }) })
2049
1890
  ]
2050
1891
  }
2051
1892
  ) });
@@ -2127,9 +1968,7 @@ const ie = X(null), Gs = (t) => {
2127
1968
  if (new URLSearchParams(window.location.search).has("code"))
2128
1969
  try {
2129
1970
  await e.handleCallback();
2130
- const w = Ya(
2131
- new URL(window.location.href)
2132
- );
1971
+ const w = Ya(new URL(window.location.href));
2133
1972
  window.history.replaceState({}, "", w);
2134
1973
  } catch (w) {
2135
1974
  console.error("Failed to handle callback:", w);
@@ -2157,9 +1996,7 @@ const ie = X(null), Gs = (t) => {
2157
1996
  }, le = () => {
2158
1997
  const t = L(ie);
2159
1998
  if (!t)
2160
- throw new Error(
2161
- "useAuth/useAuthSuspense must be used within an AuthProvider"
2162
- );
1999
+ throw new Error("useAuth/useAuthSuspense must be used within an AuthProvider");
2163
2000
  return t;
2164
2001
  }, qs = () => {
2165
2002
  const t = le(), { isAuthenticated: e, error: s, isReady: r } = t.authState;
@@ -2293,11 +2130,7 @@ function os(t) {
2293
2130
  if (typeof t == "object" && t !== null) {
2294
2131
  const e = t, s = [];
2295
2132
  e.line1 && s.push(String(e.line1)), e.line2 && s.push(String(e.line2));
2296
- const r = [
2297
- e.city,
2298
- e.state || e.province,
2299
- e.zip || e.postalCode
2300
- ].filter(Boolean).join(", ");
2133
+ const r = [e.city, e.state || e.province, e.zip || e.postalCode].filter(Boolean).join(", ");
2301
2134
  return r && s.push(r), e.country && s.push(String(e.country)), s;
2302
2135
  }
2303
2136
  return [String(t)];
@@ -2423,14 +2256,7 @@ function ms({ field: t }) {
2423
2256
  if (!r || !s)
2424
2257
  return /* @__PURE__ */ a("span", { className: "astw:text-sm astw:font-medium astw:text-foreground", children: n });
2425
2258
  const o = s.replace("{id}", r);
2426
- return /* @__PURE__ */ a(
2427
- "a",
2428
- {
2429
- href: o,
2430
- className: "astw:text-sm astw:text-primary astw:hover:underline",
2431
- children: n
2432
- }
2433
- );
2259
+ return /* @__PURE__ */ a("a", { href: o, className: "astw:text-sm astw:text-primary astw:hover:underline", children: n });
2434
2260
  }
2435
2261
  function Lt(t) {
2436
2262
  switch (t.type) {
@@ -2542,13 +2368,7 @@ function Xs({
2542
2368
  o && /* @__PURE__ */ a("div", { children: o })
2543
2369
  ] }),
2544
2370
  /* @__PURE__ */ a("div", { className: "astw:px-6 astw:pb-4", children: l ? /* @__PURE__ */ a("div", { className: "astw:space-y-4", children: i.map((d, h) => /* @__PURE__ */ c(f.Fragment, { children: [
2545
- h > 0 && /* @__PURE__ */ a(
2546
- "div",
2547
- {
2548
- className: "astw:h-px astw:bg-border",
2549
- role: "separator"
2550
- }
2551
- ),
2371
+ h > 0 && /* @__PURE__ */ a("div", { className: "astw:h-px astw:bg-border", role: "separator" }),
2552
2372
  w(d)
2553
2373
  ] }, d.id)) }) : /* @__PURE__ */ a("p", { className: "astw:text-sm astw:text-muted-foreground", children: "No information available" }) })
2554
2374
  ]
@@ -2567,14 +2387,7 @@ const xt = f.forwardRef(
2567
2387
  )
2568
2388
  );
2569
2389
  xt.displayName = "Layout.Column";
2570
- function bs({
2571
- columns: t,
2572
- className: e,
2573
- gap: s = 4,
2574
- title: r,
2575
- actions: n,
2576
- children: o
2577
- }) {
2390
+ function bs({ columns: t, className: e, gap: s = 4, title: r, actions: n, children: o }) {
2578
2391
  if (process.env.NODE_ENV !== "production") {
2579
2392
  const h = f.Children.toArray(o).reduce((p, g) => f.isValidElement(g) && g.type === xt ? p + 1 : p, 0);
2580
2393
  if (h !== t)
@@ -2589,16 +2402,10 @@ function bs({
2589
2402
  t === 1 && "astw:flex-col",
2590
2403
  // 2 columns: Stack on mobile, side-by-side on desktop (lg: ≥1024px)
2591
2404
  // Main column flexible, side column fixed 360px
2592
- t === 2 && [
2593
- "astw:flex-col",
2594
- "astw:lg:flex-row"
2595
- ],
2405
+ t === 2 && ["astw:flex-col", "astw:lg:flex-row"],
2596
2406
  // 3 columns: Stack on mobile, 3 columns side-by-side on desktop (xl: ≥1280px)
2597
2407
  // Outer columns fixed 360px, middle column flexible
2598
- t === 3 && [
2599
- "astw:flex-col",
2600
- "astw:xl:flex-row"
2601
- ],
2408
+ t === 3 && ["astw:flex-col", "astw:xl:flex-row"],
2602
2409
  e
2603
2410
  ), u = f.useMemo(() => t === 1 ? f.Children.map(o, (d) => d) : t === 2 ? f.Children.map(o, (d, h) => f.isValidElement(d) ? f.cloneElement(d, {
2604
2411
  className: m(
@@ -2622,14 +2429,14 @@ function bs({
2622
2429
  "header",
2623
2430
  {
2624
2431
  className: "astw:w-full astw:flex astw:justify-between astw:items-center",
2625
- style: { padding: "1.5rem", paddingBottom: "1rem" },
2432
+ style: { paddingTop: "1rem", paddingBottom: "1rem" },
2626
2433
  children: [
2627
2434
  r && /* @__PURE__ */ a("h1", { style: { fontSize: "1.5rem", fontWeight: "bold" }, children: r }),
2628
2435
  n && n.length > 0 && /* @__PURE__ */ a("div", { className: "astw:flex astw:gap-2 astw:items-center", children: n.map((d, h) => /* @__PURE__ */ a(f.Fragment, { children: d }, h)) })
2629
2436
  ]
2630
2437
  }
2631
2438
  ),
2632
- /* @__PURE__ */ a("div", { style: { padding: w ? "0 1.5rem 1.5rem 1.5rem" : "1.5rem" }, children: /* @__PURE__ */ a("div", { className: l, children: u }) })
2439
+ /* @__PURE__ */ a("div", { style: { padding: w ? "0 0 1rem 0" : "1rem 0 1rem 0" }, children: /* @__PURE__ */ a("div", { className: l, children: u }) })
2633
2440
  ] });
2634
2441
  }
2635
2442
  bs.Column = xt;
package/package.json CHANGED
@@ -1,20 +1,35 @@
1
1
  {
2
2
  "name": "@tailor-platform/app-shell",
3
- "version": "0.27.1",
4
- "type": "module",
3
+ "version": "0.27.3",
4
+ "description": "An opinionated React application framework for building ERP applications on Tailor Platform",
5
+ "keywords": [
6
+ "app-shell",
7
+ "erp",
8
+ "react",
9
+ "routing",
10
+ "sidebar",
11
+ "tailor-platform",
12
+ "vite"
13
+ ],
14
+ "homepage": "https://github.com/tailor-platform/app-shell/tree/main/packages/core#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/tailor-platform"
17
+ },
18
+ "license": "MIT",
5
19
  "repository": {
6
20
  "type": "git",
7
21
  "url": "https://github.com/tailor-platform/app-shell",
8
22
  "directory": "packages/core"
9
23
  },
10
- "publishConfig": {
11
- "access": "public"
12
- },
24
+ "files": [
25
+ "dist/**"
26
+ ],
27
+ "type": "module",
13
28
  "exports": {
14
29
  "./styles": "./dist/app-shell.css",
15
30
  "./theme.css": "./dist/theme.css",
16
31
  ".": {
17
- "types": "./dist/index.d.ts",
32
+ "types": "./dist/app-shell.d.ts",
18
33
  "default": "./dist/app-shell.js"
19
34
  },
20
35
  "./vite-plugin": {
@@ -22,12 +37,8 @@
22
37
  "default": "./dist/vite-plugin.js"
23
38
  }
24
39
  },
25
- "files": [
26
- "dist/**"
27
- ],
28
- "peerDependencies": {
29
- "react": ">= 19",
30
- "react-dom": ">= 19"
40
+ "publishConfig": {
41
+ "access": "public"
31
42
  },
32
43
  "dependencies": {
33
44
  "@base-ui/react": "^1.2.0",
@@ -36,8 +47,8 @@
36
47
  "change-case": "^5.4.4",
37
48
  "class-variance-authority": "^0.7.1",
38
49
  "clsx": "^2.1.1",
39
- "es-toolkit": "^1.44.0",
40
- "graphql": "^16.12.0",
50
+ "es-toolkit": "^1.45.1",
51
+ "graphql": "^16.13.0",
41
52
  "lucide-react": "^0.562.0",
42
53
  "next-themes": "^0.4.6",
43
54
  "oauth4webapi": "^3.8.5",
@@ -50,7 +61,6 @@
50
61
  "@tailor-platform/app-shell-vite-plugin": "0.1.0"
51
62
  },
52
63
  "devDependencies": {
53
- "@eslint/js": "^10.0.1",
54
64
  "@tailwindcss/postcss": "^4.2.0",
55
65
  "@testing-library/react": "^16.3.2",
56
66
  "@testing-library/user-event": "^14.6.1",
@@ -58,25 +68,25 @@
58
68
  "@types/react": "^19",
59
69
  "@types/react-dom": "^19",
60
70
  "@vitejs/plugin-react": "^5.1.2",
61
- "eslint": "^9.0.0",
62
- "eslint-plugin-react-hooks": "^7.0.1",
63
71
  "happy-dom": "^20.6.2",
64
72
  "postcss": "^8",
65
- "prettier": "^3.8.1",
66
- "tailwindcss": "^4.1.18",
73
+ "tailwindcss": "^4.2.1",
67
74
  "tw-animate-css": "^1.4.0",
68
75
  "typescript": "^5",
69
- "typescript-eslint": "^8.55.0",
70
76
  "vite": "^7.3.1",
71
77
  "vite-plugin-dts": "^4.5.0",
72
78
  "vite-plugin-externalize-deps": "^0.10.0",
73
79
  "vite-tsconfig-paths": "^6.0.4",
74
80
  "vitest": "^4.0.18"
75
81
  },
82
+ "peerDependencies": {
83
+ "react": ">= 19",
84
+ "react-dom": ">= 19"
85
+ },
76
86
  "scripts": {
77
87
  "dev": "vite build --watch --mode development",
78
88
  "build": "vite build",
79
- "lint": "eslint .",
89
+ "lint": "oxlint -c .oxlintrc.jsonc",
80
90
  "test": "vitest run",
81
91
  "type-check": "tsc --incremental"
82
92
  }