Skip to content

Commit d8abce0

Browse files
committed
Merge branch '@invertase/v7-development' of https://github.com/firebase/firebaseui-web into @invertase/shadcn-registry
2 parents 5a7e296 + caa1c8d commit d8abce0

File tree

177 files changed

+9216
-5817
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

177 files changed

+9216
-5817
lines changed

GEMINI.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Firebase UI for Web
2+
3+
A library for building UIs with Firebase, with first class support for Angular and shad (with Shadcn).
4+
5+
## General rules
6+
7+
- The workspace is managed with pnpm. Always use pnpm commands for installation and execution.
8+
- This is a monorepo, with `packages` and `examples` sub-directories.
9+
- Linting is controlled by ESLint, via a root flatconfig `eslint.config.ts` file. Run `pnpm lint:check` for linting errors.
10+
- Formatting is controlled vi Prettier integrated with ESLint via the `.prettierrc` file. Run `pnpm format:check` for formatting errors.
11+
- The workspace uses pnpm cataloges to ensure dependency version alignment. If a dependency exists twice, it should be cataloged.
12+
- Tests can be run for the entire workspace via `pnpm test` or scoped to a package via `test:<name>`.
13+
14+
## Structure
15+
16+
The project structure is setup in a way which provides a framework agnostic set of packages; `core`, `translations` and `styles`.
17+
18+
- `core`: The main entry-point to the package via `initalizeUI`. Firebase UI provides it's own functional exports, which when called wraps the Firebase JS SDK functionality, however manages state, translated error handling and behaviors (configurable by the user).
19+
- `translations`: A package exporting utilities and translation mappings for various languages, which `core` depends on.
20+
- `styles`: A package providing CSS utility classes which frameworks can use to provide consistent styling. The `styles` package works for existing Tailwind users, but also exports a distributable file with compiled "tailwindless" CSS. The CSS styles heavily depend on CSS variables for customization.
21+
22+
Additionally, framework specific packages depend on these agnostic packages to offer full integration with the frameworks:
23+
24+
- `react`: Exposes React UI components (in the form of screens, full page components, or forms, the bare-bones UI forms) & hooks, enabling users to easily build their own UIs or consume the built in ones.
25+
- `angular`: Exposes Angular UI components (in the form of screens, full page components, or forms, the bare-bones UI forms) & DI functionality, enabling users to easily build their own UIs or consume the built in ones. This package depends directly on AngularFire.
26+
27+
The dependency graph is:
28+
29+
```
30+
graph TD
31+
core --> translations;
32+
react --> core;
33+
angular --> core;
34+
angular --> styles;
35+
react --> styles;
36+
shadcn --> react;
37+
```
38+
39+
## Misc
40+
41+
- All packages extend the same base `tsconfig.json` file.
42+
- Where possible, prefer Vitest testing framework.
43+
44+
## Additional Context
45+
46+
- `core`: @./packages/core/GEMINI.md
47+
- `react`: @./packages/react/GEMINI.md
48+
- `styles`: @./packages/styles/GEMINI.md
49+
- `translations`: @./packages/translations/GEMINI.md

README.md

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,11 @@ The initializeUI function accepts an options object that allows you to customize
202202
### Type Definition
203203

204204
```js
205-
type FirebaseUIConfigurationOptions = {
205+
type FirebaseUIOptions = {
206206
app: FirebaseApp;
207-
locale?: Locale | undefined;
208-
translations?: RegisteredTranslations[] | undefined;
209-
behaviors?: Partial<Behavior<keyof BehaviorHandlers>>[] | undefined;
210-
recaptchaMode?: 'normal' | 'invisible' | undefined;
207+
auth?: Auth;
208+
locale?: Locale;
209+
behaviors?: Behavior<any>[];
211210
};
212211
```
213212

@@ -290,7 +289,7 @@ const ui = initializeUI({
290289
Configuration Type:
291290

292291
```js
293-
type FirebaseUIConfigurationOptions = {
292+
type FirebaseUIOptions = {
294293
app: FirebaseApp;
295294
locale?: Locale | undefined;
296295
translations?: RegisteredTranslations[] | undefined;
@@ -303,61 +302,61 @@ type FirebaseUIConfigurationOptions = {
303302

304303
**signInWithEmailAndPassword**: Signs in the user based on an email/password credential.
305304

306-
- _ui_: FirebaseUIConfiguration
305+
- _ui_: FirebaseUI
307306
- _email_: string
308307
- _password_: string
309308

310309
**createUserWithEmailAndPassword**: Creates a user account based on an email/password credential.
311310

312-
- _ui_: FirebaseUIConfiguration
311+
- _ui_: FirebaseUI
313312
- _email_: string
314313
- _password_: string
315314

316315
**signInWithPhoneNumber**: Signs in the user based on a provided phone number, using ReCaptcha to verify the sign-in.
317316

318-
- _ui_: FirebaseUIConfiguration
317+
- _ui_: FirebaseUI
319318
- _phoneNumber_: string
320319
- _recaptchaVerifier_: string
321320

322321
**confirmPhoneNumber**: Verifies the phonenumber credential and signs in the user.
323322

324-
- _ui_: FirebaseUIConfiguration
323+
- _ui_: FirebaseUI
325324
- _confirmationResult_: [ConfirmationResult](https://firebase.google.com/docs/reference/node/firebase.auth.ConfirmationResult)
326325
- _verificationCode_: string
327326

328327
**sendPasswordResetEmail**: Sends password reset instructions to an email account.
329328

330-
- _ui_: FirebaseUIConfiguration
329+
- _ui_: FirebaseUI
331330
- _email_: string
332331

333332
**sendSignInLinkToEmail**: Send an sign-in links to an email account.
334333

335-
- _ui_: FirebaseUIConfiguration
334+
- _ui_: FirebaseUI
336335
- _email_: string
337336

338337
**signInWithEmailLink**: Signs in with the user with the email link. If `autoUpgradeAnonymousCredential` then a pending credential will be handled.
339338

340-
- _ui_: FirebaseUIConfiguration
339+
- _ui_: FirebaseUI
341340
- _email_: string
342341
- _link_: string
343342

344343
**signInAnonymously**: Signs in as an anonymous user.
345344

346-
- _ui_: FirebaseUIConfiguration
345+
- _ui_: FirebaseUI
347346

348347
**signInWithOAuth**: Signs in with a provider such as Google via a redirect link. If `autoUpgradeAnonymousCredential` then the account will upgraded.
349348

350-
- _ui_: FirebaseUIConfiguration
349+
- _ui_: FirebaseUI
351350
- _provider_: [AuthProvider](https://firebase.google.com/docs/reference/node/firebase.auth.AuthProvider)
352351

353352
**completeEmailLinkSignIn**: Completes the signing process based on a user signing in with an email link.
354353

355-
- _ui_: FirebaseUIConfiguration
354+
- _ui_: FirebaseUI
356355
- _currentUrl_: string
357356

358357
#### Provide a Store via Context
359358

360-
Using the returned `FirebaseUIConfiguration`, it is reccomended to use local context/providers/dependency-injection to expose the FirebaseUIConfiguration to the application. Here is an example context wrapper which accepts the configuration as a `ui` parameter:
359+
Using the returned `FirebaseUI`, it is reccomended to use local context/providers/dependency-injection to expose the FirebaseUI to the application. Here is an example context wrapper which accepts the configuration as a `ui` parameter:
361360

362361
```js
363362
/** Creates a framework-agnostic context for Firebase UI configuration **/
@@ -391,7 +390,7 @@ export function createFirebaseUIContext(initialConfig) {
391390
FirebaseUI Configuration Type:
392391

393392
```js
394-
export type FirebaseUIConfiguration = {
393+
export type FirebaseUI = {
395394
app: FirebaseApp,
396395
getAuth: () => Auth,
397396
setLocale: (locale: Locale) => void,
@@ -556,7 +555,7 @@ The core library provides a function for handling errors.
556555

557556
```js
558557
export function handleFirebaseError(
559-
ui: FirebaseUIConfiguration,
558+
ui: FirebaseUI,
560559
error: any,
561560
opts?: {
562561
enableHandleExistingCredential?: boolean;

eslint.config.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import tseslint from "typescript-eslint";
77
import pluginPrettier from "eslint-plugin-prettier";
88
import pluginReact from "eslint-plugin-react";
99
import pluginReactHooks from "eslint-plugin-react-hooks";
10+
import pluginAngular from "angular-eslint";
1011

1112
const config: any[] = [
1213
globalIgnores([
@@ -16,6 +17,7 @@ const config: any[] = [
1617
"**/.next/**",
1718
"**/.angular/**",
1819
"**/releases/**",
20+
"**/shadcn/public-dev/**",
1921
"packages/styles/dist.css",
2022
"packages/angular/**",
2123
"packages/shadcn/public",
@@ -30,8 +32,21 @@ const config: any[] = [
3032
"prettier/prettier": "error",
3133
"arrow-body-style": "off",
3234
"prefer-arrow-callback": "off",
35+
"@typescript-eslint/consistent-type-imports": [
36+
"error",
37+
{
38+
disallowTypeAnnotations: false,
39+
prefer: "type-imports",
40+
fixStyle: "inline-type-imports",
41+
},
42+
],
3343
},
3444
},
45+
{
46+
// Angular package specific rules
47+
files: ["packages/angular/src/**/*.{ts,tsx}"],
48+
processor: pluginAngular.processInlineTemplates,
49+
},
3550
{
3651
// React package specific rules
3752
files: ["packages/react/src/**/*.{ts,tsx}", "packages/shadcn/src/**/*.{ts,tsx}"],
@@ -60,6 +75,7 @@ const config: any[] = [
6075
rules: {
6176
"@typescript-eslint/no-explicit-any": "off",
6277
"@typescript-eslint/no-unused-vars": "off",
78+
"@typescript-eslint/consistent-type-imports": "off",
6379
},
6480
},
6581
];

examples/angular/src/app/app.config.server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { mergeApplicationConfig, ApplicationConfig } from "@angular/core";
17+
import { mergeApplicationConfig, type ApplicationConfig } from "@angular/core";
1818
import { provideServerRendering, withRoutes } from "@angular/ssr";
1919
import { serverRoutes } from "./app.routes.server";
2020
import { appConfig } from "./app.config";

examples/angular/src/app/app.config.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { ApplicationConfig, provideZoneChangeDetection, isDevMode } from "@angular/core";
17+
import { type ApplicationConfig, provideZoneChangeDetection, isDevMode } from "@angular/core";
1818
import { provideRouter } from "@angular/router";
1919

2020
import { routes } from "./app.routes";
@@ -26,7 +26,12 @@ import { provideFirebaseUI, provideFirebaseUIPolicies } from "@firebase-ui/angul
2626
import { initializeUI } from "@firebase-ui/core";
2727

2828
const firebaseConfig = {
29-
// your Firebase config here
29+
apiKey: "AIzaSyCvMftIUCD9lUQ3BzIrimfSfBbCUQYZf-I",
30+
authDomain: "fir-ui-rework.firebaseapp.com",
31+
projectId: "fir-ui-rework",
32+
storageBucket: "fir-ui-rework.firebasestorage.app",
33+
messagingSenderId: "200312857118",
34+
appId: "1:200312857118:web:94e3f69b0e0a4a863f040f",
3035
};
3136

3237
export const appConfig: ApplicationConfig = {

examples/angular/src/app/app.routes.server.ts

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,47 +14,56 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { RenderMode, ServerRoute } from "@angular/ssr";
17+
import { RenderMode, type ServerRoute } from "@angular/ssr";
1818

1919
export const serverRoutes: ServerRoute[] = [
2020
/** Home page - perfect for SSG as it's a static landing page */
2121
{
2222
path: "",
2323
renderMode: RenderMode.Prerender,
2424
},
25-
/** Key auth screen demos - good for SSG as they showcase Firebase UI components */
25+
/** Static auth demos - good for SSG as they showcase Firebase UI components */
2626
{
27-
path: "screens/sign-in-auth-screen",
27+
path: "sign-in",
2828
renderMode: RenderMode.Prerender,
2929
},
3030
{
31-
path: "screens/oauth-screen",
31+
path: "oauth",
3232
renderMode: RenderMode.Prerender,
3333
},
34+
/** Interactive auth routes - better as CSR for user interaction */
3435
{
35-
path: "screens/sign-up-auth-screen",
36-
renderMode: RenderMode.Prerender,
36+
path: "sign-up",
37+
renderMode: RenderMode.Client,
3738
},
3839
{
39-
path: "screens/email-link-auth-screen",
40-
renderMode: RenderMode.Prerender,
40+
path: "forgot-password",
41+
renderMode: RenderMode.Client,
4142
},
43+
/** Dynamic auth routes - good for SSR as they may need server-side data */
4244
{
43-
path: "screens/phone-auth-screen",
44-
renderMode: RenderMode.Prerender,
45+
path: "email-link",
46+
renderMode: RenderMode.Server,
4547
},
46-
/** Interactive auth routes - better as CSR for user interaction */
4748
{
48-
path: "sign-in",
49-
renderMode: RenderMode.Client,
49+
path: "email-link-oauth",
50+
renderMode: RenderMode.Server,
5051
},
5152
{
52-
path: "register",
53-
renderMode: RenderMode.Client,
53+
path: "phone",
54+
renderMode: RenderMode.Server,
5455
},
5556
{
56-
path: "forgot-password",
57-
renderMode: RenderMode.Client,
57+
path: "phone-oauth",
58+
renderMode: RenderMode.Server,
59+
},
60+
{
61+
path: "sign-in-oauth",
62+
renderMode: RenderMode.Server,
63+
},
64+
{
65+
path: "sign-up-oauth",
66+
renderMode: RenderMode.Server,
5867
},
5968
/** All other routes will be rendered on the server (SSR) */
6069
{

0 commit comments

Comments
 (0)