Skip to content

chore: deep maintenance overhaul — builder-bob, ESLint 9, CI, tests, validator fixes & README rewrite#586

Open
kuraydev wants to merge 7 commits into
masterfrom
chore/deep-overhaul-2026
Open

chore: deep maintenance overhaul — builder-bob, ESLint 9, CI, tests, validator fixes & README rewrite#586
kuraydev wants to merge 7 commits into
masterfrom
chore/deep-overhaul-2026

Conversation

@kuraydev

@kuraydev kuraydev commented Jun 29, 2026

Copy link
Copy Markdown
Owner

Automated deep-overhaul PR — review before merge.

Review fixes applied: bumped package.json to 6.0.0 (was still 5.0.0, identical to the last-published version) and retitled the CHANGELOG [Unreleased] section to [6.0.0], per the recommended major below.

Summary

A full maintenance overhaul of react-native-login-screen after ~3.3 years without a release. The library's public API — exported names, ILoginScreenProps prop names, and every runtime default value — is unchanged. The default export (import LoginScreen from "react-native-login-screen") and named exports (SocialButton, emailValidator, passwordValidator) still resolve exactly as before. The npm package name and license are untouched. Changes cluster into: broken-tooling repair, real tests + CI, packaging modernization, pure bug fixes, and a README rewrite.

All work is verified locally (see Verification).

Non-breaking improvements

Tooling

  • Replaced the dead tslint -p tsconfig.json lint script (TSLint removed from npm since 2019, not installed) with eslint ..
  • Migrated the legacy .eslintrc.js to an ESLint 9 flat eslint.config.js (typescript-eslint + eslint-plugin-react + react-hooks + eslint-config-prettier).
  • Fixed the format script glob (it targeted a non-existent src/** on the old layout).
  • Modernized husky hooks (lint-staged pre-commit, commitlint commit-msg).

CI / release

  • Added .github/workflows/ci.yml: install + lint + typecheck (tsc --noEmit) + test (with coverage) + build on a Node 18/20/22 matrix, on push/PR.
  • Added .github/workflows/release.yml (manual dispatch) wiring up the already-present semantic-release.

Tests (library had zero)

  • Jest + @testing-library/react-native, 24 tests: emailValidator, passwordValidator (incl. the strength patterns), SocialButton, and LoginScreen covering rendering, text/placeholder overrides, disableSignup / disableSocialButtons / disablePasswordInput, the change/press handlers, email-validation tooltip behavior, and custom-button slots.

Source quality (no public-API change)

  • Replaced any types: logoImageSourceImageSourcePropType, childrenReact.ReactNode, TouchableComponent → a real TouchableComponentType, and rewrote useStateWithCallback with real generics.
  • Added an Android UIManager.setLayoutAnimationEnabledExperimental(true) guard so tooltip LayoutAnimation.spring() calls actually animate.
  • Switched Dimensions.get('screen') to useWindowDimensions() for responsive re-layout.
  • Wrapped the component in React.memo and memoized the render* helpers and default tooltip content.
  • Added accessibilityRole/accessibilityLabel to the login button, signup link, social buttons, and inputs.

Packaging / metadata

  • Repointed all URLs (homepage/bugs/repository/author) to kuraydev; kept the npm name react-native-login-screen.
  • Declared react (>=16.8.0) and react-native (>=0.60.0) peerDependencies with intentionally wide ranges.
  • Added a files allowlist and explicit types/module/react-native/source/exports fields.
  • Removed dead/deprecated devDeps: the tslint reference, @types/react-native, react-native-typescript-transformer, npm-post-install, prettier-format, eslint-config-airbnb.

Docs / hygiene

  • README rewrite: deduped the disableEmailTooltip row (was listed 3× with copy-pasted wrong descriptions) and the duplicated style/button rows; documented enablePasswordValidation; added a SocialButton props table and exported-helper docs; added a ToC, TypeScript usage, and a New Architecture / Expo / web-support section; reconciled the peer-dep description.
  • Added CHANGELOG.md (Keep a Changelog), CONTRIBUTING.md, .github/ISSUE_TEMPLATE/*, and PULL_REQUEST_TEMPLATE.md.

Breaking changes (v6.0.0 major)

  1. builder-bob packaging. Output moves from build/dist/* to lib/{commonjs,module,typescript}/*; mainlib/commonjs/index.js and an exports map is added. The bare package import is preserved, but deep imports into build/dist/* (or the old lib/*.ts source) will break.
  2. passwordValidator regex fix. patternNormal/Medium/High used \\d (literal backslash+d) and never matched digits; now corrected to \d. Passwords that passed the broken validation may now fail. Limited blast radius — enablePasswordValidation defaults to false.
  3. Dependency bound. react-native-text-input-interactive tightened from open-ended >=0.1.4 to >=0.1.4 <1.0.0.
  4. New peerDependencies. react/react-native are now declared (very wide ranges); consumers may see new peer warnings.
  5. Stricter public types. any props are now properly typed; strongly-typed consumers passing previously-any values may surface new compile-time errors. No prop names or runtime defaults changed.

Verification

Run on this branch (node 20 / npm 10):

Check Command Result
Typecheck npx tsc --noEmit pass — no errors
Lint npx eslint . pass — no issues
Tests npx jest pass — 24/24
Build npx bob build pass — commonjs + module + typescript, PNG assets copied
Entry resolution fs.existsSync(main/module/types) all true after build

Public ILoginScreenProps prop names and every runtime default are byte-identical to master. lib/ is gitignored so no build artifacts are committed.

Web issues

The two open web issues are addressed via documentation (react-native-web caveats around Dimensions, require()'d PNG assets, and LayoutAnimation) plus the useWindowDimensions swap and the Android LayoutAnimation guard, rather than a verified web-rendering fix:

react-native-web support (Closes #56, #11)

LoginScreen is a pure-JS component, so it can run on the web — but it didn't, because the email/password validation flow called LayoutAnimation.spring() unconditionally. react-native-web does not implement LayoutAnimation, so those calls threw/warned and broke the screen on web.

Fix (additive, web-only, non-breaking on native):

  • New helper src/helpers/layoutAnimation.tsspringLayoutAnimation() no-ops when Platform.OS === 'web' and otherwise runs the exact native LayoutAnimation.spring(). Both former call sites in LoginScreen.tsx now use it; LayoutAnimation is no longer statically imported by the component.
  • On web the validation tooltips still appear, just without the spring animation. iOS/Android behavior is byte-for-byte unchanged (the only added branch is gated on Platform.OS === 'web').
  • Audited other RNW breakers: bundled require()'d PNGs (logo, social icons, eye) all already carry explicit width/height, so they render under RNW; no native-only APIs like Keyboard/BackHandler are used.

Tests / docs:

  • Added src/__tests__/LoginScreen.web.test.tsx (runs under Platform.OS === 'web'): asserts the component renders without throwing and that an invalid-email Login press still shows the tooltip while LayoutAnimation.spring is never called.
  • Updated the README "Platform support" section (web is now supported, with caveats) and added an [Unreleased] CHANGELOG entry.

No public exports/props/defaults/visuals changed; package name and version untouched.

Verification: tsc --noEmit clean, eslint . clean, jest 26/26 passing (24 → 26), bob build (commonjs/module/typescript) succeeds.

kuraydev added 6 commits June 29, 2026 16:03
- Move source from lib/ to src/.
- Fix passwordValidator regex (\\d -> \d) so the digit rule actually applies.
- Guard LayoutAnimation on Android via setLayoutAnimationEnabledExperimental.
- Replace any-typed props (logoImageSource, children, TouchableComponent) and
  rewrite useStateWithCallback with real generics.
- Wrap LoginScreen in React.memo; memoize render helpers and tooltip content.
- Derive widths from useWindowDimensions instead of a module-load Dimensions read.
- Add accessibilityRole/accessibilityLabel to buttons and inputs.
- Export prop types and password pattern presets from the barrel.
- Replace bespoke tsc+cpx+react-native-typescript-transformer pipeline with
  react-native-builder-bob (commonjs/module/typescript targets).
- Add main/module/types/react-native/source/exports/files fields; keep the
  default + named exports and bare package-name import working.
- Declare react/react-native peerDependencies (wide ranges) and bound
  react-native-text-input-interactive to >=0.1.4 <1.0.0.
- Repoint repository/homepage/bugs/author URLs to kuraydev (npm name unchanged).
- Drop dead deps (tslint ref, react-native-typescript-transformer,
  @types/react-native, cpx, npm-post-install, prettier-format, airbnb config).
- Replace dead tslint lint script with ESLint 9 flat config; fix format glob.
- Wire husky pre-commit to lint-staged.
Unit tests for emailValidator and passwordValidator (incl. the \d regression),
plus render/interaction tests for LoginScreen and SocialButton.
CI runs install, lint, typecheck, test and build on a Node 18/20/22 matrix.
A manual release workflow drives semantic-release. Adds issue + PR templates.
Fix the duplicated/incorrect props tables, document enablePasswordValidation,
SocialButton, the exported validators and pattern presets, reconcile the
dependency note, and add New Architecture/Expo/web platform guidance.
@kuraydev kuraydev changed the title Deep overhaul: builder-bob packaging, ESLint 9, tests, CI, validator fixes & README rewrite chore: deep maintenance overhaul — builder-bob, ESLint 9, CI, tests, validator fixes & README rewrite Jun 29, 2026
react-native-web does not implement LayoutAnimation, so the unconditional
LayoutAnimation.spring() calls in the email/password validation flow threw
or warned on web, breaking LoginScreen there (closes #56, #11).

Add a web-only springLayoutAnimation() helper that no-ops on
Platform.OS === "web" and runs the exact native animation everywhere else,
so iOS/Android behavior is byte-for-byte unchanged. Bundled PNG assets
already carry explicit width/height, so they render under RNW.

Add a web smoke test (Platform.OS === "web") asserting the component
renders without throwing and the tooltip degrades gracefully without
invoking LayoutAnimation. Update README web-support note and CHANGELOG.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Doesn't work with Web

1 participant