├── app ├── vite-env.d.ts ├── main.tsx ├── Footer.tsx ├── App.tsx ├── Profiler.tsx ├── Examples │ ├── BasicMode │ │ ├── index.tsx │ │ └── styles.css │ ├── RefineMode │ │ ├── index.tsx │ │ └── styles.css │ └── EventsChildren │ │ ├── styles.css │ │ └── index.tsx ├── favicon.svg ├── styles │ ├── reset.css │ └── app.css ├── Header.tsx └── Section.tsx ├── .husky └── pre-commit ├── src ├── index.ts ├── useLocalizedList.ts ├── utils.ts ├── types.ts ├── domains.json └── Email.tsx ├── .gitignore ├── .prettierrc ├── cypress └── support │ ├── component-index.html │ ├── component.ts │ ├── cypress.d.ts │ └── commands.ts ├── cypress.config.ts ├── index.html ├── tsconfig.json ├── .github └── workflows │ └── tests.yml ├── .eslintrc.json ├── tests ├── useLocalizedList.tsx ├── Email.tsx ├── useLocalizedList.cy.tsx └── Email.cy.tsx ├── LICENSE ├── vite.config.mts ├── package.json └── README.md /app/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx lint-staged -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { default as domains } from './domains.json' 2 | export { useLocalizedList } from './useLocalizedList' 3 | export { Email } from './Email' 4 | 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | 4 | .vscode/* 5 | !.vscode/extensions.json 6 | .DS_Store 7 | 8 | cypress/downloads 9 | cypress/videos 10 | cypress/screenshots 11 | 12 | *.tgz 13 | .eslintcache 14 | 15 | pnpm-lock.yaml 16 | -------------------------------------------------------------------------------- /app/main.tsx: -------------------------------------------------------------------------------- 1 | import { createRoot } from 'react-dom/client' 2 | import { App } from './App' 3 | 4 | import './styles/reset.css' 5 | import './styles/app.css' 6 | 7 | const root = createRoot(document.getElementById('root') as HTMLElement) 8 | 9 | root.render() 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "singleQuote": true, 4 | "printWidth": 120, 5 | "useTabs": false, 6 | "tabWidth": 3, 7 | "semi": false, 8 | "overrides": [ 9 | { 10 | "files": "README.md", 11 | "options": { 12 | "printWidth": 80, 13 | "tabWidth": 2 14 | } 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /cypress/support/component-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | React Email Autocomplete 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /app/Footer.tsx: -------------------------------------------------------------------------------- 1 | export function Footer() { 2 | return ( 3 | 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /cypress/support/component.ts: -------------------------------------------------------------------------------- 1 | import 'cypress-real-events' 2 | import 'cypress-axe' 3 | import './commands' 4 | 5 | export function getRandomInt(min: number, max: number) { 6 | min = Math.ceil(min) 7 | max = Math.floor(max) 8 | return Math.floor(Math.random() * (max - min) + min) 9 | } 10 | 11 | export function getRandomIndex(length: number) { 12 | return Math.floor(Math.random() * length) 13 | } 14 | -------------------------------------------------------------------------------- /cypress.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'cypress' 2 | 3 | export default defineConfig({ 4 | component: { 5 | specPattern: '**/*.cy.tsx', 6 | devServer: { 7 | framework: 'react', 8 | bundler: 'vite', 9 | }, 10 | video: false, 11 | setupNodeEvents(on) { 12 | on('task', { 13 | log(message) { 14 | console.log(message) 15 | return null 16 | }, 17 | }) 18 | }, 19 | }, 20 | }) 21 | -------------------------------------------------------------------------------- /cypress/support/cypress.d.ts: -------------------------------------------------------------------------------- 1 | import { mount } from 'cypress/react' 2 | 3 | declare global { 4 | namespace Cypress { 5 | interface Chainable { 6 | mount: typeof mount 7 | downArrow(repeat: number): Chainable 8 | upArrow(repeat: number): Chainable 9 | setNavigatorLang(value: string): Chainable 10 | getSuggestions(selector: string, username: string): Chainable 11 | withinRoot(fn: () => void): Chainable 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | React Email Autocomplete 8 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/App.tsx: -------------------------------------------------------------------------------- 1 | import { useLayoutEffect } from 'react' 2 | import { Header } from './Header' 3 | import { Footer } from './Footer' 4 | import { BasicMode } from './Examples/BasicMode' 5 | import { RefineMode } from './Examples/RefineMode' 6 | import { EventsChildren } from './Examples/EventsChildren' 7 | 8 | export function App() { 9 | useLayoutEffect(() => { 10 | document.getElementsByTagName('input')[0].focus() 11 | }, []) 12 | 13 | return ( 14 | <> 15 |
16 | 17 | 18 | 19 |