Skip to content

Commit

Permalink
Merge branch 'master' into fix-regexp-file-extension
Browse files Browse the repository at this point in the history
  • Loading branch information
guilhermerodz authored Mar 11, 2024
2 parents c27a76b + 2c44459 commit 3553630
Show file tree
Hide file tree
Showing 87 changed files with 14,300 additions and 381 deletions.
13 changes: 13 additions & 0 deletions .github/ISSUE_TEMPLATE/bad-design-choice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
name: Bad design choice
about: Describe a preference/default that was either 1. ignored 2. blocked or 3. wrong
from the API perspective.
title: "[DX/UX]"
labels: invalid
assignees: ''

---

Example:

I'm unhappy with ___ design/API choice because ___. The ___ could be better if you ___.
41 changes: 41 additions & 0 deletions .github/ISSUE_TEMPLATE/bug-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
name: Bug report
about: Describe your bug. Which version?
title: "[BUG]"
labels: bug
assignees: guilhermerodz

---

Issue tracker is **ONLY** used for reporting bugs. New features should be discussed on our slack channel. Please use [stackoverflow](https://stackoverflow.com) for supporting issues.

<!--- Provide a general summary of the issue in the Title above -->

## Expected Behavior
<!--- Tell us what should happen -->

## Current Behavior
<!--- Tell us what happens instead of the expected behavior -->

## Possible Solution
<!--- Not obligatory, but suggest a fix/reason for the bug, -->

## Steps to Reproduce
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug. Include code to reproduce, if relevant -->
1.
2.
3.
4.

## Context (Environment)
<!--- How has this issue affected you? What are you trying to accomplish? -->
<!--- Providing context helps us come up with a solution that is most useful in the real world -->

<!--- Provide a general summary of the issue in the Title above -->

## Detailed Description
<!--- Provide a detailed description of the change or addition you are proposing -->

## Possible Implementation
<!--- Not obligatory, but suggest an idea for implementing addition or change -->
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
11 changes: 7 additions & 4 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: oven-sh/setup-bun@v1
- uses: actions/setup-node@v3
with:
node-version: 18.17.0
- run: npm install -g [email protected]

- run: bun install
- run: bunx playwright install --with-deps
- run: bun run test || exit 1
- run: pnpm install
- run: npx playwright install --with-deps
- run: pnpm test || exit 1

- uses: actions/upload-artifact@v3
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ node_modules

# testing
coverage
/test-results/
test-results/
playwright-report/
playwright/.cache/

Expand Down
138 changes: 133 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# OTP Input for React
# The only accessible & unstyled & full featured Input OTP component in the Web.

### OTP Input for React 🔐 by [@guilhermerodz](https://twitter.com/guilherme_rodz)

https://github.com/guilhermerodz/input-otp/assets/10366880/753751f5-eda8-4145-a4b9-7ef51ca5e453

Expand Down Expand Up @@ -123,6 +125,8 @@ This library works by rendering an invisible input as a sibling of the slots, co

## Features

This is the most complete OTP input on the web. It's fully featured

<details>
<summary>Supports iOS + Android copy-paste-cut</summary>

Expand Down Expand Up @@ -165,6 +169,27 @@ https://github.com/guilhermerodz/input-otp/assets/10366880/185985c0-af64-48eb-92

</details>

<details>
<summary>Automatically optimizes for password managers</summary>


For password managers such as LastPass, 1Password, Dashlane or Bitwarden, `input-otp` will automatically detect them in the page and increase input width by ~40px to trick the password manager's browser extension and prevent the badge from rendering to the last/right slot of the input.

<img width="670" alt="image" src="https://github.com/guilhermerodz/input-otp/assets/10366880/9bb306ca-deff-4803-aa3d-148c594a540c">

- **This feature is optional and it's enabled by default. You can disable this optimization by adding `pushPasswordManagerStrategy="none"`.**
- **This feature does not cause visible layout shift.**

### Auto tracks if the input has space in the right side for the badge

https://github.com/guilhermerodz/input-otp/assets/10366880/bf01af88-1f82-463e-adf4-54a737a92f59

### Experimental flag

Try `pushPasswordManagerStrategy={experimental-no-flickering}` to initially render the input with extra width so that password manager users won't see their badges flickering.
After ~6 seconds _onfocus_, the input will return to it's original width if no password manager.
</details>

## API Reference

### OTPInput
Expand Down Expand Up @@ -200,6 +225,47 @@ type OTPInputProps = {
// Virtual keyboard appearance on mobile
// Default: 'numeric'
inputMode?: 'numeric' | 'text'

// Enabled by default, it's an optional
// strategy for detecting Password Managers
// in the page and then shifting their
// badges to the right side, outside the input.
// There is also `experimental-no-flickering`
// (experimental flag use it on your risk)
// which won't cause badge flickering at all.
// Default: 'increase-width'
pushPasswordManagerStrategy?:
| 'increase-width'
| 'none'
| 'experimental-no-flickering'

// Enabled by default, it's an optional
// fallback for pages without JS.
// This is a CSS string. Write your own
// rules that will be applied as soon as
// <noscript> is parsed for no-js pages.
// Use `null` to disable any no-js fallback (not recommended).
// Default: `
// [data-input-otp] {
// --nojs-bg: white !important;
// --nojs-fg: black !important;
//
// background-color: var(--nojs-bg) !important;
// color: var(--nojs-fg) !important;
// caret-color: var(--nojs-fg) !important;
// letter-spacing: .25em !important;
// text-align: center !important;
// border: 1px solid var(--nojs-fg) !important;
// border-radius: 4px !important;
// width: 100% !important;
// }
// @media (prefers-color-scheme: dark) {
// [data-input-otp] {
// --nojs-bg: black !important;
// --nojs-fg: white !important;
// }
// }`
noScriptCSSFallback?: string | null
}
```
Expand Down Expand Up @@ -249,7 +315,69 @@ export default function Page() {
## Caveats

<details>
<summary>If you're using experiencing an unwanted border on input focus:</summary>
<summary>[Workaround] If you want to block specific password manager/badges:</summary>

By default, `input-otp` handles password managers for you.
The password manager badges should be automatically shifted to the right side.

However, if you still want to block password managers, please disable the `pushPasswordManagerStrategy` and then manually block each PWM.

```diff
<OTPInput
// First, disable library's built-in strategy
// for shifting badges automatically
- pushPasswordManagerStrategy="increase-width"
- pushPasswordManagerStrategy="experimental-no-flickering"
+ pushPasswordManagerStrategy="none"
// Then, manually add specifics attributes
// your password manager docs
// Example: block LastPass
+ data-lpignore="true"
// Example: block 1Password
+ data-1p-ignore="true"
/>
```
</details>

<details>
<summary>[Setting] If you want to customize the <noscript> CSS fallback</summary>

By default, `input-otp` handles cases where JS is not in the page by applying custom CSS styles.
If you do not like the fallback design and want to apply it to your own, just pass a prop:

```diff
// This is the default CSS fallback.
// Feel free to change it entirely and apply to your design system.
const NOSCRIPT_CSS_FALLBACK = `
[data-input-otp] {
--nojs-bg: white !important;
--nojs-fg: black !important;

background-color: var(--nojs-bg) !important;
color: var(--nojs-fg) !important;
caret-color: var(--nojs-fg) !important;
letter-spacing: .25em !important;
text-align: center !important;
border: 1px solid var(--nojs-fg) !important;
border-radius: 4px !important;
width: 100% !important;
}
@media (prefers-color-scheme: dark) {
[data-input-otp] {
--nojs-bg: black !important;
--nojs-fg: white !important;
}
}`

<OTPInput
// Pass your own custom styles for when JS is disabled
+ noScriptCSSFallback={NOSCRIPT_CSS_FALLBACK}
/>
```
</details>

<details>
<summary>[Workaround] If you're experiencing an unwanted border on input focus:</summary>

```diff
<OTPInput
Expand All @@ -262,7 +390,7 @@ export default function Page() {
</details>

<details>
<summary>If you want to centralize input text/selection, use the `textAlign` prop:</summary>
<summary>[Not Recommended] If you want to centralize input text/selection, use the `textAlign` prop:</summary>

```diff
<OTPInput
Expand All @@ -271,7 +399,7 @@ export default function Page() {
/>
```

NOTE: this also affects the selected caret position after a touch/click
NOTE: this also affects the selected caret position after a touch/click.

`textAlign="left"`
<img src="https://github.com/guilhermerodz/input-otp/assets/10366880/685a03df-2b69-4a36-b21c-e453f6098f79" width="300" />
Expand All @@ -288,7 +416,7 @@ NOTE: this also affects the selected caret position after a touch/click
</details>

<details>
<summary>Add Tailwind autocomplete for `containerClassname` attribute in VS Code.</summary>
<summary>[DX] Add Tailwind autocomplete for `containerClassname` attribute in VS Code.</summary>

Add the following setting to your `.vscode/settings.json`:
```diff
Expand Down
24 changes: 24 additions & 0 deletions apps/storybook/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
.eslintcache

npm-debug.log*
yarn-debug.log*
yarn-error.log*
22 changes: 22 additions & 0 deletions apps/storybook/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/** @type { import('@storybook/react-vite').StorybookConfig } */
const config = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
staticDirs: ['../public'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/react-vite',
options: {},
},
docs: {
autodocs: 'tag',
},
webpackFinal: async (config, { configType }) => {
config.resolve.plugins = [new TsconfigPathsPlugin()]
return config
},
}
export default config
16 changes: 16 additions & 0 deletions apps/storybook/.storybook/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import '../src/globals.css'

/** @type { import('@storybook/react').Preview } */
const preview = {
parameters: {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
},
};

export default preview;
21 changes: 21 additions & 0 deletions apps/storybook/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2018 Chroma Software Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading

0 comments on commit 3553630

Please sign in to comment.