react-animated-select 0.5.6 → 0.6.0

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/src/options.jsx DELETED
@@ -1,222 +0,0 @@
1
- import {CSSTransition} from 'react-transition-group'
2
- import {useRef, useState, useEffect, useCallback, memo, useLayoutEffect} from 'react'
3
- import {createPortal} from 'react-dom'
4
-
5
- function Options({
6
- visibility,
7
- children,
8
- selectRef,
9
- onAnimationDone,
10
- unmount = true,
11
- duration,
12
- easing,
13
- offset,
14
- animateOpacity,
15
- style,
16
- className
17
- }) {
18
-
19
- const nodeRef = useRef(null)
20
- const [selectHeight, setSelectHeight] = useState(0)
21
-
22
- const [coords, setCoords] = useState({top: 0, left: 0, width: 0})
23
-
24
- const coordsRef = useRef(coords)
25
-
26
- useEffect(() => {
27
- coordsRef.current = coords
28
- }, [coords])
29
-
30
- const updateCoords = useCallback(() => {
31
- if (selectRef?.current) {
32
- const rect = selectRef.current.getBoundingClientRect()
33
- const windowHeight = window.innerHeight
34
-
35
- const dropdownHeight = nodeRef.current?.scrollHeight || 250
36
-
37
- const spaceBelow = windowHeight - rect.bottom
38
- const showUpward = spaceBelow < dropdownHeight && rect.top > spaceBelow
39
-
40
- setCoords({
41
- top: rect.top,
42
- bottom: rect.bottom,
43
- left: rect.left,
44
- width: rect.width,
45
- isUpward: showUpward
46
- })
47
- }
48
- }, [selectRef])
49
-
50
- useEffect(() => {
51
- if (visibility) {
52
- updateCoords()
53
-
54
- window.addEventListener('scroll', updateCoords, true)
55
- window.addEventListener('resize', updateCoords)
56
-
57
- return () => {
58
- window.removeEventListener('scroll', updateCoords, true)
59
- window.removeEventListener('resize', updateCoords)
60
- }
61
- }
62
- }, [visibility, updateCoords])
63
-
64
- const transitionString = `height var(--rac-duration) ${easing}${animateOpacity ? `, opacity var(--rac-duration) ${easing}` : ''}`;
65
-
66
- useLayoutEffect(() => {
67
- if (!selectRef?.current) return
68
-
69
- const updateHeight = () => setSelectHeight(selectRef.current.offsetHeight)
70
- updateHeight()
71
-
72
- const resizeObserver = new ResizeObserver((entries) => {
73
- for (let entry of entries) {
74
- setSelectHeight(entry.target.offsetHeight)
75
-
76
- if (visibility && nodeRef.current && selectRef.current) {
77
- const rect = selectRef.current.getBoundingClientRect()
78
- const { isUpward } = coordsRef.current
79
-
80
- nodeRef.current.style.width = `${rect.width}px`
81
- nodeRef.current.style.left = `${rect.left}px`
82
-
83
- if (isUpward) {
84
- nodeRef.current.style.bottom = `${window.innerHeight - rect.top + offset}px`
85
- } else {
86
- nodeRef.current.style.top = `${rect.bottom + offset}px`
87
- }
88
- }
89
- }
90
- })
91
-
92
- resizeObserver.observe(selectRef.current)
93
- return () => resizeObserver.disconnect()
94
- }, [selectRef, visibility, offset])
95
-
96
- const baseStyles = {
97
- position: 'fixed',
98
- '--rac-duration': `${duration}ms`,
99
- '--rac-easing': easing,
100
- left: `${coords.left}px`,
101
- width: `${coords.width}px`,
102
- overflow: 'hidden',
103
- zIndex: '2147483647',
104
- height: visibility ? 'auto' : '0px',
105
- opacity: animateOpacity ? (visibility ? 1 : 0) : 1,
106
- pointerEvents: visibility ? 'all' : 'none',
107
- visibility: selectHeight ? 'visible' : 'hidden',
108
- boxSizing: 'border-box',
109
- transformOrigin: coords.isUpward ? 'bottom' : 'top',
110
-
111
- ...(coords.isUpward ? {
112
- bottom: `${window.innerHeight - coords.top + offset}px`,
113
- top: 'auto'
114
- } : {
115
- top: `${coords.bottom + offset}px`,
116
- bottom: 'auto'
117
- }),
118
- ...Object.fromEntries(
119
- Object.entries(style || {}).map(([key, value]) => [
120
- key.startsWith('--') ? key : `--rac-${key.replace(/([A-Z])/g, '-$1').toLowerCase()}`,
121
- value
122
- ])
123
- )
124
- }
125
-
126
- const handleEnter = useCallback(() => {
127
- const el = nodeRef.current
128
- if (!el) return
129
-
130
- el.style.height = '0px'
131
- if (animateOpacity) el.style.opacity = '0'
132
- el.style.transition = ''
133
- }, [animateOpacity])
134
-
135
- const handleEntering = useCallback(() => {
136
- const el = nodeRef.current
137
- if (!el) return
138
-
139
- el.style.transition = transitionString
140
- el.style.height = `${el.scrollHeight}px`
141
- if (animateOpacity) el.style.opacity = '1'
142
- }, [transitionString, animateOpacity])
143
-
144
- const handleEntered = useCallback(() => {
145
- const el = nodeRef.current
146
- if (!el) return
147
-
148
- el.style.height = 'auto'
149
- el.style.transition = ''
150
- if (onAnimationDone) onAnimationDone()
151
- }, [onAnimationDone])
152
-
153
- const handleExit = useCallback(() => {
154
- const el = nodeRef.current
155
- if (!el) return
156
-
157
- el.style.height = `${el.scrollHeight}px`
158
- if (animateOpacity) el.style.opacity = '1'
159
-
160
- el.offsetHeight
161
- el.style.transition = transitionString
162
- }, [transitionString, animateOpacity])
163
-
164
- const handleExiting = useCallback(() => {
165
- const el = nodeRef.current
166
- if (!el) return
167
-
168
- el.style.height = '0px'
169
- if (animateOpacity) el.style.opacity = '0'
170
- }, [animateOpacity])
171
-
172
- const handleExited = useCallback(() => {
173
- const el = nodeRef.current
174
- if (!el) return
175
- el.style.transition = ''
176
- }, [])
177
-
178
- return createPortal(
179
- <CSSTransition
180
- in={visibility}
181
- timeout={duration}
182
- classNames='rac-options'
183
- unmountOnExit={unmount}
184
- nodeRef={nodeRef}
185
- onEnter={handleEnter}
186
- onEntering={handleEntering}
187
- onEntered={handleEntered}
188
- onExit={handleExit}
189
- onExiting={handleExiting}
190
- onExited={handleExited}
191
- >
192
- <div
193
- ref={nodeRef}
194
- className={`rac-options ${className || ''}`}
195
- style={{
196
- ...baseStyles,
197
- '--rac-duration': `${duration}ms`,
198
- '--rac-duration-fast': 'calc(var(--rac-duration) * 0.5)',
199
- '--rac-duration-base': 'var(--rac-duration)',
200
- '--rac-duration-slow': 'calc(var(--rac-duration) * 1.3)',
201
-
202
- }}
203
- onMouseDown={(e) => {
204
- e.preventDefault()
205
- }}
206
- >
207
- {children}
208
- </div>
209
- </CSSTransition>, document.body
210
- )
211
- }
212
-
213
- export default memo(Options, (prev, next) => {
214
- return prev.visibility === next.visibility &&
215
- prev.duration === next.duration &&
216
- prev.easing === next.easing &&
217
- prev.offset === next.offset &&
218
- prev.animateOpacity === next.animateOpacity &&
219
- prev.selectRef === next.selectRef &&
220
- prev.children === next.children &&
221
- JSON.stringify(prev.style) === JSON.stringify(next.style)
222
- })
package/src/select.css DELETED
@@ -1,367 +0,0 @@
1
- @media (prefers-reduced-motion: reduce) {
2
- .rac-select {
3
- --rac-duration: 1ms;
4
- }
5
- }
6
-
7
- :root {
8
- --rac-base-red: #e7000b;
9
- --rac-base-green: #4caf50;
10
- --rac-base-yellow: #ffc107;
11
-
12
- --rac-select-background: color-mix(in srgb, Canvas 98%, CanvasText 2%);
13
- --rac-select-color: CanvasText;
14
- --rac-select-border: 2px solid color-mix(in srgb, Canvas 98%, CanvasText 2%);
15
- --rac-select-border-error: 2px solid color-mix(in srgb, var(--rac-base-red), CanvasText 15%);
16
- --rac-select-height: 2em;
17
- --rac-select-padding: 0em 0.5em;
18
- --rac-disabled-opacity: 0.75;
19
-
20
- --rac-title-anim-shift: 4px;
21
- --rac-title-anim-entry-ease: cubic-bezier(0.34, 1.56, 0.64, 1);
22
- --rac-title-font-size: 1em;
23
-
24
- --rac-dots-height: 3px;
25
- --rac-dots-width: 3px;
26
- --rac-dots-color: currentColor;
27
- --rac-dots-gap: 3px;
28
- --rac-dots-padding-left: 0.25em;
29
- --rac-dots-align: end;
30
- --rac-dots-animation-duration: 1.4s;
31
- --rac-dots-animation-delay-1: 0s;
32
- --rac-dots-animation-delay-2: 0.2s;
33
- --rac-dots-animation-delay-3: 0.4s;
34
-
35
- --rac-arrow-height: 1em;
36
- --rac-arrow-width: 1em;
37
- --rac-arrow-padding: 1px 0 2px;
38
-
39
- --rac-cancel-height: 0.9em;
40
- --rac-cancel-width: 0.9em;
41
-
42
- --rac-scroll-color: color-mix(in srgb, CanvasText 10%, Canvas);
43
- --rac-scroll-track: color-mix(in srgb, CanvasText 5%, Canvas);
44
- --rac-scroll-padding-top: 0.5em;
45
- --rac-scroll-padding-bottom: 0.5em;
46
-
47
- --rac-option-hover: color-mix(in srgb, CanvasText 6%, Canvas);
48
- --rac-option-highlight: color-mix(in srgb, CanvasText 10%, Canvas);
49
- --rac-option-selected: color-mix(in srgb, CanvasText 14%, Canvas);
50
-
51
- --rac-list-background: color-mix(in srgb, Canvas 98%, CanvasText 2%);
52
- --rac-list-color: CanvasText;
53
- --rac-list-max-height: 250px;
54
-
55
- --rac-option-padding: 0.5em;
56
- --rac-option-min-height: 1em;
57
- --rac-disabled-option-color: color-mix(in srgb, GrayText, CanvasText 20%);
58
- --rac-invalid-option-color: color-mix(in srgb, var(--rac-base-red), CanvasText 10%);
59
- --rac-true-option-color: color-mix(in srgb, var(--rac-base-green), CanvasText 10%);
60
- --rac-false-option-color: color-mix(in srgb, var(--rac-base-red), CanvasText 10%);
61
- --rac-warning-option-color: color-mix(in srgb, var(--rac-base-yellow), CanvasText 10%);
62
-
63
- --rac-group-header-font-size: 1.25em;
64
- --rac-group-header-font-weight: bold;
65
- --rac-group-header-min-height: 1em;
66
- --rac-group-header-padding: 0.5em;
67
- --rac-group-arrow-height: 1em;
68
- --rac-group-arrow-width: 1em;
69
- --rac-group-arrow-padding: 1px 0 2px;
70
- --rac-disabled-group-color: color-mix(in srgb, GrayText, CanvasText 20%);
71
-
72
- --rac-multiple-selected-border: 0.1em solid gray;
73
- --rac-multiple-selected-radius: 5px;
74
- --rac-checkbox-border: 1px solid gray;
75
- --rac-multiple-selected-padding: 0em 0.25em;
76
- --rac-multiple-selected-margin: 0.25em 0.25em;
77
- --rac-multiple-selected-gap: 0.5em 0;
78
- --rac-checkbox-margin-right: 0.20em;
79
- --rac-multiple-selected-min-height: 1.5em;
80
- --rac-checkbox-size: var(--rac-option-min-height);
81
-
82
- --rac-options-z-index: 1;
83
- }
84
-
85
- .rac-select {
86
- background: var(--rac-select-background);
87
- padding: var(--rac-select-padding);
88
- border: var(--rac-select-border);
89
- color: var(--rac-select-color);
90
-
91
- min-height: var(--rac-select-height);
92
- interpolate-size: allow-keywords;
93
- transition:
94
- border-color var(--rac-duration-base) ease,
95
- height var(--rac-duration-base) ease;
96
- justify-content: space-between;
97
- box-sizing: border-box;
98
- cursor: pointer;
99
- display: flex;
100
- }
101
-
102
- .rac-loading-style,
103
- .rac-disabled-style {
104
- opacity: var(--rac-disabled-opacity);
105
- transition:
106
- border-color var(--rac-duration-base),
107
- filter var(--rac-duration-base),
108
- opacity var(--rac-duration-base);
109
- cursor: wait;
110
- }
111
-
112
- .rac-disabled-style {
113
- cursor: not-allowed;
114
- }
115
-
116
- .rac-error-style {
117
- border: var(--rac-select-border-error);
118
- cursor: help;
119
- }
120
-
121
- .rac-select-title-wrapper {
122
- transition: height 300ms cubic-bezier(0.4, 0, 0.2, 1);
123
- }
124
-
125
- .rac-select-title {
126
- display: flex;
127
- align-items: center;
128
- flex-wrap: wrap;
129
- gap: var(--rac-multiple-selected-gap);
130
- }
131
-
132
- .rac-title-text {
133
- margin: 0.5em 0em;
134
- display: block;
135
- animation: rac-fade-in var(--rac-duration-base) var(--rac-title-anim-entry-ease);
136
- height: 100%;
137
- align-content: center;
138
- font-size: var(--rac-title-font-size);
139
- }
140
-
141
- @keyframes rac-fade-in {
142
- from {
143
- opacity: 0;
144
- transform: translateY(var(--rac-title-anim-shift));
145
- }
146
- to {
147
- opacity: 1;
148
- transform: translateY(0);
149
- }
150
- }
151
-
152
- .rac-loading-dots {
153
- display: inline-flex;
154
- gap: var(--rac-dots-gap);
155
- padding-left: var(--rac-dots-padding-left);
156
- align-items: var(--rac-dots-align);
157
- }
158
-
159
- .rac-loading-dots i {
160
- width: var(--rac-dots-height);
161
- height: var(--rac-dots-width);
162
- background: var(--rac-dots-color);
163
- border-radius: 50%;
164
- animation: blink var(--rac-dots-animation-duration) infinite both;
165
- }
166
-
167
- .rac-loading-dots i:nth-child(1) {animation-delay: var(--rac-dots-animation-delay-1);}
168
- .rac-loading-dots i:nth-child(2) {animation-delay: var(--rac-dots-animation-delay-2);}
169
- .rac-loading-dots i:nth-child(3) {animation-delay: var(--rac-dots-animation-delay-3);}
170
-
171
- @keyframes blink {
172
- 0% {opacity: .2;}
173
- 20% {opacity: 1;}
174
- 100% {opacity: .2;}
175
- }
176
-
177
- .rac-select-buttons {
178
- display: flex;
179
- align-items: center;
180
- }
181
-
182
- .rac-select-cancel {
183
- height: var(--rac-cancel-height);
184
- width: var(--rac-cancel-width);
185
-
186
- transition:
187
- opacity var(--rac-duration-fast),
188
- border-color var(--rac-duration-fast);
189
- }
190
-
191
- .rac-select-arrow-wrapper {
192
- display: block;
193
- height: var(--rac-arrow-height);
194
- width: var(--rac-arrow-width);
195
- padding: var(--rac-arrow-padding);
196
-
197
- will-change: transform;
198
- transition:
199
- transform var(--rac-duration-base) cubic-bezier(.4,0,.2,1),
200
- padding var(--rac-duration-fast);
201
- transform-origin: 50% 50%;
202
- transform: translateZ(0);
203
- }
204
-
205
- .rac-select-arrow-wrapper.--open {
206
- transform: rotate(180deg);
207
- }
208
-
209
- .rac-select-arrow,
210
- .rac-select-cancel {
211
- object-fit: contain;
212
- }
213
-
214
- .rac-select-list {
215
- background-color: var(--rac-list-background);
216
- color: var(--rac-list-color);
217
- max-height: var(--rac-list-max-height);
218
- overflow-y: auto;
219
- scrollbar-color: var(--rac-scroll-color) var(--rac-scroll-track);
220
- scrollbar-width: thin;
221
- scrollbar-gutter: stable;
222
- scroll-behavior: smooth;
223
- scroll-padding-top: var(--rac-scroll-padding-top);
224
- scroll-padding-bottom: var(--rac-scroll-padding-bottom);
225
- z-index: 1;
226
- transition:
227
- border-color var(--rac-duration-fast),
228
- background-color var(--rac-duration-fast),
229
- opacity var(--rac-duration-base);
230
- }
231
-
232
- .rac-select-option {
233
- transition: background-color var(--rac-duration-fast) cubic-bezier(0.4,0,0.2,1);
234
- min-height: var(--rac-option-min-height);
235
- padding: var(--rac-option-padding);
236
- justify-content: space-between;
237
- align-items: center;
238
- display: flex;
239
- cursor: pointer;
240
- }
241
-
242
- .rac-select-option:not(.rac-disabled-option):not(.rac-group-option):hover {
243
- background-color: var(--rac-option-hover);
244
- }
245
-
246
- .rac-select-option.rac-highlighted {
247
- background-color: var(--rac-option-highlight);
248
- }
249
-
250
- .rac-select-option.rac-selected {
251
- background-color: var(--rac-option-selected);
252
- }
253
-
254
- .rac-select-option.rac-selected.rac-highlighted {
255
- background-color: var(--rac-option-selected);
256
- }
257
-
258
- .rac-option-title {
259
- text-overflow: ellipsis;
260
- overflow: hidden;
261
- text-wrap: wrap;
262
- }
263
-
264
- .rac-disabled-option {
265
- cursor: not-allowed;
266
- color: var(--rac-disabled-option-color);
267
- }
268
-
269
- .rac-invalid-option {
270
- color: var(--rac-invalid-option-color);
271
- }
272
-
273
- .rac-true-option {
274
- color: var(--rac-true-option-color);
275
- }
276
-
277
- .rac-false-option {
278
- color: var(--rac-false-option-color);
279
- }
280
-
281
- .rac-loading-option {
282
- cursor: wait;
283
- }
284
-
285
- .rac-group-header {
286
- cursor: pointer;
287
- min-height: var(--rac-group-header-min-height);
288
- padding: var(--rac-group-header-padding);
289
- transition: background-color var(--rac-duration-fast) cubic-bezier(0.4,0,0.2,1);
290
- display: flex;
291
- justify-content: space-between;
292
- align-items: center;
293
- font-weight: var(--rac-group-header-font-weight);
294
- font-size: var(--rac-group-header-font-size);
295
- }
296
-
297
- .rac-group-arrow-wrapper {
298
- display: block;
299
- height: var(--rac-group-arrow-height);
300
- width: var(--rac-group-arrow-width);
301
- padding: var(--rac-group-arrow-padding);
302
-
303
- will-change: transform;
304
- transition:
305
- transform var(--rac-duration-base) cubic-bezier(.4,0,.2,1),
306
- padding var(--rac-duration-fast);
307
- transform-origin: 50% 50%;
308
- transform: translateZ(0);
309
- }
310
-
311
- .rac-group-arrow-wrapper.--open {
312
- transform: rotate(180deg);
313
- }
314
-
315
- .rac-disabled-group {
316
- cursor: not-allowed;
317
- color: var(--rac-disabled-group-color);
318
- }
319
-
320
- .rac-select-selected {
321
- display: flex;
322
- align-items: center;
323
- }
324
-
325
- .rac-multiple-selected-option {
326
- border: var(--rac-multiple-selected-border);
327
- border-radius: var(--rac-multiple-selected-radius);
328
- min-height: var(--rac-multiple-selected-min-height);
329
- transition: background-color var(--rac-duration-fast) cubic-bezier(0.4,0,0.2,1);
330
-
331
- display: inline-flex;
332
- align-items: center;
333
- vertical-align: middle;
334
- line-height: normal;
335
- padding: var(--rac-multiple-selected-padding);
336
- margin: var(--rac-multiple-selected-margin);
337
- white-space: nowrap;
338
- }
339
-
340
- .rac-multiple-selected-option:hover {
341
- background-color: color-mix(in srgb, CanvasText 6%, Canvas);
342
- }
343
-
344
- .rac-checkbox {
345
- min-height: var(--rac-option-min-height);
346
- min-width: var(--rac-option-min-height);
347
- border: var(--rac-checkbox-border);
348
- justify-content: center;
349
- align-items: center;
350
- display: flex;
351
- height: 100%;
352
- margin-right: var(--rac-checkbox-margin-right);
353
- }
354
-
355
- .rac-checkmark {
356
- color: var(--rac-base-green);
357
- opacity: 0;
358
- max-width: 0;
359
- max-height: 0;
360
- transition: opacity var(--rac-duration-base), max-height var(--rac-duration-base), max-width var(--rac-duration-base);
361
- }
362
-
363
- .rac-checkmark.--checked {
364
- opacity: 1;
365
- max-height: var(--rac-option-min-height);
366
- max-width: var(--rac-option-min-height);
367
- }