react-animated-select 0.2.8 → 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 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
+ [![Demo](https://img.shields.io/badge/demo-live_preview-brightgreen?style=for-the-badge&logo=vercel)](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 | Type | Default | Description |
105
- |------|------|---------|-------------|
106
- | `visibility` | `boolean` | `false` | Manually controls the visibility of the list (used with `ownBehavior`). |
107
- | `ownBehavior` | `boolean` | `false` | If `true`, the component stops managing its own open/close state and relies on the `visibility` prop. |
108
- | `alwaysOpen` | `boolean` | `false` | Keeps the list permanently visible. Primarily used for debugging or specific UI layouts. |
109
- | `unmount` | `boolean` | `true` | When `true`, the list is removed from the DOM when closed. When `false`, it stays invisible in the DOM. |
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.2.7
250
- #### **New Features**
251
- - **Custom Icons Support:** Added `ArrowIcon` and `ClearIcon` props. Users can now pass their own SVG components, image paths, or JSX elements to customize the interface.
252
- - **Ref Forwarding:** Implemented access to the internal ref. This enables manual focus management and integration with third-party libraries.
253
- - **Enhanced Styling:** Added `className` and `style` prop to the root `.rac-select` container for easier layout integration and style overrides.
254
- - **Animated Title Transitions:** Introduced a smooth "fade-and-slide" animation for the `title` element when the value changes.
255
-
256
- #### **Architecture & CSS**
257
- - **CSS Variable Injection:** Refactored animation parameters into CSS custom properties (`--rac-title-anim-shift`, `--rac-title-anim-entry-ease`
258
-
259
- #### **Bug Fixes**
260
- - **Opacity Animation:** Resolved an issue where the optional opacity transition for the dropdown list was not triggering correctly during the enter/exit phases.
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
+ ])
@@ -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>