react-animated-select 0.2.9 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -28
- package/demo/README.md +16 -0
- package/demo/eslint.config.js +29 -0
- package/demo/index.html +13 -0
- package/demo/package-lock.json +3436 -0
- package/demo/package.json +37 -0
- package/demo/public/vite.svg +1 -0
- package/demo/src/App.tsx +412 -0
- package/demo/src/main.jsx +9 -0
- package/demo/src/rac.css +754 -0
- package/demo/src/shake.js +11 -0
- package/demo/src/slideDown.jsx +35 -0
- package/demo/vite.config.js +7 -0
- package/dist/index.cjs.js +5 -8
- package/dist/index.css +1 -1
- package/dist/index.es.js +666 -569
- package/index.d.ts +10 -1
- package/package.json +3 -2
- package/src/option.jsx +5 -1
- package/src/select.css +7 -0
- package/src/select.jsx +71 -40
- package/src/useSelect.jsx +77 -8
- package/src/useSelectLogic.jsx +88 -49
package/README.md
CHANGED
|
@@ -2,30 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
A lightweight, high-performance, and fully customizable Select component for React. Featuring smooth CSS animations, accessible keyboard navigation, and flexible option rendering.
|
|
4
4
|
|
|
5
|
+
**Try it out:**
|
|
6
|
+
[](https://l1nway.github.io/react-animated-select/)
|
|
7
|
+
|
|
5
8
|
## Features
|
|
6
9
|
|
|
7
10
|
- **Smooth Animations**
|
|
8
|
-
|
|
9
11
|
Powered by `react-transition-group` with height-expanding dropdowns and sliding side-elements.
|
|
10
12
|
|
|
11
13
|
- **Accessible**
|
|
12
|
-
|
|
13
14
|
Full keyboard support (Arrow keys, Enter, Space, Escape, Tab) and ARIA attributes built-in.
|
|
14
15
|
|
|
15
16
|
- **Flexible Data**
|
|
16
|
-
|
|
17
|
-
Supports simple arrays, objects, or declarative JSX children (`<Option />`).
|
|
17
|
+
Supports simple arrays, objects, or declarative JSX children (`<Option />`). **Smart deep parsing** extracts labels from any available object key.
|
|
18
18
|
|
|
19
19
|
- **Smart Auto-Positioning**
|
|
20
|
-
|
|
21
20
|
Recalculates dropdown position using `ResizeObserver`.
|
|
22
21
|
|
|
23
22
|
- **Zero-Config Styles**
|
|
24
|
-
|
|
25
23
|
The minimum styles required for the select to work are built into the project, but you can add your own on top of the basic ones.
|
|
26
24
|
|
|
27
25
|
- **Search & Clear**
|
|
28
|
-
|
|
29
26
|
Built-in “Clear” button and intelligent state handling (loading, error, empty, disabled).
|
|
30
27
|
|
|
31
28
|
## Installation
|
|
@@ -81,10 +78,10 @@ function App() {
|
|
|
81
78
|
| `disabled` | `boolean` | `false` | Disables the entire component. |
|
|
82
79
|
| `loading` | `boolean` | `false` | Shows a loading animation and disables interaction. |
|
|
83
80
|
| `error` | `boolean` | `false` | Shows the error state and `errorText`. |
|
|
84
|
-
| `style` | `object` | `{}` | Inline styles for the root container.
|
|
85
|
-
| `className` | `string` | '' | Additional CSS class for the root container .rac-select.
|
|
81
|
+
| `style` | `object` | `{}` | Inline styles for the root container. |
|
|
82
|
+
| `className` | `string` | '' | Additional CSS class for the root container .rac-select. |
|
|
86
83
|
| `ArrowIcon` | `ElementType \ string \ JSX` | Default icon | Custom arrow icon. Accepts a component, image path, or JSX. |
|
|
87
|
-
| `ClearIcon` | `ElementType \ string \ JSX` | Default icon | Custom clear icon. Accepts a component, image path, or JSX.
|
|
84
|
+
| `ClearIcon` | `ElementType \ string \ JSX` | Default icon | Custom clear icon. Accepts a component, image path, or JSX. |
|
|
88
85
|
|
|
89
86
|
---
|
|
90
87
|
|
|
@@ -101,12 +98,20 @@ function App() {
|
|
|
101
98
|
|
|
102
99
|
### Behavioral Props
|
|
103
100
|
|
|
104
|
-
| Prop
|
|
105
|
-
|
|
106
|
-
| `visibility`
|
|
107
|
-
| `ownBehavior`
|
|
108
|
-
| `alwaysOpen`
|
|
109
|
-
| `unmount`
|
|
101
|
+
| Prop | Type | Default | Description |
|
|
102
|
+
| --------------- | ---------- | ---------- | ------------------------------------------------------------------------------------------------------- |
|
|
103
|
+
| `visibility` | `boolean` | `false` | Manually controls the visibility of the list (used with `ownBehavior`). |
|
|
104
|
+
| `ownBehavior` | `boolean` | `false` | If `true`, the component stops managing its own open/close state and relies on the `visibility` prop. |
|
|
105
|
+
| `alwaysOpen` | `boolean` | `false` | Keeps the list permanently visible. Primarily used for debugging or specific UI layouts. |
|
|
106
|
+
| `unmount` | `boolean` | `true` | When `true`, the list is removed from the DOM when closed. When `false`, it stays invisible in the DOM. |
|
|
107
|
+
| `hasMore` | `boolean` | `false` | Indicates whether more options are available for loading (used for infinite loading). |
|
|
108
|
+
| `loadMore` | `function` | `() => {}` | Callback triggered when more options need to be loaded. |
|
|
109
|
+
| `loadMoreText` | `string` | `'Loading'` | Text displayed inside the options list during loading. |
|
|
110
|
+
| `loadOffset` | `number` | `100` | Distance (in pixels) from the bottom of the list that triggers `loadMore`. |
|
|
111
|
+
| `loadAhead` | `number` | `3` | Number of remaining options before the end at which loading is triggered during keyboard navigation. |
|
|
112
|
+
| `loadButton` | `boolean` | `false` | Enables a manual “Load more” button instead of automatic loading. |
|
|
113
|
+
| `loadButtonText` | `string` | `'Load more'` | Text displayed on the load button. |
|
|
114
|
+
| `childrenFirst` | `boolean` | `false` | Determines priority of JSX `<Option />` children over options passed via props. |
|
|
110
115
|
|
|
111
116
|
---
|
|
112
117
|
|
|
@@ -202,6 +207,7 @@ The component uses CSS variables for deep styling. These are based on system col
|
|
|
202
207
|
| `--rac-true-option-color` | `color-mix(...)` | Text color for "Boolean True" items. |
|
|
203
208
|
| `--rac-false-option-color` | `color-mix(...)` | Text color for "Boolean False" items. |
|
|
204
209
|
| `--rac-option-padding` | `0.5em` | Internal padding for each option item. |
|
|
210
|
+
| `--rac-option-min-height` | `1em` | Minimum option height. |
|
|
205
211
|
| `--rac-invalid-option-color` | `color-mix(...)` | Text color for invalid options. |
|
|
206
212
|
| `--rac-warning-option-color` | `color-mix(...)` | Text color for warning/caution options. |
|
|
207
213
|
|
|
@@ -246,18 +252,54 @@ The select and its options react to internal states by applying the following cl
|
|
|
246
252
|
- `.rac-select-arrow-wrapper.--open`: Applied to the arrow icon when the dropdown is expanded.
|
|
247
253
|
|
|
248
254
|
## Change log
|
|
249
|
-
### 0.
|
|
250
|
-
####
|
|
251
|
-
-
|
|
252
|
-
|
|
253
|
-
-
|
|
254
|
-
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
- **
|
|
255
|
+
### 0.3.0
|
|
256
|
+
#### Features
|
|
257
|
+
- **Extended option format support**
|
|
258
|
+
If standard option fields (`name`, `label`, `id`, `value`) are missing or empty, the parser performs a deep lookup and automatically uses the first meaningful content field as the option label.
|
|
259
|
+
- **Smart empty-state handling**
|
|
260
|
+
- Option objects without meaningful content (e.g. `{value: null}`) are now automatically marked as `disabled` and display the `emptyOption` text.
|
|
261
|
+
- JSX options with an empty `value` but valid textual content (e.g. `<Option value="">Text</Option>`) are now treated as valid and selectable.
|
|
262
|
+
- **Infinite loading support**
|
|
263
|
+
- Added `loadMore` mechanism for infinite or paginated option lists.
|
|
264
|
+
- Automatic loading when scrolling near the end of the list.
|
|
265
|
+
- Automatic loading when navigating with keyboard near the last options.
|
|
266
|
+
- **Demo preview**
|
|
267
|
+
- Added an interactive demo showcasing all Select component features.
|
|
268
|
+
----------
|
|
269
|
+
### Improvements
|
|
270
|
+
- **Keyboard navigation**
|
|
271
|
+
- Navigation behaves predictably with infinite loading enabled.
|
|
272
|
+
- **Options handling**
|
|
273
|
+
- Extended support for options passed both via props and JSX.
|
|
274
|
+
- Improved internal merging logic for mixed option sources.
|
|
275
|
+
- **Focus management**
|
|
276
|
+
- Removed unnecessary focus on the options list container.
|
|
277
|
+
- Improved overall keyboard navigation flow.
|
|
278
|
+
- **Visual consistency**
|
|
279
|
+
- Improved layout stability and rendering consistency across option states.
|
|
280
|
+
----------
|
|
281
|
+
### Fixes
|
|
282
|
+
- **Object value matching**
|
|
283
|
+
- Fixed an issue where the Select could not correctly find the selected option when it was passed as an object.
|
|
284
|
+
- Selection matching now works correctly using reference comparison and structural analysis.
|
|
285
|
+
- **Opacity rendering**
|
|
286
|
+
- Fixed incorrect opacity handling for various option states.
|
|
287
|
+
- **JSX identifier validation**
|
|
288
|
+
- Fixed an issue where passing an empty `id` to `<Option id="" />` caused the option text to be lost.
|
|
289
|
+
- The parser now prioritizes any available meaningful content.
|
|
290
|
+
- **Focus issues**
|
|
291
|
+
- Fixed extra and unintended focus being applied to the options list on open.
|
|
292
|
+
----------
|
|
293
|
+
### Styling & UI
|
|
294
|
+
- **UI stability**
|
|
295
|
+
- Added `--rac-option-min-height` CSS variable to prevent layout breaking when option content is smaller than others.
|
|
296
|
+
- **Loading indication**
|
|
297
|
+
- Added `.rac-loading-option` class for styling loading items.
|
|
298
|
+
- Added `--rac-loading-option-opacity` CSS variable to control loading state transparency.
|
|
299
|
+
----------
|
|
300
|
+
### Accessibility
|
|
301
|
+
- Improved keyboard interaction consistency.
|
|
302
|
+
- Prevented non-interactive (loading) options from being focusable or selectable.
|
|
261
303
|
|
|
262
304
|
## License
|
|
263
305
|
|
package/demo/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# React + Vite
|
|
2
|
+
|
|
3
|
+
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
|
4
|
+
|
|
5
|
+
Currently, two official plugins are available:
|
|
6
|
+
|
|
7
|
+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
|
|
8
|
+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
|
9
|
+
|
|
10
|
+
## React Compiler
|
|
11
|
+
|
|
12
|
+
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
|
|
13
|
+
|
|
14
|
+
## Expanding the ESLint configuration
|
|
15
|
+
|
|
16
|
+
If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import js from '@eslint/js'
|
|
2
|
+
import globals from 'globals'
|
|
3
|
+
import reactHooks from 'eslint-plugin-react-hooks'
|
|
4
|
+
import reactRefresh from 'eslint-plugin-react-refresh'
|
|
5
|
+
import {defineConfig, globalIgnores} from 'eslint/config'
|
|
6
|
+
|
|
7
|
+
export default defineConfig([
|
|
8
|
+
globalIgnores(['dist']),
|
|
9
|
+
{
|
|
10
|
+
files: ['**/*.{js,jsx}'],
|
|
11
|
+
extends: [
|
|
12
|
+
js.configs.recommended,
|
|
13
|
+
reactHooks.configs.flat.recommended,
|
|
14
|
+
reactRefresh.configs.vite,
|
|
15
|
+
],
|
|
16
|
+
languageOptions: {
|
|
17
|
+
ecmaVersion: 2020,
|
|
18
|
+
globals: globals.browser,
|
|
19
|
+
parserOptions: {
|
|
20
|
+
ecmaVersion: 'latest',
|
|
21
|
+
ecmaFeatures: {jsx: true},
|
|
22
|
+
sourceType: 'module',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
rules: {
|
|
26
|
+
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
])
|
package/demo/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>demo</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="root"></div>
|
|
11
|
+
<script type="module" src="/src/main.jsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|