@tailor-platform/app-shell 0.22.0 → 0.24.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/dist/app-shell.css +1 -1
- package/dist/app-shell.js +859 -648
- package/dist/index.d.ts +267 -66
- package/package.json +4 -6
package/dist/index.d.ts
CHANGED
|
@@ -14,42 +14,26 @@ import { useRouteError } from 'react-router';
|
|
|
14
14
|
import { useSearchParams } from 'react-router';
|
|
15
15
|
import { VariantProps } from 'class-variance-authority';
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
* Context provided to access control functions
|
|
19
|
-
*/
|
|
20
|
-
declare type AccessContext = {
|
|
21
|
-
params: Params;
|
|
22
|
-
searchParams: URLSearchParams;
|
|
23
|
-
signal: AbortSignal;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
declare type AccessControl = (context: AccessContext) => Promise<AccessResult> | AccessResult;
|
|
17
|
+
export declare const AppShell: (props: AppShellProps) => JSX.Element | null;
|
|
27
18
|
|
|
28
19
|
/**
|
|
29
|
-
*
|
|
20
|
+
* Context for static configuration (title, icon, configurations).
|
|
21
|
+
* Changes to this context will cause RouterContainer to re-render.
|
|
30
22
|
*/
|
|
31
|
-
declare type
|
|
32
|
-
/**
|
|
33
|
-
* Resource is visible and accessible
|
|
34
|
-
*/
|
|
35
|
-
{
|
|
36
|
-
state: "visible";
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Resource is hidden and not accessible
|
|
40
|
-
*/
|
|
41
|
-
| {
|
|
42
|
-
state: "hidden";
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export declare const AppShell: (props: AppShellProps) => JSX.Element | null;
|
|
46
|
-
|
|
47
|
-
declare type AppShellContextType = {
|
|
23
|
+
declare type AppShellConfigContextType = {
|
|
48
24
|
title?: string;
|
|
49
25
|
icon?: ReactNode;
|
|
50
26
|
configurations: RootConfiguration;
|
|
51
27
|
};
|
|
52
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Context for dynamic data (contextData).
|
|
31
|
+
* Changes to this context will NOT cause RouterContainer to re-render.
|
|
32
|
+
*/
|
|
33
|
+
declare type AppShellDataContextType = {
|
|
34
|
+
contextData: ContextData;
|
|
35
|
+
};
|
|
36
|
+
|
|
53
37
|
export declare type AppShellProps = React.PropsWithChildren<{
|
|
54
38
|
/**
|
|
55
39
|
* App shell title
|
|
@@ -64,19 +48,15 @@ export declare type AppShellProps = React.PropsWithChildren<{
|
|
|
64
48
|
*/
|
|
65
49
|
basePath?: string;
|
|
66
50
|
/**
|
|
67
|
-
* A component to be rendered at the root level of AppShell
|
|
68
|
-
*
|
|
51
|
+
* A component to be rendered at the root level of AppShell.
|
|
52
|
+
* Use guards with redirectTo() for redirects.
|
|
69
53
|
*
|
|
70
54
|
* @example
|
|
71
55
|
* ```tsx
|
|
72
|
-
* // Render a component
|
|
73
56
|
* rootComponent: () => <DashboardHome />
|
|
74
|
-
*
|
|
75
|
-
* // Redirect to a resource
|
|
76
|
-
* rootComponent: redirectToResource("dashboard/overview")
|
|
77
57
|
* ```
|
|
78
58
|
*/
|
|
79
|
-
rootComponent?: (
|
|
59
|
+
rootComponent?: () => React.ReactNode;
|
|
80
60
|
/**
|
|
81
61
|
* Navigation configuration
|
|
82
62
|
*/
|
|
@@ -120,8 +100,52 @@ export declare type AppShellProps = React.PropsWithChildren<{
|
|
|
120
100
|
* ```
|
|
121
101
|
*/
|
|
122
102
|
errorBoundary?: ErrorBoundaryComponent;
|
|
103
|
+
/**
|
|
104
|
+
* Custom context data accessible from guards and components.
|
|
105
|
+
*
|
|
106
|
+
* Use module augmentation to define the type of context data:
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* // types.d.ts
|
|
111
|
+
* declare module "@tailor-platform/app-shell" {
|
|
112
|
+
* interface AppShellRegister {
|
|
113
|
+
* contextData: {
|
|
114
|
+
* apiClient: ApiClient;
|
|
115
|
+
* currentUser: User;
|
|
116
|
+
* };
|
|
117
|
+
* }
|
|
118
|
+
* }
|
|
119
|
+
*
|
|
120
|
+
* // App.tsx
|
|
121
|
+
* <AppShell
|
|
122
|
+
* modules={modules}
|
|
123
|
+
* contextData={{ apiClient, currentUser }}
|
|
124
|
+
* />
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
contextData?: ContextData;
|
|
123
128
|
}>;
|
|
124
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Empty interface for module augmentation.
|
|
132
|
+
* Users can extend this to define their own context data type.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* declare module "@tailor-platform/app-shell" {
|
|
137
|
+
* interface AppShellRegister {
|
|
138
|
+
* contextData: {
|
|
139
|
+
* apiClient: ApiClient;
|
|
140
|
+
* currentUser: User;
|
|
141
|
+
* };
|
|
142
|
+
* }
|
|
143
|
+
* }
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export declare interface AppShellRegister {
|
|
147
|
+
}
|
|
148
|
+
|
|
125
149
|
declare type AuthContextType = {
|
|
126
150
|
/**
|
|
127
151
|
* Current authentication state.
|
|
@@ -258,6 +282,21 @@ export declare const badgeVariants: (props?: ({
|
|
|
258
282
|
*/
|
|
259
283
|
declare type BadgeVariantType = "default" | "success" | "warning" | "error" | "neutral" | "outline-success" | "outline-warning" | "outline-error" | "outline-info" | "outline-neutral";
|
|
260
284
|
|
|
285
|
+
/**
|
|
286
|
+
* Supported column count options
|
|
287
|
+
*/
|
|
288
|
+
declare type ColumnCount = 1 | 2 | 3;
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Props for individual Layout.Column component
|
|
292
|
+
*/
|
|
293
|
+
declare interface ColumnProps {
|
|
294
|
+
/** Additional CSS classes */
|
|
295
|
+
className?: string;
|
|
296
|
+
/** Child content */
|
|
297
|
+
children?: ReactNode;
|
|
298
|
+
}
|
|
299
|
+
|
|
261
300
|
/**
|
|
262
301
|
* Column layout options for the card
|
|
263
302
|
*/
|
|
@@ -282,7 +321,6 @@ declare type CommonModuleProps = {
|
|
|
282
321
|
declare type CommonPageResource = {
|
|
283
322
|
path: string;
|
|
284
323
|
type: "component";
|
|
285
|
-
component: () => ReactNode;
|
|
286
324
|
meta: {
|
|
287
325
|
title: LocalizedString;
|
|
288
326
|
icon?: ReactNode;
|
|
@@ -302,11 +340,29 @@ declare type CommonProps = {
|
|
|
302
340
|
*/
|
|
303
341
|
meta?: ResourceMetaProps;
|
|
304
342
|
/**
|
|
305
|
-
*
|
|
343
|
+
* Guards to control access to this module/resource.
|
|
344
|
+
* Guards are executed in order. If any guard returns non-pass result,
|
|
345
|
+
* access is denied.
|
|
346
|
+
*
|
|
347
|
+
* @example
|
|
348
|
+
* ```tsx
|
|
349
|
+
* guards: [
|
|
350
|
+
* ({ context }) => context.currentUser ? pass() : redirectTo("/login"),
|
|
351
|
+
* ({ context }) => context.currentUser.role === "admin" ? pass() : hidden(),
|
|
352
|
+
* ]
|
|
353
|
+
* ```
|
|
306
354
|
*/
|
|
307
|
-
|
|
355
|
+
guards?: Guard[];
|
|
308
356
|
};
|
|
309
357
|
|
|
358
|
+
/**
|
|
359
|
+
* Context data type inferred from AppShellRegister.
|
|
360
|
+
* Falls back to Record<string, unknown> if not augmented.
|
|
361
|
+
*/
|
|
362
|
+
export declare type ContextData = AppShellRegister extends {
|
|
363
|
+
contextData: infer T;
|
|
364
|
+
} ? T : Record<string, unknown>;
|
|
365
|
+
|
|
310
366
|
/**
|
|
311
367
|
* Date format options
|
|
312
368
|
*/
|
|
@@ -391,7 +447,24 @@ export declare const defineI18nLabels: <const L extends Exclude<string, "en">, c
|
|
|
391
447
|
* }
|
|
392
448
|
* ```
|
|
393
449
|
*/
|
|
394
|
-
useT: () => <K extends keyof Def & string>(key: K, ...args: Def[K] extends (props: infer P) => string ? [props: P] : []) => string
|
|
450
|
+
useT: () => (<K extends keyof Def & string>(key: K, ...args: Def[K] extends (props: infer P) => string ? [props: P] : []) => string) & {
|
|
451
|
+
/**
|
|
452
|
+
* Resolve a label with a dynamic key.
|
|
453
|
+
* This is useful when the key is constructed at runtime.
|
|
454
|
+
*
|
|
455
|
+
* @param key - The dynamic key to resolve
|
|
456
|
+
* @param fallback - The fallback value if the key is not found
|
|
457
|
+
* @returns The resolved label or the fallback value
|
|
458
|
+
*
|
|
459
|
+
* @example
|
|
460
|
+
* ```tsx
|
|
461
|
+
* const employeeType = "STAFF";
|
|
462
|
+
* t.dynamic(`employees.${employeeType}`, "Unknown"); // "Staff"
|
|
463
|
+
* t.dynamic("unknown.key", "Default"); // "Default"
|
|
464
|
+
* ```
|
|
465
|
+
*/
|
|
466
|
+
dynamic: (key: string, fallback: string) => string;
|
|
467
|
+
};
|
|
395
468
|
/**
|
|
396
469
|
* A function to get the translater for a specific label key.
|
|
397
470
|
* This is expected to be used in `meta.title` in module/resource definitions.
|
|
@@ -439,18 +512,15 @@ export declare function defineModule(props: DefineModuleProps): Module;
|
|
|
439
512
|
|
|
440
513
|
declare type DefineModuleProps = CommonProps & CommonModuleProps & {
|
|
441
514
|
/**
|
|
442
|
-
* React component to render
|
|
515
|
+
* React component to render.
|
|
516
|
+
* If not provided, the module will redirect to the first resource.
|
|
443
517
|
*
|
|
444
518
|
* @example
|
|
445
519
|
* ```tsx
|
|
446
|
-
* // Render a component
|
|
447
520
|
* component: (props) => <div>{props.title}</div>
|
|
448
|
-
*
|
|
449
|
-
* // Redirect to a resource
|
|
450
|
-
* component: redirectToResource("dashboard/overview")
|
|
451
521
|
* ```
|
|
452
522
|
*/
|
|
453
|
-
component
|
|
523
|
+
component?: (props: ResourceComponentProps) => ReactNode;
|
|
454
524
|
/**
|
|
455
525
|
* Error boundary component for this module and its child resources.
|
|
456
526
|
* When an error occurs in this module or its resources, this component will render.
|
|
@@ -639,6 +709,56 @@ declare interface FieldMeta {
|
|
|
639
709
|
*/
|
|
640
710
|
declare type FieldType = "text" | "badge" | "money" | "date" | "link" | "address" | "reference";
|
|
641
711
|
|
|
712
|
+
/**
|
|
713
|
+
* Guard function type.
|
|
714
|
+
* Guards are executed in order and stop on the first non-pass result.
|
|
715
|
+
*/
|
|
716
|
+
export declare type Guard = (ctx: GuardContext) => Promise<GuardResult> | GuardResult;
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* Context provided to guard functions
|
|
720
|
+
*/
|
|
721
|
+
export declare type GuardContext = {
|
|
722
|
+
params: Params;
|
|
723
|
+
searchParams: URLSearchParams;
|
|
724
|
+
signal: AbortSignal;
|
|
725
|
+
context: ContextData;
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* Result of guard evaluation.
|
|
730
|
+
* Guards can only return one of these constrained result types.
|
|
731
|
+
*/
|
|
732
|
+
export declare type GuardResult =
|
|
733
|
+
/** Allow access and render the component */
|
|
734
|
+
{
|
|
735
|
+
type: "pass";
|
|
736
|
+
}
|
|
737
|
+
/** Deny access and show 404 */
|
|
738
|
+
| {
|
|
739
|
+
type: "hidden";
|
|
740
|
+
}
|
|
741
|
+
/** Redirect to another path */
|
|
742
|
+
| {
|
|
743
|
+
type: "redirect";
|
|
744
|
+
to: string;
|
|
745
|
+
};
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
* Deny access and show 404 Not Found.
|
|
749
|
+
*
|
|
750
|
+
* @example
|
|
751
|
+
* ```tsx
|
|
752
|
+
* const adminOnly: Guard = ({ context }) => {
|
|
753
|
+
* if (context.currentUser.role !== "admin") {
|
|
754
|
+
* return hidden();
|
|
755
|
+
* }
|
|
756
|
+
* return pass();
|
|
757
|
+
* };
|
|
758
|
+
* ```
|
|
759
|
+
*/
|
|
760
|
+
export declare const hidden: () => GuardResult;
|
|
761
|
+
|
|
642
762
|
export declare type I18nLabels<Def extends Record<string, LabelValue> = Record<string, LabelValue>, L extends string = never> = {
|
|
643
763
|
en: Def;
|
|
644
764
|
} & {
|
|
@@ -658,6 +778,57 @@ declare type LabelDefinition<Def extends Record<string, LabelValue>> = {
|
|
|
658
778
|
*/
|
|
659
779
|
declare type LabelValue = string | ((props: any) => string);
|
|
660
780
|
|
|
781
|
+
/**
|
|
782
|
+
* Layout - Responsive column layout component
|
|
783
|
+
*
|
|
784
|
+
* Automatically handles responsive behavior for 1, 2, or 3 column layouts.
|
|
785
|
+
* Uses flexbox with viewport breakpoints for simple, CSS-only responsive behavior.
|
|
786
|
+
*
|
|
787
|
+
* @example
|
|
788
|
+
* ```tsx
|
|
789
|
+
* // Basic layout
|
|
790
|
+
* <Layout columns={2}>
|
|
791
|
+
* <Layout.Column>Main content</Layout.Column>
|
|
792
|
+
* <Layout.Column>Side panel</Layout.Column>
|
|
793
|
+
* </Layout>
|
|
794
|
+
*
|
|
795
|
+
* // With header and actions
|
|
796
|
+
* <Layout columns={2} title="Page Title" actions={[<Button key="save">Save</Button>]}>
|
|
797
|
+
* <Layout.Column>...</Layout.Column>
|
|
798
|
+
* <Layout.Column>...</Layout.Column>
|
|
799
|
+
* </Layout>
|
|
800
|
+
* ```
|
|
801
|
+
*/
|
|
802
|
+
export declare function Layout({ columns, className, gap, title, actions, children, }: LayoutProps): JSX.Element;
|
|
803
|
+
|
|
804
|
+
export declare namespace Layout {
|
|
805
|
+
var Column: React_2.ForwardRefExoticComponent<ColumnProps & React_2.RefAttributes<HTMLDivElement>>;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Props for the Layout component
|
|
810
|
+
*/
|
|
811
|
+
export declare interface LayoutProps {
|
|
812
|
+
/**
|
|
813
|
+
* Number of columns (1, 2, or 3).
|
|
814
|
+
*
|
|
815
|
+
* **Required.** Must match the exact number of `Layout.Column` children.
|
|
816
|
+
* The component will throw an error in development if there's a mismatch.
|
|
817
|
+
*/
|
|
818
|
+
columns: ColumnCount;
|
|
819
|
+
/** Additional CSS classes */
|
|
820
|
+
className?: string;
|
|
821
|
+
/** Gap between columns (default: 4 = 16px) */
|
|
822
|
+
gap?: number;
|
|
823
|
+
/** Header title - displayed at the top of the layout */
|
|
824
|
+
title?: string;
|
|
825
|
+
/** Header actions - array of action components (e.g., buttons) displayed on the right side of the header.
|
|
826
|
+
* Layout and spacing are handled automatically. */
|
|
827
|
+
actions?: ReactNode[];
|
|
828
|
+
/** Child elements - must be exactly `columns` number of Layout.Column components */
|
|
829
|
+
children: ReactNode;
|
|
830
|
+
}
|
|
831
|
+
|
|
661
832
|
export { Link }
|
|
662
833
|
|
|
663
834
|
declare type LoaderHandler = (args: LoaderFunctionArgs) => Promise<unknown> | unknown;
|
|
@@ -669,18 +840,34 @@ declare type LocalizedString = string | ((locale: string) => string);
|
|
|
669
840
|
*/
|
|
670
841
|
declare type Module = Omit<CommonPageResource, "meta"> & {
|
|
671
842
|
_type: "module";
|
|
843
|
+
component?: () => ReactNode;
|
|
672
844
|
meta: CommonPageResource["meta"] & {
|
|
673
845
|
icon?: ReactNode;
|
|
674
846
|
menuItemClickable: boolean;
|
|
675
847
|
};
|
|
676
848
|
resources: Array<Resource>;
|
|
677
849
|
errorBoundary: ErrorBoundaryComponent;
|
|
678
|
-
|
|
850
|
+
guards?: Guard[];
|
|
679
851
|
loader?: LoaderHandler;
|
|
680
852
|
};
|
|
681
853
|
|
|
682
854
|
declare type Modules = Array<Module>;
|
|
683
855
|
|
|
856
|
+
/**
|
|
857
|
+
* Allow access to the route. Continue to next guard or render component.
|
|
858
|
+
*
|
|
859
|
+
* @example
|
|
860
|
+
* ```tsx
|
|
861
|
+
* const myGuard: Guard = ({ context }) => {
|
|
862
|
+
* if (context.currentUser) {
|
|
863
|
+
* return pass();
|
|
864
|
+
* }
|
|
865
|
+
* return hidden();
|
|
866
|
+
* };
|
|
867
|
+
* ```
|
|
868
|
+
*/
|
|
869
|
+
export declare const pass: () => GuardResult;
|
|
870
|
+
|
|
684
871
|
declare type ReactResourceProps = {
|
|
685
872
|
/**
|
|
686
873
|
* React component to render.
|
|
@@ -689,30 +876,21 @@ declare type ReactResourceProps = {
|
|
|
689
876
|
};
|
|
690
877
|
|
|
691
878
|
/**
|
|
692
|
-
* Redirect
|
|
693
|
-
*/
|
|
694
|
-
declare type RedirectConfig = {
|
|
695
|
-
/**
|
|
696
|
-
* Path to redirect to (under /resources/)
|
|
697
|
-
*/
|
|
698
|
-
redirectTo: string;
|
|
699
|
-
};
|
|
700
|
-
|
|
701
|
-
/**
|
|
702
|
-
* Helper function to define a redirect to a resource path
|
|
879
|
+
* Redirect to another path.
|
|
703
880
|
*
|
|
704
|
-
* @param
|
|
881
|
+
* @param to - Path to redirect to
|
|
705
882
|
*
|
|
706
883
|
* @example
|
|
707
884
|
* ```tsx
|
|
708
|
-
*
|
|
709
|
-
*
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
*
|
|
885
|
+
* const requireAuth: Guard = ({ context }) => {
|
|
886
|
+
* if (!context.currentUser) {
|
|
887
|
+
* return redirectTo("/login");
|
|
888
|
+
* }
|
|
889
|
+
* return pass();
|
|
890
|
+
* };
|
|
713
891
|
* ```
|
|
714
892
|
*/
|
|
715
|
-
export declare
|
|
893
|
+
export declare const redirectTo: (to: string) => GuardResult;
|
|
716
894
|
|
|
717
895
|
/**
|
|
718
896
|
* A resource that can be included in the sub-content in the root resource.
|
|
@@ -721,9 +899,10 @@ export declare function redirectToResource(path: string): RedirectConfig;
|
|
|
721
899
|
*/
|
|
722
900
|
declare type Resource = CommonPageResource & {
|
|
723
901
|
_type: "resource";
|
|
902
|
+
component: () => ReactNode;
|
|
724
903
|
subResources?: Array<Resource>;
|
|
725
904
|
errorBoundary: ErrorBoundaryComponent;
|
|
726
|
-
|
|
905
|
+
guards?: Guard[];
|
|
727
906
|
loader?: LoaderHandler;
|
|
728
907
|
};
|
|
729
908
|
|
|
@@ -772,7 +951,29 @@ declare type ThemeProviderState = {
|
|
|
772
951
|
setTheme: (theme: Theme) => void;
|
|
773
952
|
};
|
|
774
953
|
|
|
775
|
-
|
|
954
|
+
/**
|
|
955
|
+
* Hook to access the full AppShell context (both config and data).
|
|
956
|
+
* For better performance, prefer useAppShellConfig() or useAppShellData()
|
|
957
|
+
* depending on what you need, as this hook subscribes to both contexts.
|
|
958
|
+
*/
|
|
959
|
+
export declare const useAppShell: () => {
|
|
960
|
+
contextData: ContextData;
|
|
961
|
+
title?: string;
|
|
962
|
+
icon?: ReactNode;
|
|
963
|
+
configurations: RootConfiguration;
|
|
964
|
+
};
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* Hook to access only the static configuration.
|
|
968
|
+
* Use this in components that don't need contextData to avoid unnecessary re-renders.
|
|
969
|
+
*/
|
|
970
|
+
export declare const useAppShellConfig: () => AppShellConfigContextType;
|
|
971
|
+
|
|
972
|
+
/**
|
|
973
|
+
* Hook to access only the dynamic contextData.
|
|
974
|
+
* Use this in components that need contextData.
|
|
975
|
+
*/
|
|
976
|
+
export declare const useAppShellData: () => AppShellDataContextType;
|
|
776
977
|
|
|
777
978
|
export declare const useAuth: () => AuthContextType;
|
|
778
979
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailor-platform/app-shell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./styles": "./dist/app-shell.css",
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
"react-dom": ">= 19"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@badgateway/oauth2-client": "^3.3.0",
|
|
22
21
|
"@radix-ui/react-checkbox": "^1.3.3",
|
|
23
22
|
"@radix-ui/react-collapsible": "^1.1.12",
|
|
24
23
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
@@ -26,7 +25,6 @@
|
|
|
26
25
|
"@radix-ui/react-label": "^2.1.8",
|
|
27
26
|
"@radix-ui/react-navigation-menu": "^1.2.14",
|
|
28
27
|
"@radix-ui/react-popover": "^1.1.15",
|
|
29
|
-
"@radix-ui/react-select": "^2.1.6",
|
|
30
28
|
"@radix-ui/react-separator": "^1.1.8",
|
|
31
29
|
"@radix-ui/react-slot": "^1.2.4",
|
|
32
30
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
@@ -40,8 +38,8 @@
|
|
|
40
38
|
"lucide-react": "^0.562.0",
|
|
41
39
|
"next-themes": "^0.4.6",
|
|
42
40
|
"oauth4webapi": "^3.8.3",
|
|
43
|
-
"react": "^19.2.
|
|
44
|
-
"react-dom": "^19.2.
|
|
41
|
+
"react": "^19.2.4",
|
|
42
|
+
"react-dom": "^19.2.4",
|
|
45
43
|
"react-hook-form": "^7.54.2",
|
|
46
44
|
"react-router": "^7.4.0",
|
|
47
45
|
"sonner": "^2.0.7",
|
|
@@ -61,7 +59,7 @@
|
|
|
61
59
|
"tailwindcss": "^4.1.3",
|
|
62
60
|
"tw-animate-css": "^1.4.0",
|
|
63
61
|
"typescript": "^5",
|
|
64
|
-
"vite": "^7.3.
|
|
62
|
+
"vite": "^7.3.1",
|
|
65
63
|
"vite-plugin-dts": "^4.5.0",
|
|
66
64
|
"vite-plugin-externalize-deps": "^0.10.0",
|
|
67
65
|
"vite-tsconfig-paths": "^6.0.4",
|