@oussemasahbeni/keycloakify-login-shadcn 250004.0.2 → 250004.0.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/keycloak-theme/components/ui/alert.tsx +4 -4
- package/keycloak-theme/components/ui/dropdown-menu.tsx +5 -5
- package/keycloak-theme/components/ui/input.tsx +1 -1
- package/keycloak-theme/components/ui/select.tsx +4 -4
- package/keycloak-theme/components/ui/separator.tsx +1 -1
- package/keycloak-theme/login/KcContext.ts +4 -0
- package/keycloak-theme/login/KcPage.tsx +3 -16
- package/keycloak-theme/login/components/Template/Template.tsx +13 -12
- package/keycloak-theme/login/i18n.ts +0 -4
- package/keycloak-theme/login/mocks/getKcContextMock.ts +5 -1
- package/keycloak-theme/login/pages/code/Page.stories.tsx +11 -15
- package/keycloak-theme/login/shared/getColorScheme.ts +45 -0
- package/keycloak-theme/login/styleLevelCustomization.tsx +21 -2
- package/package.json +2 -5
|
@@ -38,13 +38,13 @@ const Alert = React.forwardRef<
|
|
|
38
38
|
<div className="flex items-start gap-3">
|
|
39
39
|
{showIcon && (
|
|
40
40
|
<>
|
|
41
|
-
{variant === "info" && <Info className="h-5 w-5
|
|
42
|
-
{variant === "error" && <XCircle className="h-5 w-5
|
|
41
|
+
{variant === "info" && <Info className="h-5 w-5 shrink-0" />}
|
|
42
|
+
{variant === "error" && <XCircle className="h-5 w-5 shrink-0" />}
|
|
43
43
|
{variant === "warning" && (
|
|
44
|
-
<AlertTriangle className="h-5 w-5
|
|
44
|
+
<AlertTriangle className="h-5 w-5 shrink-0" />
|
|
45
45
|
)}
|
|
46
46
|
{variant === "success" && (
|
|
47
|
-
<MdCheckCircle className="h-5 w-5
|
|
47
|
+
<MdCheckCircle className="h-5 w-5 shrink-0" />
|
|
48
48
|
)}
|
|
49
49
|
</>
|
|
50
50
|
)}
|
|
@@ -44,7 +44,7 @@ const DropdownMenuSubContent = React.forwardRef<
|
|
|
44
44
|
<DropdownMenuPrimitive.SubContent
|
|
45
45
|
ref={ref}
|
|
46
46
|
className={cn(
|
|
47
|
-
"z-50 min-w-
|
|
47
|
+
"z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin]",
|
|
48
48
|
className
|
|
49
49
|
)}
|
|
50
50
|
{...props}
|
|
@@ -61,7 +61,7 @@ const DropdownMenuContent = React.forwardRef<
|
|
|
61
61
|
ref={ref}
|
|
62
62
|
sideOffset={sideOffset}
|
|
63
63
|
className={cn(
|
|
64
|
-
"z-50 max-h-
|
|
64
|
+
"z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-32 overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
|
|
65
65
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin]",
|
|
66
66
|
className
|
|
67
67
|
)}
|
|
@@ -80,7 +80,7 @@ const DropdownMenuItem = React.forwardRef<
|
|
|
80
80
|
<DropdownMenuPrimitive.Item
|
|
81
81
|
ref={ref}
|
|
82
82
|
className={cn(
|
|
83
|
-
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-
|
|
83
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
|
|
84
84
|
inset && "pl-8",
|
|
85
85
|
className
|
|
86
86
|
)}
|
|
@@ -96,7 +96,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
|
|
96
96
|
<DropdownMenuPrimitive.CheckboxItem
|
|
97
97
|
ref={ref}
|
|
98
98
|
className={cn(
|
|
99
|
-
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-
|
|
99
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
|
100
100
|
className
|
|
101
101
|
)}
|
|
102
102
|
checked={checked}
|
|
@@ -119,7 +119,7 @@ const DropdownMenuRadioItem = React.forwardRef<
|
|
|
119
119
|
<DropdownMenuPrimitive.RadioItem
|
|
120
120
|
ref={ref}
|
|
121
121
|
className={cn(
|
|
122
|
-
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-
|
|
122
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
|
123
123
|
className
|
|
124
124
|
)}
|
|
125
125
|
{...props}
|
|
@@ -9,7 +9,7 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
|
|
|
9
9
|
type={type}
|
|
10
10
|
className={cn(
|
|
11
11
|
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
12
|
-
"group-
|
|
12
|
+
"group-data-[invalid=true]/field:border-destructive group-data-[invalid=true]/field:focus-visible:ring-destructive",
|
|
13
13
|
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
14
14
|
className
|
|
15
15
|
)}
|
|
@@ -17,7 +17,7 @@ const SelectTrigger = React.forwardRef<
|
|
|
17
17
|
<SelectPrimitive.Trigger
|
|
18
18
|
ref={ref}
|
|
19
19
|
className={cn(
|
|
20
|
-
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background data-
|
|
20
|
+
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background data-placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
|
|
21
21
|
className
|
|
22
22
|
)}
|
|
23
23
|
{...props}
|
|
@@ -66,7 +66,7 @@ const SelectContent = React.forwardRef<
|
|
|
66
66
|
<SelectPrimitive.Content
|
|
67
67
|
ref={ref}
|
|
68
68
|
className={cn(
|
|
69
|
-
"relative z-50 max-h-[--radix-select-content-available-height] min-w-
|
|
69
|
+
"relative z-50 max-h-[--radix-select-content-available-height] min-w-32 overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-select-content-transform-origin]",
|
|
70
70
|
position === "popper" &&
|
|
71
71
|
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
72
72
|
className
|
|
@@ -79,7 +79,7 @@ const SelectContent = React.forwardRef<
|
|
|
79
79
|
className={cn(
|
|
80
80
|
"p-1",
|
|
81
81
|
position === "popper" &&
|
|
82
|
-
"h-
|
|
82
|
+
"h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width)"
|
|
83
83
|
)}
|
|
84
84
|
>
|
|
85
85
|
{children}
|
|
@@ -109,7 +109,7 @@ const SelectItem = React.forwardRef<
|
|
|
109
109
|
<SelectPrimitive.Item
|
|
110
110
|
ref={ref}
|
|
111
111
|
className={cn(
|
|
112
|
-
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-
|
|
112
|
+
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
|
113
113
|
className
|
|
114
114
|
)}
|
|
115
115
|
{...props}
|
|
@@ -15,7 +15,7 @@ const Separator = React.forwardRef<
|
|
|
15
15
|
orientation={orientation}
|
|
16
16
|
className={cn(
|
|
17
17
|
"shrink-0 bg-border",
|
|
18
|
-
orientation === "horizontal" ? "h-
|
|
18
|
+
orientation === "horizontal" ? "h-px w-full" : "h-full w-px",
|
|
19
19
|
className
|
|
20
20
|
)}
|
|
21
21
|
{...props}
|
|
@@ -9,6 +9,10 @@ export type KcContextExtension = {
|
|
|
9
9
|
properties: Record<KcEnvName, string> & {};
|
|
10
10
|
// NOTE: Here you can declare more properties to extend the KcContext
|
|
11
11
|
// See: https://docs.keycloakify.dev/faq-and-help/some-values-you-need-are-missing-from-in-kccontext
|
|
12
|
+
client: {
|
|
13
|
+
baseUrl?: string;
|
|
14
|
+
};
|
|
15
|
+
darkMode?: boolean;
|
|
12
16
|
};
|
|
13
17
|
|
|
14
18
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ThemeProvider } from '@/components/theme-provider';
|
|
2
1
|
import { useExclusiveAppInstanceEffect } from "@keycloakify/login-ui/tools/useExclusiveAppInstanceEffect";
|
|
3
2
|
import { KcClsxProvider } from "@keycloakify/login-ui/useKcClsx";
|
|
4
3
|
import type { ReactNode } from "react";
|
|
@@ -10,28 +9,16 @@ import { PageIndex } from "./pages/PageIndex";
|
|
|
10
9
|
import { useStyleLevelCustomization } from "./styleLevelCustomization";
|
|
11
10
|
|
|
12
11
|
|
|
12
|
+
|
|
13
|
+
|
|
13
14
|
export default function KcPage(props: { kcContext: KcContext }) {
|
|
14
15
|
const { kcContext } = props;
|
|
15
16
|
|
|
16
|
-
const defaultTheme = (): "light" | "dark" | "system" => {
|
|
17
|
-
if (kcContext.properties.ENABLE_THEME_TOGGLE !== "true") {
|
|
18
|
-
// If theme toggle is disabled, use the default os theme setting
|
|
19
|
-
return window.matchMedia &&
|
|
20
|
-
window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
21
|
-
? "dark"
|
|
22
|
-
: "light";
|
|
23
|
-
}
|
|
24
|
-
return "system";
|
|
25
|
-
};
|
|
26
|
-
|
|
27
17
|
return (
|
|
28
18
|
<KcContextProvider kcContext={kcContext}>
|
|
29
19
|
<I18nProvider kcContext={kcContext}>
|
|
30
20
|
<StyleLevelCustomization>
|
|
31
|
-
<
|
|
32
|
-
<PageIndex />
|
|
33
|
-
</ThemeProvider>
|
|
34
|
-
|
|
21
|
+
<PageIndex />
|
|
35
22
|
</StyleLevelCustomization>
|
|
36
23
|
</I18nProvider>
|
|
37
24
|
</KcContextProvider>
|
|
@@ -3,6 +3,7 @@ import { ModeToggle } from '@/components/theme-toggle';
|
|
|
3
3
|
import { Alert, AlertDescription } from '@/components/ui/alert';
|
|
4
4
|
import { Button } from '@/components/ui/button';
|
|
5
5
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
6
|
+
import { redirectUrlOrigin } from '@/login/shared/redirectUrlOrigin';
|
|
6
7
|
import { kcSanitize } from "@keycloakify/login-ui/kcSanitize";
|
|
7
8
|
import { useKcClsx } from "@keycloakify/login-ui/useKcClsx";
|
|
8
9
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@radix-ui/react-tooltip';
|
|
@@ -10,6 +11,7 @@ import { useSetClassName } from "keycloakify/tools/useSetClassName";
|
|
|
10
11
|
import { RotateCcw } from 'lucide-react';
|
|
11
12
|
import type { ReactNode } from "react";
|
|
12
13
|
import { useEffect } from "react";
|
|
14
|
+
import { FiHome } from 'react-icons/fi';
|
|
13
15
|
import { useI18n } from "../../i18n";
|
|
14
16
|
import { useKcContext } from "../../KcContext";
|
|
15
17
|
import companylogo from "./../../assets/img/auth-logo.svg";
|
|
@@ -77,20 +79,19 @@ export function Template(props: {
|
|
|
77
79
|
<div className="flex flex-col gap-4 px-0 py-0 pb-6 lg:p-6 lg:md:p-10 lg:pt-10 min-h-screen lg:min-h-0">
|
|
78
80
|
{/* navigation */}
|
|
79
81
|
<div className="absolute top-4 right-4 lg:left-4 z-20 flex gap-2">
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
<Button variant="outline" size="icon" >
|
|
83
|
+
<a href={kcContext.client.baseUrl ?? redirectUrlOrigin}>
|
|
84
|
+
<FiHome />
|
|
85
|
+
</a>
|
|
86
|
+
</Button>
|
|
87
|
+
|
|
85
88
|
{enabledLanguages.length > 1 && (
|
|
86
|
-
<
|
|
87
|
-
<Languages />
|
|
88
|
-
</div>
|
|
89
|
+
<Languages />
|
|
89
90
|
)}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
{kcContext.darkMode !== false && (
|
|
94
|
+
<ModeToggle />
|
|
94
95
|
)}
|
|
95
96
|
</div>
|
|
96
97
|
|
|
@@ -14,7 +14,6 @@ const { I18nProvider, useI18n } = i18nBuilder
|
|
|
14
14
|
enterCredentials: "Enter your credentials below to login",
|
|
15
15
|
noAccount: "Don't have an account?",
|
|
16
16
|
doRegister: "Sign up",
|
|
17
|
-
home: "Home",
|
|
18
17
|
"organization.selectTitle": "Choose Your Organization",
|
|
19
18
|
"organization.pickPlaceholder": "Pick an organization to continue"
|
|
20
19
|
},
|
|
@@ -26,8 +25,6 @@ const { I18nProvider, useI18n } = i18nBuilder
|
|
|
26
25
|
enterCredentials: "أدخل بيانات الاعتماد الخاصة بك أدناه لتسجيل الدخول",
|
|
27
26
|
doRegister: "إنشاء حساب",
|
|
28
27
|
noAccount: "ليس لديك حساب؟",
|
|
29
|
-
home: "الصفحة الرئيسية",
|
|
30
|
-
|
|
31
28
|
"organization.selectTitle": "اختر مؤسستك",
|
|
32
29
|
"organization.pickPlaceholder": "اختر مؤسسة للمتابعة"
|
|
33
30
|
},
|
|
@@ -41,7 +38,6 @@ const { I18nProvider, useI18n } = i18nBuilder
|
|
|
41
38
|
"Entrez vos informations d'identification ci-dessous pour vous connecter",
|
|
42
39
|
doRegister: "S'inscrire",
|
|
43
40
|
noAccount: "Vous n'avez pas de compte?",
|
|
44
|
-
home: "Accueil",
|
|
45
41
|
"organization.selectTitle": "Choisissez Votre Organisation",
|
|
46
42
|
"organization.pickPlaceholder": "Sélectionnez une organisation pour continuer"
|
|
47
43
|
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { createGetKcContextMock } from "@keycloakify/login-ui/KcContext/getKcContextMock";
|
|
2
|
+
import { kcEnvDefaults, themeNames } from "../../kc.gen";
|
|
2
3
|
import type { KcContextExtension, KcContextExtensionPerPage } from "../KcContext";
|
|
3
|
-
import { themeNames, kcEnvDefaults } from "../../kc.gen";
|
|
4
4
|
|
|
5
5
|
const kcContextExtension: KcContextExtension = {
|
|
6
6
|
themeName: themeNames[0],
|
|
7
|
+
client: {
|
|
8
|
+
baseUrl: "https://my-theme.keycloakify.dev"
|
|
9
|
+
},
|
|
10
|
+
darkMode: true,
|
|
7
11
|
properties: {
|
|
8
12
|
...kcEnvDefaults
|
|
9
13
|
}
|
|
@@ -15,30 +15,26 @@ export const Default: Story = {
|
|
|
15
15
|
render: () => <KcPageStory />
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
export const WithDarkModeDisabled: Story = {
|
|
19
|
-
render: () => (
|
|
20
|
-
<KcPageStory
|
|
21
|
-
kcContext={{
|
|
22
|
-
properties: {
|
|
23
|
-
ENABLE_THEME_TOGGLE: "false"
|
|
24
|
-
}
|
|
25
|
-
}}
|
|
26
|
-
/>
|
|
27
|
-
)
|
|
28
|
-
};
|
|
29
18
|
|
|
30
|
-
|
|
19
|
+
/**
|
|
20
|
+
* This reflects the state when "Dark Theme" is set to "Disabled" in the realm settings
|
|
21
|
+
* (Theme configuration tab of the Keycloak Admin UI).
|
|
22
|
+
*
|
|
23
|
+
* You should enable this configuration if you want to hide the "dark mode switch"
|
|
24
|
+
* and ensure that the theme always renders in light mode, even if the user's system
|
|
25
|
+
* preference is set to dark.
|
|
26
|
+
*/
|
|
27
|
+
export const WithDarkModeForbidden: Story = {
|
|
31
28
|
render: () => (
|
|
32
29
|
<KcPageStory
|
|
33
30
|
kcContext={{
|
|
34
|
-
|
|
35
|
-
ENABLE_THEME_TOGGLE: "true"
|
|
36
|
-
}
|
|
31
|
+
darkMode: false
|
|
37
32
|
}}
|
|
38
33
|
/>
|
|
39
34
|
)
|
|
40
35
|
};
|
|
41
36
|
|
|
37
|
+
|
|
42
38
|
export const WithErrorCode: Story = {
|
|
43
39
|
render: () => (
|
|
44
40
|
<KcPageStory
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const SESSION_STORAGE_KEY = "kc-color-scheme";
|
|
2
|
+
|
|
3
|
+
export function getTheme(
|
|
4
|
+
kcContextDarkMode: boolean | undefined
|
|
5
|
+
): "dark" | "light" | "system" {
|
|
6
|
+
from_admin_policy: {
|
|
7
|
+
if (kcContextDarkMode === undefined || kcContextDarkMode === true) {
|
|
8
|
+
break from_admin_policy;
|
|
9
|
+
}
|
|
10
|
+
return "light";
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
from_url: {
|
|
14
|
+
const url = new URL(window.location.href);
|
|
15
|
+
|
|
16
|
+
const value = url.searchParams.get("dark");
|
|
17
|
+
|
|
18
|
+
if (value === null) {
|
|
19
|
+
break from_url;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
{
|
|
23
|
+
url.searchParams.delete("dark");
|
|
24
|
+
window.history.replaceState({}, "", url.toString());
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const isDark = value === "true";
|
|
28
|
+
|
|
29
|
+
sessionStorage.setItem(SESSION_STORAGE_KEY, `${isDark}`);
|
|
30
|
+
|
|
31
|
+
return isDark ? "dark" : "light";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
from_session_storage: {
|
|
35
|
+
const value = sessionStorage.getItem(SESSION_STORAGE_KEY);
|
|
36
|
+
|
|
37
|
+
if (value === null) {
|
|
38
|
+
break from_session_storage;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return value === "true" ? "dark" : "light";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return "system";
|
|
45
|
+
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { ThemeProvider } from '@/components/theme-provider';
|
|
1
2
|
import type { ClassKey } from "@keycloakify/login-ui/useKcClsx";
|
|
2
3
|
import type { ReactNode } from "react";
|
|
4
|
+
import { useKcContext } from './KcContext';
|
|
5
|
+
import { getTheme } from './shared/getColorScheme';
|
|
3
6
|
|
|
4
7
|
type Classes = { [key in ClassKey]?: string };
|
|
5
8
|
|
|
@@ -10,8 +13,24 @@ type StyleLevelCustomization = {
|
|
|
10
13
|
Provider?: (props: { children: ReactNode }) => ReactNode;
|
|
11
14
|
};
|
|
12
15
|
|
|
16
|
+
// eslint-disable-next-line react-refresh/only-export-components
|
|
17
|
+
function Provider(props: { children: ReactNode }) {
|
|
18
|
+
const { children } = props;
|
|
19
|
+
|
|
20
|
+
const { kcContext } = useKcContext();
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<ThemeProvider defaultTheme={getTheme(kcContext.darkMode)}>
|
|
25
|
+
{children}
|
|
26
|
+
</ThemeProvider>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
13
31
|
export function useStyleLevelCustomization(): StyleLevelCustomization {
|
|
14
32
|
return {
|
|
15
|
-
doUseDefaultCss: false
|
|
33
|
+
doUseDefaultCss: false,
|
|
34
|
+
Provider
|
|
16
35
|
};
|
|
17
|
-
}
|
|
36
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oussemasahbeni/keycloakify-login-shadcn",
|
|
3
|
-
"version": "250004.0.
|
|
3
|
+
"version": "250004.0.3",
|
|
4
4
|
"description": "Keycloakify Shadcn Theme extensions",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -8,9 +8,6 @@
|
|
|
8
8
|
"files": [
|
|
9
9
|
"keycloak-theme"
|
|
10
10
|
],
|
|
11
|
-
"dependencies": {
|
|
12
|
-
"@keycloakify/login-ui": "~250004.6.5"
|
|
13
|
-
},
|
|
14
11
|
"peerDependencies": {
|
|
15
12
|
"@radix-ui/react-checkbox": "^1.3.3",
|
|
16
13
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
@@ -22,12 +19,12 @@
|
|
|
22
19
|
"@radix-ui/react-separator": "^1.1.8",
|
|
23
20
|
"@radix-ui/react-slot": "^1.2.4",
|
|
24
21
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
25
|
-
"@tailwindcss/postcss": "^4.1.18",
|
|
26
22
|
"@tailwindcss/vite": "^4.1.18",
|
|
27
23
|
"class-variance-authority": "^0.7.1",
|
|
28
24
|
"clsx": "^2.1.1",
|
|
29
25
|
"cmdk": "^1.1.1",
|
|
30
26
|
"input-otp": "^1.4.2",
|
|
27
|
+
"@keycloakify/login-ui": "~250004.6.5",
|
|
31
28
|
"lucide-react": "^0.473.0",
|
|
32
29
|
"react-icons": "^5.5.0",
|
|
33
30
|
"tailwind-merge": "^2.6.0",
|