Compare commits

...

10 Commits

6 changed files with 75 additions and 58 deletions

View File

@ -1,3 +1,15 @@
### **0.3.3** (2021-03-22)
- Fix submit not receving correct text
### **0.3.2** (2021-03-21)
- Fix broken previous release
### **0.3.1** (2021-03-21)
- kcHeaderClass can be updated after initial mount
## **0.3.0** (2021-03-20) ## **0.3.0** (2021-03-20)
- Bump version - Bump version

View File

@ -45,12 +45,11 @@ Tested with the following Keycloak versions:
- [Just changing the look](#just-changing-the-look) - [Just changing the look](#just-changing-the-look)
- [Changing the look **and** feel](#changing-the-look-and-feel) - [Changing the look **and** feel](#changing-the-look-and-feel)
- [Hot reload](#hot-reload) - [Hot reload](#hot-reload)
- [Implement context persistance (optional)](#implement-context-persistance-optional)
- [GitHub Actions](#github-actions) - [GitHub Actions](#github-actions)
- [REQUIREMENTS](#requirements) - [REQUIREMENTS](#requirements)
- [API Reference](#api-reference) - [API Reference](#api-reference)
- [The build tool](#the-build-tool) - [The build tool](#the-build-tool)
- [The fronted lib ( imported into your react app )](#the-fronted-lib--imported-into-your-react-app-) - [Implement context persistance (optional)](#implement-context-persistance-optional)
# How to use # How to use
## Setting up the build tool ## Setting up the build tool
@ -152,6 +151,37 @@ Checkout [this concrete example](https://github.com/garronej/keycloakify-demo-ap
*NOTE: keycloak-react-theming was renamed keycloakify since this video was recorded* *NOTE: keycloak-react-theming was renamed keycloakify since this video was recorded*
[![kickstart_video](https://user-images.githubusercontent.com/6702424/108877866-f146ee80-75ff-11eb-8120-003b3c5f6dd8.png)](https://youtu.be/xTz0Rj7i2v8) [![kickstart_video](https://user-images.githubusercontent.com/6702424/108877866-f146ee80-75ff-11eb-8120-003b3c5f6dd8.png)](https://youtu.be/xTz0Rj7i2v8)
# GitHub Actions
![image](https://user-images.githubusercontent.com/6702424/110708305-c44b2c00-81fa-11eb-8152-eeaaac0883d6.png)
[Here is a demo repo](https://github.com/garronej/keycloakify-demo-app) to show how to automate
the building and publishing of the theme (the .jar file).
# REQUIREMENTS
This tools assumes you are bundling your app with Webpack (tested with 4.44.2) .
It assumes there is a `build/` directory at the root of your react project directory containing a `index.html` file
and a `static/` directory generated by webpack.
**All this is defaults with [`create-react-app`](https://create-react-app.dev)** (tested with 4.0.3=)
- For building the theme: `mvn` (Maven) must be installed
- For development, (testing the theme in a local container ): `rm`, `mkdir`, `wget`, `unzip` are assumed to be available
and `docker` up and running.
NOTE: This build tool has only be tested on MacOS.
# API Reference
## The build tool
Part of the lib that runs with node, at build time.
- `npx build-keycloak-theme`: Builds the theme, the CWD is assumed to be the root of your react project.
- `npx download-sample-keycloak-themes`: Downloads the keycloak default themes (for development purposes)
# Implement context persistance (optional) # Implement context persistance (optional)
If, before logging in, a user has selected a specific language If, before logging in, a user has selected a specific language
@ -210,40 +240,3 @@ keycloakInstance.init({
If you really want to go the extra miles and avoid having the white If you really want to go the extra miles and avoid having the white
flash of the blank html before the js bundle have been evaluated flash of the blank html before the js bundle have been evaluated
[here is a snippet](https://github.com/InseeFrLab/onyxia-ui/blob/a77eb502870cfe6878edd0d956c646d28746d053/public/index.html#L5-L54) that you can place in your `public/index.html` if you are using `powerhooks/useGlobalState`. [here is a snippet](https://github.com/InseeFrLab/onyxia-ui/blob/a77eb502870cfe6878edd0d956c646d28746d053/public/index.html#L5-L54) that you can place in your `public/index.html` if you are using `powerhooks/useGlobalState`.
# GitHub Actions
![image](https://user-images.githubusercontent.com/6702424/110708305-c44b2c00-81fa-11eb-8152-eeaaac0883d6.png)
[Here is a demo repo](https://github.com/garronej/keycloakify-demo-app) to show how to automate
the building and publishing of the theme (the .jar file).
# REQUIREMENTS
This tools assumes you are bundling your app with Webpack (tested with 4.44.2) .
It assumes there is a `build/` directory at the root of your react project directory containing a `index.html` file
and a `static/` directory generated by webpack.
**All this is defaults with [`create-react-app`](https://create-react-app.dev)** (tested with 4.0.3=)
- For building the theme: `mvn` (Maven) must be installed
- For development, (testing the theme in a local container ): `rm`, `mkdir`, `wget`, `unzip` are assumed to be available
and `docker` up and running.
NOTE: This build tool has only be tested on MacOS.
# API Reference
## The build tool
Part of the lib that runs with node, at build time.
- `npx build-keycloak-theme`: Builds the theme, the CWD is assumed to be the root of your react project.
- `npx download-sample-keycloak-themes`: Downloads the keycloak default themes (for development purposes)
## The fronted lib ( imported into your react app )
Part of the lib that you import in your react project and runs on the browser.
**TODO**

View File

@ -1,6 +1,6 @@
{ {
"name": "keycloakify", "name": "keycloakify",
"version": "0.3.0", "version": "0.3.3",
"description": "Keycloak theme generator for Reacts app", "description": "Keycloak theme generator for Reacts app",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -66,7 +66,7 @@ export const LoginResetPassword = memo(({ kcContext, ...props }: { kcContext: Kc
props.kcButtonBlockClass, props.kcButtonLargeClass props.kcButtonBlockClass, props.kcButtonLargeClass
)} )}
type="submit" type="submit"
defaultValue={msgStr("doSubmit")} value={msgStr("doSubmit")}
/> />
</div> </div>
</div> </div>

View File

@ -113,7 +113,7 @@ export const Register = memo(({ kcContext, ...props }: { kcContext: KcContext.Re
<div id="kc-form-buttons" className={cx(props.kcFormButtonsClass)}> <div id="kc-form-buttons" className={cx(props.kcFormButtonsClass)}>
<input className={cx(props.kcButtonClass, props.kcButtonPrimaryClass, props.kcButtonBlockClass, props.kcButtonLargeClass)} type="submit" <input className={cx(props.kcButtonClass, props.kcButtonPrimaryClass, props.kcButtonBlockClass, props.kcButtonLargeClass)} type="submit"
defaultValue={msgStr("doRegister")} /> value={msgStr("doRegister")} />
</div> </div>
</div> </div>
</form > </form >

View File

@ -25,8 +25,7 @@ export type TemplateProps = {
showUsernameNode?: ReactNode; showUsernameNode?: ReactNode;
formNode: ReactNode; formNode: ReactNode;
infoNode?: ReactNode; infoNode?: ReactNode;
} & { kcContext: KcContext.Template; } & KcTemplateProps; } & { kcContext: KcContext.Template; } & KcTemplateProps;
export const Template = memo((props: TemplateProps) => { export const Template = memo((props: TemplateProps) => {
@ -60,34 +59,35 @@ export const Template = memo((props: TemplateProps) => {
); );
const { const {
realm, locale, auth, realm, locale, auth,
url, message, isAppInitiatedAction url, message, isAppInitiatedAction
}= kcContext; } = kcContext;
useEffect(()=>{ useEffect(() => {
if( !realm.internationalizationEnabled ){ if (!realm.internationalizationEnabled) {
return; return;
} }
assert( locale !== undefined ); assert(locale !== undefined);
if( kcLanguageTag === getBestMatchAmongKcLanguageTag(locale.current) ){ if (kcLanguageTag === getBestMatchAmongKcLanguageTag(locale.current)) {
return; return;
} }
window.location.href = window.location.href =
locale.supported.find(({ languageTag }) => languageTag === kcLanguageTag)!.url; locale.supported.find(({ languageTag }) => languageTag === kcLanguageTag)!.url;
},[kcLanguageTag]); }, [kcLanguageTag]);
const [isExtraCssLoaded, setExtraCssLoaded] = useReducer(() => true, false); const [isExtraCssLoaded, setExtraCssLoaded] = useReducer(() => true, false);
useEffect(() => { useEffect(() => {
let isUnmounted = false; let isUnmounted = false;
const cleanups: (() => void)[] = [];
const toArr = (x: string | readonly string[] | undefined) => const toArr = (x: string | readonly string[] | undefined) =>
typeof x === "string" ? x.split(" ") : x ?? []; typeof x === "string" ? x.split(" ") : x ?? [];
Promise.all( Promise.all(
@ -116,15 +116,27 @@ export const Template = memo((props: TemplateProps) => {
if (props.kcHtmlClass !== undefined) { if (props.kcHtmlClass !== undefined) {
document.getElementsByTagName("html")[0] const htmlClassList =
.classList document.getElementsByTagName("html")[0]
.add(...cx(props.kcHtmlClass).split(" ")); .classList;
const tokens = cx(props.kcHtmlClass).split(" ")
htmlClassList.add(...tokens);
cleanups.push(() => htmlClassList.remove(...tokens));
} }
return () => { isUnmounted = true; }; return () => {
}, []); isUnmounted = true;
cleanups.forEach(f => f());
};
}, [props.kcHtmlClass]);
if (!isExtraCssLoaded) { if (!isExtraCssLoaded) {
return null; return null;