@motor-hero/ui-kit 0.19.0 → 0.20.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.
@@ -1,16 +1,16 @@
1
- import { type TenantTheme } from "../lib/tenant-theme";
1
+ import { type CompanyTheme } from "../lib/company-theme";
2
2
  type Theme = "dark" | "light" | "system";
3
3
  type ThemeProviderProps = {
4
4
  children: React.ReactNode;
5
5
  defaultTheme?: Theme;
6
6
  storageKey?: string;
7
- tenantTheme?: TenantTheme;
7
+ companyTheme?: CompanyTheme;
8
8
  };
9
9
  type ThemeProviderState = {
10
10
  theme: Theme;
11
11
  setTheme: (theme: Theme) => void;
12
12
  };
13
- export declare function ThemeProvider({ children, defaultTheme, storageKey, tenantTheme, ...props }: ThemeProviderProps): import("react").JSX.Element;
13
+ export declare function ThemeProvider({ children, defaultTheme, storageKey, companyTheme, ...props }: ThemeProviderProps): import("react").JSX.Element;
14
14
  export declare function useTheme(): ThemeProviderState;
15
15
  export type { Theme, ThemeProviderProps, ThemeProviderState };
16
16
  //# sourceMappingURL=theme-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme-provider.d.ts","sourceRoot":"","sources":["../../src/components/theme-provider.tsx"],"names":[],"mappings":"AACA,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAExE,KAAK,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;AAExC,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,YAAY,CAAC,EAAE,KAAK,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B,CAAA;AAED,KAAK,kBAAkB,GAAG;IACxB,KAAK,EAAE,KAAK,CAAA;IACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACjC,CAAA;AASD,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,YAAuB,EACvB,UAAuB,EACvB,WAAW,EACX,GAAG,KAAK,EACT,EAAE,kBAAkB,+BAsCpB;AAED,wBAAgB,QAAQ,uBAMvB;AAED,YAAY,EAAE,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,CAAA"}
1
+ {"version":3,"file":"theme-provider.d.ts","sourceRoot":"","sources":["../../src/components/theme-provider.tsx"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAE3E,KAAK,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;AAExC,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,YAAY,CAAC,EAAE,KAAK,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,YAAY,CAAA;CAC5B,CAAA;AAED,KAAK,kBAAkB,GAAG;IACxB,KAAK,EAAE,KAAK,CAAA;IACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACjC,CAAA;AASD,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,YAAuB,EACvB,UAAuB,EACvB,YAAY,EACZ,GAAG,KAAK,EACT,EAAE,kBAAkB,+BAsCpB;AAED,wBAAgB,QAAQ,uBAMvB;AAED,YAAY,EAAE,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,CAAA"}
@@ -0,0 +1,10 @@
1
+ export type UseCompanySubdomainOptions = {
2
+ enableOverride?: boolean;
3
+ overrideStorageKey?: string;
4
+ };
5
+ export type UseCompanySubdomainResult = {
6
+ subdomain: string | undefined;
7
+ };
8
+ export declare function getSubdomain(hostname: string): string | undefined;
9
+ export declare function useCompanySubdomain(opts?: UseCompanySubdomainOptions): UseCompanySubdomainResult;
10
+ //# sourceMappingURL=use-company-subdomain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-company-subdomain.d.ts","sourceRoot":"","sources":["../../src/hooks/use-company-subdomain.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,0BAA0B,GAAG;IACvC,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;CAC9B,CAAA;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMjE;AAiBD,wBAAgB,mBAAmB,CACjC,IAAI,GAAE,0BAA+B,GACpC,yBAAyB,CAc3B"}
package/dist/index.cjs CHANGED
@@ -56,11 +56,13 @@ __export(index_exports, {
56
56
  ThemeProvider: () => ThemeProvider,
57
57
  Toaster: () => Toaster,
58
58
  UserMenu: () => UserMenu,
59
- applyTenantTheme: () => applyTenantTheme,
59
+ applyCompanyTheme: () => applyCompanyTheme,
60
60
  cn: () => cn,
61
61
  defaultRenderLink: () => defaultRenderLink,
62
62
  extractApiError: () => extractApiError,
63
+ getSubdomain: () => getSubdomain,
63
64
  toast: () => import_sonner2.toast,
65
+ useCompanySubdomain: () => useCompanySubdomain,
64
66
  useCustomToast: () => useCustomToast,
65
67
  useDisclosure: () => useDisclosure,
66
68
  useIsDesktop: () => useIsDesktop,
@@ -71,7 +73,7 @@ module.exports = __toCommonJS(index_exports);
71
73
  // src/components/theme-provider.tsx
72
74
  var import_react = require("react");
73
75
 
74
- // src/lib/tenant-theme.ts
76
+ // src/lib/company-theme.ts
75
77
  var VAR_MAP = {
76
78
  primary: "--color-primary",
77
79
  primaryForeground: "--color-primary-foreground",
@@ -81,8 +83,14 @@ var VAR_MAP = {
81
83
  accentForeground: "--color-accent-foreground",
82
84
  ring: "--color-ring"
83
85
  };
84
- function applyTenantTheme(root, tenantTheme, mode) {
85
- const tokens = tenantTheme ? mode === "dark" ? { ...tenantTheme.light, ...tenantTheme.dark } : tenantTheme.light : {};
86
+ function definedTokens(tokens) {
87
+ if (!tokens) return {};
88
+ return Object.fromEntries(
89
+ Object.entries(tokens).filter(([, value]) => value != null)
90
+ );
91
+ }
92
+ function applyCompanyTheme(root, companyTheme, mode) {
93
+ const tokens = companyTheme ? mode === "dark" ? { ...companyTheme.light, ...definedTokens(companyTheme.dark) } : companyTheme.light : {};
86
94
  for (const key of Object.keys(VAR_MAP)) {
87
95
  const value = tokens[key];
88
96
  if (value) root.style.setProperty(VAR_MAP[key], value);
@@ -101,7 +109,7 @@ function ThemeProvider({
101
109
  children,
102
110
  defaultTheme = "system",
103
111
  storageKey = "ui-theme",
104
- tenantTheme,
112
+ companyTheme,
105
113
  ...props
106
114
  }) {
107
115
  const [theme, setTheme] = (0, import_react.useState)(
@@ -112,7 +120,7 @@ function ThemeProvider({
112
120
  const applyResolved = (resolved) => {
113
121
  root.classList.remove("light", "dark");
114
122
  root.classList.add(resolved);
115
- applyTenantTheme(root, tenantTheme, resolved);
123
+ applyCompanyTheme(root, companyTheme, resolved);
116
124
  };
117
125
  if (theme === "system") {
118
126
  const mql = window.matchMedia("(prefers-color-scheme: dark)");
@@ -122,7 +130,7 @@ function ThemeProvider({
122
130
  return () => mql.removeEventListener("change", onChange);
123
131
  }
124
132
  applyResolved(theme);
125
- }, [theme, tenantTheme]);
133
+ }, [theme, companyTheme]);
126
134
  const value = {
127
135
  theme,
128
136
  setTheme: (theme2) => {
@@ -140,6 +148,42 @@ function useTheme() {
140
148
  return context;
141
149
  }
142
150
 
151
+ // src/hooks/use-company-subdomain.ts
152
+ var import_react2 = require("react");
153
+ function getSubdomain(hostname) {
154
+ const labels = hostname.split(".");
155
+ if (labels.length < 2) return void 0;
156
+ const first = labels[0];
157
+ if (!first || first === "www" || first === "localhost") return void 0;
158
+ return first;
159
+ }
160
+ function resolveOverride(storageKey) {
161
+ if (typeof window === "undefined") return void 0;
162
+ const params = new URLSearchParams(window.location.search);
163
+ if (params.has("company")) {
164
+ const value = params.get("company");
165
+ if (value) {
166
+ window.localStorage.setItem(storageKey, value);
167
+ return value;
168
+ }
169
+ window.localStorage.removeItem(storageKey);
170
+ return void 0;
171
+ }
172
+ return window.localStorage.getItem(storageKey) ?? void 0;
173
+ }
174
+ function useCompanySubdomain(opts = {}) {
175
+ const { enableOverride = false, overrideStorageKey = "company-subdomain" } = opts;
176
+ const [subdomain] = (0, import_react2.useState)(() => {
177
+ if (enableOverride) {
178
+ const override = resolveOverride(overrideStorageKey);
179
+ if (override) return override;
180
+ }
181
+ if (typeof window === "undefined") return void 0;
182
+ return getSubdomain(window.location.hostname);
183
+ });
184
+ return { subdomain };
185
+ }
186
+
143
187
  // src/components/mode-toggle.tsx
144
188
  var DropdownMenu = __toESM(require("@radix-ui/react-dropdown-menu"), 1);
145
189
  var import_lucide_react = require("lucide-react");
@@ -369,11 +413,11 @@ function ProgressBar({
369
413
  }
370
414
 
371
415
  // src/components/form-field.tsx
372
- var import_react2 = require("react");
416
+ var import_react3 = require("react");
373
417
  var import_jsx_runtime9 = require("react/jsx-runtime");
374
418
  function FormField({ label, htmlFor, error, required, children, className }) {
375
- const errorId = (0, import_react2.useId)();
376
- const field = error && (0, import_react2.isValidElement)(children) ? (0, import_react2.cloneElement)(children, {
419
+ const errorId = (0, import_react3.useId)();
420
+ const field = error && (0, import_react3.isValidElement)(children) ? (0, import_react3.cloneElement)(children, {
377
421
  "aria-invalid": true,
378
422
  "aria-describedby": [
379
423
  children.props["aria-describedby"],
@@ -844,7 +888,7 @@ function DataTableWrapper({
844
888
  }
845
889
 
846
890
  // src/components/mobile-card-list.tsx
847
- var import_react3 = require("react");
891
+ var import_react4 = require("react");
848
892
  var import_jsx_runtime19 = require("react/jsx-runtime");
849
893
  var SCROLL_THRESHOLD = 8;
850
894
  function MobileCardList({
@@ -855,8 +899,8 @@ function MobileCardList({
855
899
  loadingCount = 5,
856
900
  className
857
901
  }) {
858
- const start = (0, import_react3.useRef)(null);
859
- const scrolled = (0, import_react3.useRef)(false);
902
+ const start = (0, import_react4.useRef)(null);
903
+ const scrolled = (0, import_react4.useRef)(false);
860
904
  const onTouchStart = (e) => {
861
905
  const t = e.touches[0];
862
906
  start.current = { x: t.clientX, y: t.clientY };
@@ -958,10 +1002,10 @@ function Toaster(props) {
958
1002
 
959
1003
  // src/components/app-shell.tsx
960
1004
  var import_lucide_react6 = require("lucide-react");
961
- var import_react6 = require("react");
1005
+ var import_react7 = require("react");
962
1006
 
963
1007
  // src/components/sidebar-nav.tsx
964
- var import_react4 = require("react");
1008
+ var import_react5 = require("react");
965
1009
 
966
1010
  // src/components/types.tsx
967
1011
  var import_jsx_runtime22 = require("react/jsx-runtime");
@@ -1000,14 +1044,14 @@ function SidebarNav({
1000
1044
  !isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate", children: item.label })
1001
1045
  ] })
1002
1046
  });
1003
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react4.Fragment, { children: link }, item.href);
1047
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react5.Fragment, { children: link }, item.href);
1004
1048
  }) });
1005
1049
  }
1006
1050
 
1007
1051
  // src/components/user-menu.tsx
1008
1052
  var DropdownMenu2 = __toESM(require("@radix-ui/react-dropdown-menu"), 1);
1009
1053
  var import_lucide_react5 = require("lucide-react");
1010
- var import_react5 = require("react");
1054
+ var import_react6 = require("react");
1011
1055
  var import_vaul2 = require("vaul");
1012
1056
  var import_jsx_runtime24 = require("react/jsx-runtime");
1013
1057
  function initials(user) {
@@ -1028,7 +1072,7 @@ function UserMenu({
1028
1072
  align = "end"
1029
1073
  }) {
1030
1074
  const isDesktop = useIsDesktop();
1031
- const [open, setOpen] = (0, import_react5.useState)(false);
1075
+ const [open, setOpen] = (0, import_react6.useState)(false);
1032
1076
  const label = initials(user);
1033
1077
  const trigger = /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1034
1078
  "button",
@@ -1193,8 +1237,8 @@ function AppShell({
1193
1237
  defaultCollapsed = false,
1194
1238
  children
1195
1239
  }) {
1196
- const [collapsed, setCollapsed] = (0, import_react6.useState)(defaultCollapsed);
1197
- const [mobileOpen, setMobileOpen] = (0, import_react6.useState)(false);
1240
+ const [collapsed, setCollapsed] = (0, import_react7.useState)(defaultCollapsed);
1241
+ const [mobileOpen, setMobileOpen] = (0, import_react7.useState)(false);
1198
1242
  const nav = (isCollapsed, onNavigate) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1199
1243
  SidebarNav,
1200
1244
  {
@@ -1283,7 +1327,7 @@ function AppShell({
1283
1327
  // src/components/row-actions-menu.tsx
1284
1328
  var DropdownMenu3 = __toESM(require("@radix-ui/react-dropdown-menu"), 1);
1285
1329
  var import_lucide_react7 = require("lucide-react");
1286
- var import_react7 = require("react");
1330
+ var import_react8 = require("react");
1287
1331
  var import_vaul3 = require("vaul");
1288
1332
  var import_jsx_runtime26 = require("react/jsx-runtime");
1289
1333
  var triggerClass = "inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50";
@@ -1297,7 +1341,7 @@ function RowActionsMenu({
1297
1341
  renderLink = defaultRenderLink
1298
1342
  }) {
1299
1343
  const isDesktop = useIsDesktop();
1300
- const [open, setOpen] = (0, import_react7.useState)(false);
1344
+ const [open, setOpen] = (0, import_react8.useState)(false);
1301
1345
  if (actions.length === 0) return null;
1302
1346
  const trigger = /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1303
1347
  "button",
@@ -1414,20 +1458,20 @@ function extractApiError(err, fallbackMessage = "Ocorreu um erro inesperado.") {
1414
1458
  }
1415
1459
 
1416
1460
  // src/hooks/use-disclosure.ts
1417
- var import_react8 = require("react");
1461
+ var import_react9 = require("react");
1418
1462
  function useDisclosure(initial = false) {
1419
- const [open, setOpen] = (0, import_react8.useState)(initial);
1420
- const onOpen = (0, import_react8.useCallback)(() => setOpen(true), []);
1421
- const onClose = (0, import_react8.useCallback)(() => setOpen(false), []);
1422
- const onToggle = (0, import_react8.useCallback)(() => setOpen((v) => !v), []);
1463
+ const [open, setOpen] = (0, import_react9.useState)(initial);
1464
+ const onOpen = (0, import_react9.useCallback)(() => setOpen(true), []);
1465
+ const onClose = (0, import_react9.useCallback)(() => setOpen(false), []);
1466
+ const onToggle = (0, import_react9.useCallback)(() => setOpen((v) => !v), []);
1423
1467
  return { open, onOpen, onClose, onToggle, setOpen };
1424
1468
  }
1425
1469
 
1426
1470
  // src/hooks/use-toast.ts
1427
1471
  var import_sonner2 = require("sonner");
1428
- var import_react9 = require("react");
1472
+ var import_react10 = require("react");
1429
1473
  function useCustomToast() {
1430
- const showToast = (0, import_react9.useCallback)(
1474
+ const showToast = (0, import_react10.useCallback)(
1431
1475
  (title, description, status = "success") => {
1432
1476
  switch (status) {
1433
1477
  case "success":
@@ -1476,11 +1520,13 @@ function useCustomToast() {
1476
1520
  ThemeProvider,
1477
1521
  Toaster,
1478
1522
  UserMenu,
1479
- applyTenantTheme,
1523
+ applyCompanyTheme,
1480
1524
  cn,
1481
1525
  defaultRenderLink,
1482
1526
  extractApiError,
1527
+ getSubdomain,
1483
1528
  toast,
1529
+ useCompanySubdomain,
1484
1530
  useCustomToast,
1485
1531
  useDisclosure,
1486
1532
  useIsDesktop,