In this project, we've curated a collection of UI elements, layouts, and interactions to demonstrate best practices in user interface design. Each section focuses on a specific aspect of UI.
In order to mantain this project with the most updated version of LTS's packages:
Run npm outdated
to see a table of packages with the current version, wanted version, and latest version.
To update a specific package, you can use npm update package_name
This will update the package to the 'wanted' version, which is the maximum version that satisfies the versioning range specified in package.json.
In order to Update all packages you can also use the command npx npm-check-updates
that upgrades your package.json dependencies to the latest versions, ignoring specified versions.
- Flexible Authentication Provider: This project include the authentication provider library that supports multiple authentication providers. You can easily support the providers you need.
- Diverse Examples: From simple buttons to complex navigation menus, the project covers a wide range of UI elements commonly found in web and mobile applications.
- Accessible Components: Explore implementations that prioritize accessibility, making your UIs inclusive and usable for everyone.
- Code Snippets: Each example comes with corresponding code snippets, making it easy for developers to integrate these UI patterns into their projects.
- Localization: based on i18next and vscode i18n-ally extension, supports dynamic loading of translation files and auto-detect based on Browser
TODO: this section would provide examples on how to run the template and how to use it
When styling components, we follow these guidelines:
The application supports natively both light and dark mode. The way this works is that chackra save a variable in the localStorage with either 'Light' or 'Dark'. On a deployed environment this do not rapresent any problem but, locally, having multiple chackra projects could mess with this setting and leading to unwanted bheaviour such as having the swith reversed (having light theme when Dark mode is selected). To avoid this ensure to set a custom name to this variable in the index.tsx file:
const colorModeManager = createLocalStorageManager("appName-ColorMode");
and then pass it in the Provider:
<ChakraProvider theme={theme} colorModeManager={colorModeManager}>
For any need of z-Index, we refer to the zIndices guideline of Chackra UI
the only accepted values for any zIndex property across the project would be one of the followings:
const zIndices = {
hide: -1,
auto: "auto",
base: 0,
docked: 10,
dropdown: 1000,
sticky: 1100,
banner: 1200,
overlay: 1300,
modal: 1400,
popover: 1500,
skipLink: 1600,
toast: 1700,
tooltip: 1800,
};
-
Use
em
units for font sizes and other measurements related to text: This makes the design more flexible and accessible, asem
units adjust automatically to the user's default font size. For example, instead offontSize="16px"
, usefontSize="1em"
. -
Use
px
units for margins and padding: These measurements are often not related to text size, so it's okay to usepx
units for them. For example,mx="5px"
.
Remember to test your design at different browser font sizes to make sure it looks good and is easy to read for all users.
Tables are implemented with Tanstack (react tables v8)
In the template there is a component (PaginatedSortableTable) ready for the most common use, completely compatible with standard ARK APIs.
Ex:
<PaginatedSortableTable<T>
columns={columns}
useQueryHook={useGetMoviesQuery}
isDraggable
/>
Props:
type PaginatedSortableTableProps<T> = {
columns: ColumnDef<T>[];
useQueryHook: (args: {
pageIndex: number;
pageSize: number;
sorting: SortingState;
filters: ColumnFiltersState;
}) => any;
isDraggable?: boolean;
disableHeaderFilters?: boolean;
externalFilters?: boolean;
externalFiltersState?: ColumnFiltersState;
};
columns: an Array of ColumnDef that specify the columns with all the props needed (see Tanstack docs)
useQueryHook: The query hook generated by your Redux Toolkit Query API for fetching table data that should return an object like this
data: {
data: retData.data,
count: retData.count,
page: page,
limit: pageSize,
}
isDraggable: Enables column sorting trough drag & drop
disableHeaderFilters: this remove all the column headers filters (if you dont want to specify all false in the columns array
externalFilters: this enable the use of external filters (external means that filters are not in the columns header)
externalFiltersState: ColumnFiltersState object with the state of external filters (this is mandatory if externalFilters is true
The application initializes itself by reading environmental variables and injecting them into the Redux store (env). Additionally, the Authentication provider constructor receives env as a parameter, containing all the necessary configurations. env is an object of type CustomSettingsType defined as it follows:
type CustomSettingsType = {
clientID: string;
domain: string;
scopes: string;
knownAuthorities: string;
signUpSignInPolicyId: string;
serviceUrl: string;
redirectUri: string;
authority: string;
audience: string;
};
This will be used as globals configuration and can be implemented to support more features (ex: subsidiaries).
This project is implemented with a flexible authentication provider that can support multiple providers. Now it support MSAL and AUTH0 providers and you can switch between one another easily. This is how:
- Go to the index.tsx file
- Instantiate the implementation of your choice of AuthProvider interface
const authProvider = new Auth0AuthProvider(env);
in this case we choose the Auth0 implementation. env is the enviroment and it must contains all the data needed to authenticate with the provider(all details in the specific implementations below). For this reason make sure that the connectionStrings.js file is aligned with the deploy environments you are using. In order to make this works locally you must create a .env.local file in the root of your project with all the env variables needed by connectionStrings.js and your AuthProvider implementation.
AUTH0_ClientId = "yourclientId";
AUTH0_Domain = "yourDomain";
AUTH0_Audience = "https://yourAudience.auth0.com/api/v2/";
AUTH0_RedirectUri = "yourRedirectUri";
SERVICE_URL = "yourApi.com";
var http = require("http");
var port = process.env.port;
if (process.env.NODE_ENV === "development") {
require("dotenv").config({ path: ".env.local" });
}
http
.createServer(function (req, res) {
res.writeHead(200, { "Content-Type": "text/javascript" });
res.end(`
window.customSettings = {
clientID: "${process.env["AUTH0_ClientId"]}",
domain: "${process.env["AUTH0_Domain"]}",
audience: "${process.env["AUTH0_Audience"]}",
redirectUri: "${process.env["AUTH0_RedirectUri"]}",
serviceUrl: "${process.env["SERVICE_URL"]}",
};
`);
})
.listen(port);
PORT = 4000;
MSAL_ClientId = "yourclientId";
MSAL_Domain = "yourDomain";
MSAL_Scopes = "YourScopes";
MSAL_knownAuthorities = "yourKnownAutorities";
MSAL_authority = "YourMsalAutority";
MSAL_RedirectUri = "yourRedirectUri";
SERVICE_URL = "yourApi.com";
var http = require("http");
var port = process.env.port;
if (process.env.NODE_ENV === "development") {
require("dotenv").config({ path: ".env.local" });
}
http
.createServer(function (req, res) {
res.writeHead(200, { "Content-Type": "text/javascript" });
res.end(`
window.customSettings = {
clientID: "${process.env["MSAL_ClientId"]}",
domain: "${process.env["MSAL_Domain"]}",
scopes: "${process.env["MSAL_Scopes"]}",
authority:"${process.env["MSAL_authority"]}",
knownAuthorities:"${process.env["MSAL_knownAuthorities"]}",
redirectUri: "${process.env["MSAL_RedirectUri"]}",
serviceUrl: "${process.env["SERVICE_URL"]}",
};
`);
})
.listen(port);
In order to add support for more providers you will implement your own version of the AuthProvider interface. Here is the interface:
export interface AuthProvider {
/**
* Initializes the authentication module with configuration data,
* typically fetched from Azure, and stores it in the Redux store.
*/
init: () => Promise<void>;
/**
* Initiates the login process.
*/
login: () => void;
/**
* Initiates the logout process.
*/
logout: () => void;
/**
* Retrieves the authentication token information
* if token is not valid token will be refreshed silently
* @returns The authentication token information.
*/
handleLoginRedirect: () => Promise<void>;
getToken: (audience?: string) => TokenResponse;
/*
* Checks whether the current user has the specified permission.
*
* @param permission - The permission to check.
* @returns true if the user has the permission, false otherwise.
*/
hasPermission: (permission: string, audience?: string) => boolean;
/**
* Provides information about the current login status,
* including whether the authentication process is loading, any data retrieved,
* and any encountered errors.
*/
getLoginStatus: () => LoginStatus;
/**
* Provides information about the current token retrieval status,
* including whether the process is loading, any data retrieved,
* and any encountered errors.
*/
getUserDetail: () => Promise<UserAccountInfo | null>;
}
React-i18next is used for Localization support. Refer to official documentation for usage or check the LocalizationPage examples.
Edit config/lang.ts configuring the list of supported Locales and the respective title, which will be shown in the LocaleSwitcher in the Header.
To disable Localization but still supporting Zod errors, fill the list with the only supported lang.
Based on zod-i18n-map, has been configured so that you can use zodCustom i18n namespace for custom key messages as shown in LocalizationPage.
const TestSchema = z.object({
name: z.string().min(6),
fieldName: z.string().email(),
customErrorInline: z.number().refine(x => x < 3, {
params: {
i18n: { key: "custom_error" },
},
}),
});
{
"custom_error": "This is a custom message."
}
Check LocalizationPage to see how to use Zod for validating the Forms using zod2FormValidator
and zod2FieldValidator
helpers.
This starter project include PWA via vite-plugin-pwa.
To test the PWA popup, run the preview build.
- npm run build
- npm run preview
- Ctrl+C to stop the Preview server - leave the page open in the Browser
- edit any file
- npm run build
- npm run preview
- A wild Popup happears!
- Remember to uninstall the Service Worker by clearing site data from DevTools before moving back to development via
npm run start
By default this Template adds a Cookie Consent banner. By choice, the Banner is blocking and the entire site is blocked until user picks a choice.
The Template uses technical 'Cookies' by default to provide the following 'necessary' capabilities (Cookies include any storage, including LocalStorage, SessionStorage, WorkersCache, etc.):
- lang: used to provide Lang switch so that User can also Read the ToS.
- dark theme: used to use the system configured theme. This is arguably a 'functional' cookie more than 'necessary' but is embeeded in Chakra UI. Check this discussion.
- auth: authentication libraries like MSAL and Auth0 use cookies for login purposes. Check the respective website for the list of cookies used.
Edit config/gdpr.ts
file.
Only 'external' policy urls are supported as the ConsentBanner is blocking and thus would not redirect. Use the Translation files to embeed the Policy within the description of the Customize.