@asafarim/react-dropdowns 1.0.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/README.md ADDED
@@ -0,0 +1,396 @@
1
+ # @asafarim/react-dropdowns
2
+
3
+ Comprehensive, accessible, and mobile-first dropdown components for React with TypeScript support.
4
+
5
+ ## Features
6
+
7
+ - 🎯 **Comprehensive**: Multiple components for different use cases
8
+ - ♿ **Accessible**: Full keyboard navigation and screen reader support
9
+ - 📱 **Mobile-First**: Optimized for touch devices with responsive design
10
+ - 🎨 **Themeable**: Uses ASafariM design tokens with dark theme support
11
+ - 🔧 **TypeScript**: Full type safety and IntelliSense support
12
+ - âš¡ **Performant**: Lightweight with minimal dependencies
13
+ - 🎪 **Flexible**: Multiple placement options and customization
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @asafarim/react-dropdowns
19
+ # or
20
+ yarn add @asafarim/react-dropdowns
21
+ # or
22
+ pnpm add @asafarim/react-dropdowns
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ```tsx
28
+ import { Dropdown } from '@asafarim/react-dropdowns';
29
+ import '@asafarim/react-dropdowns/dist/dropdown.css';
30
+
31
+ function App() {
32
+ return (
33
+ <Dropdown
34
+ items={[
35
+ {
36
+ id: 'edit',
37
+ label: 'Edit',
38
+ onClick: () => console.log('Edit clicked')
39
+ },
40
+ {
41
+ id: 'delete',
42
+ label: 'Delete',
43
+ danger: true,
44
+ onClick: () => console.log('Delete clicked')
45
+ }
46
+ ]}
47
+ placement="bottom-start"
48
+ >
49
+ <button>Actions</button>
50
+ </Dropdown>
51
+ );
52
+ }
53
+ ```
54
+
55
+ ## Components
56
+
57
+ ### Dropdown
58
+
59
+ The main dropdown component that combines trigger and menu functionality.
60
+
61
+ ```tsx
62
+ <Dropdown
63
+ items={[
64
+ {
65
+ id: 'option1',
66
+ label: 'Option 1',
67
+ icon: <Icon />,
68
+ onClick: () => {},
69
+ disabled: false,
70
+ danger: false
71
+ },
72
+ { divider: true }, // Separator
73
+ {
74
+ id: 'option2',
75
+ label: 'Option 2',
76
+ onClick: () => {}
77
+ }
78
+ ]}
79
+ isOpen={isOpen}
80
+ onToggle={setIsOpen}
81
+ placement="bottom-start"
82
+ size="md"
83
+ disabled={false}
84
+ closeOnSelect={true}
85
+ >
86
+ <button>Trigger</button>
87
+ </Dropdown>
88
+ ```
89
+
90
+ ### DropdownItem
91
+
92
+ Individual menu item component.
93
+
94
+ ```tsx
95
+ <DropdownItem
96
+ label="Edit Item"
97
+ icon={<EditIcon />}
98
+ onClick={() => {}}
99
+ disabled={false}
100
+ danger={false}
101
+ />
102
+ ```
103
+
104
+ ### DropdownMenu
105
+
106
+ Standalone menu component for custom implementations.
107
+
108
+ ```tsx
109
+ <DropdownMenu
110
+ isOpen={isOpen}
111
+ position={{ top: 100, left: 50 }}
112
+ size="md"
113
+ >
114
+ <DropdownItem label="Option 1" onClick={() => {}} />
115
+ <DropdownItem label="Option 2" onClick={() => {}} />
116
+ </DropdownMenu>
117
+ ```
118
+
119
+ ## Props
120
+
121
+ ### DropdownProps
122
+
123
+ | Prop | Type | Default | Description |
124
+ |------|------|---------|-------------|
125
+ | `children` | `ReactNode` | - | Trigger element |
126
+ | `items` | `DropdownItemData[]` | `[]` | Menu items |
127
+ | `isOpen` | `boolean` | - | Controlled open state |
128
+ | `onToggle` | `(isOpen: boolean) => void` | - | Open state change handler |
129
+ | `placement` | `DropdownPlacement` | `'bottom-start'` | Menu position |
130
+ | `size` | `DropdownSize` | `'md'` | Menu size |
131
+ | `disabled` | `boolean` | `false` | Disable the dropdown |
132
+ | `closeOnSelect` | `boolean` | `true` | Close menu on item select |
133
+
134
+ ### DropdownItemData
135
+
136
+ | Prop | Type | Default | Description |
137
+ |------|------|---------|-------------|
138
+ | `id` | `string` | - | Unique identifier |
139
+ | `label` | `string` | - | Item text |
140
+ | `value` | `string` | - | Item value |
141
+ | `icon` | `ReactNode` | - | Item icon |
142
+ | `disabled` | `boolean` | `false` | Disable the item |
143
+ | `danger` | `boolean` | `false` | Danger styling |
144
+ | `divider` | `boolean` | `false` | Render as divider |
145
+ | `onClick` | `(event: MouseEvent) => void` | - | Click handler |
146
+
147
+ ## Placement Options
148
+
149
+ The dropdown supports 12 different placement options:
150
+
151
+ - `top`, `top-start`, `top-end`
152
+ - `bottom`, `bottom-start`, `bottom-end`
153
+ - `left`, `left-start`, `left-end`
154
+ - `right`, `right-start`, `right-end`
155
+
156
+ ## Size Options
157
+
158
+ Three size variants are available:
159
+
160
+ - `sm` - Compact size for tight spaces
161
+ - `md` - Default size for most use cases
162
+ - `lg` - Large size for better touch targets
163
+
164
+ ## Hooks
165
+
166
+ ### useDropdown
167
+
168
+ Custom hook for building dropdown functionality:
169
+
170
+ ```tsx
171
+ import { useDropdown } from '@asafarim/react-dropdowns';
172
+
173
+ const {
174
+ isOpen,
175
+ position,
176
+ triggerRef,
177
+ menuRef,
178
+ toggle,
179
+ open,
180
+ close,
181
+ handleItemClick
182
+ } = useDropdown({
183
+ placement: 'bottom-start',
184
+ offset: 8,
185
+ closeOnSelect: true
186
+ });
187
+ ```
188
+
189
+ ### useClickOutside
190
+
191
+ Hook for detecting clicks outside an element:
192
+
193
+ ```tsx
194
+ import { useClickOutside } from '@asafarim/react-dropdowns';
195
+
196
+ useClickOutside({
197
+ ref: elementRef,
198
+ handler: () => setIsOpen(false),
199
+ enabled: isOpen
200
+ });
201
+ ```
202
+
203
+ ### useKeyboardNavigation
204
+
205
+ Hook for keyboard navigation support:
206
+
207
+ ```tsx
208
+ import { useKeyboardNavigation } from '@asafarim/react-dropdowns';
209
+
210
+ useKeyboardNavigation({
211
+ isOpen,
212
+ menuRef,
213
+ onClose: () => setIsOpen(false),
214
+ onSelect: (index) => selectItem(index)
215
+ });
216
+ ```
217
+
218
+ ## Styling
219
+
220
+ The components use CSS custom properties (CSS variables) from the ASafariM design token system. Import the CSS file:
221
+
222
+ ```tsx
223
+ import '@asafarim/react-dropdowns/dist/dropdown.css';
224
+ ```
225
+
226
+ ### Custom Styling
227
+
228
+ You can override the default styles by targeting the CSS classes:
229
+
230
+ ```css
231
+ .asm-dropdown-menu {
232
+ /* Custom menu styles */
233
+ }
234
+
235
+ .asm-dropdown-item {
236
+ /* Custom item styles */
237
+ }
238
+
239
+ .asm-dropdown-item--danger {
240
+ /* Custom danger item styles */
241
+ }
242
+ ```
243
+
244
+ ## Accessibility
245
+
246
+ The dropdown components are built with accessibility in mind:
247
+
248
+ - **Keyboard Navigation**: Arrow keys, Enter, Escape, Home, End
249
+ - **Screen Reader Support**: Proper ARIA attributes and roles
250
+ - **Focus Management**: Automatic focus handling and restoration
251
+ - **High Contrast**: Support for high contrast mode
252
+ - **Reduced Motion**: Respects user's motion preferences
253
+
254
+ ### Keyboard Shortcuts
255
+
256
+ | Key | Action |
257
+ |-----|--------|
258
+ | `Space` / `Enter` | Open/close dropdown or select item |
259
+ | `Arrow Down` | Navigate to next item or open dropdown |
260
+ | `Arrow Up` | Navigate to previous item |
261
+ | `Home` | Navigate to first item |
262
+ | `End` | Navigate to last item |
263
+ | `Escape` | Close dropdown |
264
+ | `Tab` | Close dropdown and move to next element |
265
+
266
+ ## Examples
267
+
268
+ ### Basic Menu
269
+
270
+ ```tsx
271
+ <Dropdown
272
+ items={[
273
+ { id: 'new', label: 'New', onClick: () => {} },
274
+ { id: 'edit', label: 'Edit', onClick: () => {} },
275
+ { divider: true },
276
+ { id: 'delete', label: 'Delete', danger: true, onClick: () => {} }
277
+ ]}
278
+ >
279
+ <button>File</button>
280
+ </Dropdown>
281
+ ```
282
+
283
+ ### User Menu
284
+
285
+ ```tsx
286
+ <Dropdown
287
+ items={[
288
+ {
289
+ id: 'profile',
290
+ label: 'Profile',
291
+ icon: <UserIcon />,
292
+ onClick: () => navigate('/profile')
293
+ },
294
+ {
295
+ id: 'settings',
296
+ label: 'Settings',
297
+ icon: <SettingsIcon />,
298
+ onClick: () => navigate('/settings')
299
+ },
300
+ { divider: true },
301
+ {
302
+ id: 'logout',
303
+ label: 'Logout',
304
+ icon: <LogoutIcon />,
305
+ danger: true,
306
+ onClick: handleLogout
307
+ }
308
+ ]}
309
+ placement="bottom-end"
310
+ >
311
+ <img src={user.avatar} alt={user.name} />
312
+ </Dropdown>
313
+ ```
314
+
315
+ ### Filter Dropdown
316
+
317
+ ```tsx
318
+ const [filter, setFilter] = useState('all');
319
+
320
+ <Dropdown
321
+ items={[
322
+ {
323
+ id: 'all',
324
+ label: 'All Items',
325
+ icon: filter === 'all' ? <CheckIcon /> : undefined,
326
+ onClick: () => setFilter('all')
327
+ },
328
+ {
329
+ id: 'active',
330
+ label: 'Active Only',
331
+ icon: filter === 'active' ? <CheckIcon /> : undefined,
332
+ onClick: () => setFilter('active')
333
+ },
334
+ {
335
+ id: 'archived',
336
+ label: 'Archived',
337
+ icon: filter === 'archived' ? <CheckIcon /> : undefined,
338
+ onClick: () => setFilter('archived')
339
+ }
340
+ ]}
341
+ >
342
+ <button>
343
+ <FilterIcon />
344
+ Filter: {filter}
345
+ <ChevronDownIcon />
346
+ </button>
347
+ </Dropdown>
348
+ ```
349
+
350
+ ## Demo
351
+
352
+ Run the demo application to see all features in action:
353
+
354
+ ```bash
355
+ cd packages/react-dropdowns/demo
356
+ npm install
357
+ npm start
358
+ ```
359
+
360
+ The demo showcases:
361
+ - Basic usage examples
362
+ - All placement options
363
+ - Interactive examples (filters, user selectors)
364
+ - Different sizes and states
365
+ - Mobile optimizations
366
+ - Dark theme support
367
+
368
+ ## Browser Support
369
+
370
+ - Chrome 88+
371
+ - Firefox 78+
372
+ - Safari 14+
373
+ - Edge 88+
374
+
375
+ ## Contributing
376
+
377
+ 1. Fork the repository
378
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
379
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
380
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
381
+ 5. Open a Pull Request
382
+
383
+ ## License
384
+
385
+ MIT © ASafariM
386
+
387
+ ## Changelog
388
+
389
+ ### 1.0.0
390
+
391
+ - Initial release
392
+ - Comprehensive dropdown components
393
+ - Mobile-first responsive design
394
+ - Full accessibility support
395
+ - TypeScript support
396
+ - ASafariM design token integration
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { DropdownProps } from '../types';
3
+ export declare const Dropdown: React.FC<DropdownProps>;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { DropdownItemProps } from '../types';
3
+ export declare const DropdownItem: React.FC<DropdownItemProps>;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { DropdownMenuProps } from '../types';
3
+ export declare const DropdownMenu: React.ForwardRefExoticComponent<DropdownMenuProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { DropdownTriggerProps } from '../types';
3
+ export declare const DropdownTrigger: React.ForwardRefExoticComponent<DropdownTriggerProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,8 @@
1
+ import { RefObject } from 'react';
2
+ interface UseClickOutsideProps {
3
+ ref: RefObject<HTMLDivElement>;
4
+ handler: () => void;
5
+ enabled?: boolean;
6
+ }
7
+ export declare const useClickOutside: ({ ref, handler, enabled }: UseClickOutsideProps) => void;
8
+ export {};
@@ -0,0 +1,17 @@
1
+ import { DropdownPlacement, DropdownPosition } from '../types';
2
+ interface UseDropdownProps {
3
+ placement?: DropdownPlacement;
4
+ offset?: number;
5
+ closeOnSelect?: boolean;
6
+ }
7
+ export declare const useDropdown: ({ placement, offset, closeOnSelect }?: UseDropdownProps) => {
8
+ isOpen: boolean;
9
+ position: DropdownPosition;
10
+ triggerRef: import("react").RefObject<HTMLDivElement>;
11
+ menuRef: import("react").RefObject<HTMLDivElement>;
12
+ toggle: () => void;
13
+ open: () => void;
14
+ close: () => void;
15
+ handleItemClick: () => void;
16
+ };
17
+ export {};
@@ -0,0 +1,9 @@
1
+ import { RefObject } from 'react';
2
+ interface UseKeyboardNavigationProps {
3
+ isOpen: boolean;
4
+ menuRef: RefObject<HTMLElement>;
5
+ onClose: () => void;
6
+ onSelect?: (index: number) => void;
7
+ }
8
+ export declare const useKeyboardNavigation: ({ isOpen, menuRef, onClose, onSelect }: UseKeyboardNavigationProps) => void;
9
+ export {};
package/dist/index.css ADDED
@@ -0,0 +1 @@
1
+ .dropdown_asm-dropdown__h1OJq{display:inline-block;position:relative}.dropdown_asm-dropdown-trigger__NJPo2{align-items:center;background:none;border:none;cursor:pointer;display:inline-flex;justify-content:center;margin:0;padding:0}.dropdown_asm-dropdown-trigger__NJPo2:disabled{cursor:not-allowed;opacity:.6}.dropdown_asm-dropdown-trigger__NJPo2:focus-visible{border-radius:var(--asm-radius-sm);outline:2px solid var(--asm-color-primary-500);outline-offset:2px}.dropdown_asm-dropdown-menu__YMlWB{animation:dropdown_asm-dropdown-enter__rh5Tw .15s ease-out;background-color:var(--asm-color-surface);border:1px solid var(--asm-color-border);border-radius:var(--asm-radius-lg);box-shadow:var(--asm-effect-shadow-lg);max-height:400px;max-width:320px;min-width:160px;overflow-y:auto;padding:var(--asm-space-1);transform-origin:top;z-index:var(--asm-z-dropdown)}@keyframes dropdown_asm-dropdown-enter__rh5Tw{0%{opacity:0;transform:scale(.95) translateY(-8px)}to{opacity:1;transform:scale(1) translateY(0)}}.dropdown_asm-dropdown-menu--sm__jecEV{min-width:120px;padding:var(--asm-space-0-5)}.dropdown_asm-dropdown-menu--md__X4BwH{min-width:160px;padding:var(--asm-space-1)}.dropdown_asm-dropdown-menu--lg__BQ3dL{min-width:200px;padding:var(--asm-space-1-5)}.dropdown_asm-dropdown-item__8UHDs{align-items:center;background:transparent;border:none;border-radius:var(--asm-radius-md);color:var(--asm-color-text);cursor:pointer;display:flex;font-size:var(--asm-font-size-sm);font-weight:var(--asm-font-weight-400);gap:var(--asm-space-2);min-height:36px;padding:var(--asm-space-2) var(--asm-space-3);text-align:left;transition:var(--asm-transition-fade);width:100%}.dropdown_asm-dropdown-item__8UHDs:focus,.dropdown_asm-dropdown-item__8UHDs:hover:not(:disabled){background-color:var(--asm-color-button-ghost-bg-hover);color:var(--asm-color-text)}.dropdown_asm-dropdown-item__8UHDs:focus{outline:none}.dropdown_asm-dropdown-item__8UHDs:active:not(:disabled){background-color:var(--asm-color-button-ghost-bg-hover)}.dropdown_asm-dropdown-item--disabled__FiaRm{color:var(--asm-color-text-muted);cursor:not-allowed;opacity:.6}.dropdown_asm-dropdown-item--danger__8yZZC{color:var(--asm-color-danger-600)}.dropdown_asm-dropdown-item--danger__8yZZC:focus,.dropdown_asm-dropdown-item--danger__8yZZC:hover:not(:disabled){background-color:var(--asm-color-danger-50);color:var(--asm-color-danger-700)}.dropdown_asm-dropdown-item__icon__r1aA0{align-items:center;display:flex;flex-shrink:0;height:16px;justify-content:center;width:16px}.dropdown_asm-dropdown-item__label__UVmKu{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dropdown_asm-dropdown-divider__JN-Gh{background-color:var(--asm-color-border);height:1px;margin:var(--asm-space-1) 0}[data-theme=dark] .dropdown_asm-dropdown-menu__YMlWB{background-color:var(--asm-color-surface);border-color:var(--asm-color-border);box-shadow:var(--asm-effect-shadow-lg)}[data-theme=dark] .dropdown_asm-dropdown-item__8UHDs{color:var(--asm-color-text)}[data-theme=dark] .dropdown_asm-dropdown-item__8UHDs:hover:not(:disabled){background-color:var(--asm-color-button-ghost-bg-hover)}[data-theme=dark] .dropdown_asm-dropdown-item--danger__8yZZC{color:var(--asm-color-danger-400)}[data-theme=dark] .dropdown_asm-dropdown-item--danger__8yZZC:hover:not(:disabled){background-color:var(--asm-color-danger-900);color:var(--asm-color-danger-300)}@media (max-width:640px){.dropdown_asm-dropdown-menu__YMlWB{max-height:60vh;max-width:calc(100vw - 32px);min-width:200px}.dropdown_asm-dropdown-item__8UHDs{font-size:var(--asm-font-size-md);min-height:44px;padding:var(--asm-space-3) var(--asm-space-4)}.dropdown_asm-dropdown-item__icon__r1aA0{height:20px;width:20px}}@media (hover:none) and (pointer:coarse){.dropdown_asm-dropdown-item__8UHDs{min-height:44px;padding:var(--asm-space-3) var(--asm-space-4)}}@media (prefers-reduced-motion:reduce){.dropdown_asm-dropdown-menu__YMlWB{animation:none}.dropdown_asm-dropdown-item__8UHDs{transition:none}}@media (prefers-contrast:high){.dropdown_asm-dropdown-menu__YMlWB{border-width:2px}.dropdown_asm-dropdown-item__8UHDs:focus{outline:2px solid currentColor;outline-offset:-2px}}@import "@asafarim/design-tokens/css/index.css";.DropdownTrigger-module_trigger__2aFGL{align-items:center;border:none;border-radius:var(--asm-radius-md);cursor:pointer;display:inline-flex;font-family:var(--asm-font-family-primary);font-size:var(--asm-font-size-md);font-weight:var(--asm-font-weight-500);gap:var(--asm-space-2);justify-content:center;transition:all var(--asm-motion-duration-normal) var(--asm-motion-easing-standard);white-space:nowrap}.DropdownTrigger-module_trigger__2aFGL:disabled{cursor:not-allowed;opacity:.6}.DropdownTrigger-module_trigger__2aFGL:focus-visible{outline:2px solid var(--asm-color-focus-ring);outline-offset:2px}.DropdownTrigger-module_sm__J-u1E{font-size:var(--asm-font-size-sm);padding:calc(var(--asm-space-control-padding-y)*.75) calc(var(--asm-space-control-padding-x)*.75)}.DropdownTrigger-module_md__9rX9v{font-size:var(--asm-font-size-md);padding:var(--asm-space-control-padding-y) var(--asm-space-control-padding-x)}.DropdownTrigger-module_lg__Q-JAS{font-size:var(--asm-font-size-lg);padding:calc(var(--asm-space-control-padding-y)*1.25) calc(var(--asm-space-control-padding-x)*1.25)}.DropdownTrigger-module_primary__UQ1Xa{background-color:var(--asm-color-button-primary-bg);border:1px solid transparent;color:var(--asm-color-button-primary-text)}.DropdownTrigger-module_primary__UQ1Xa:hover:not(:disabled){background-color:var(--asm-color-button-primary-bg-hover)}.DropdownTrigger-module_primary__UQ1Xa:active:not(:disabled){background-color:var(--asm-color-button-primary-bg-active)}.DropdownTrigger-module_secondary__1NNLR{background-color:var(--asm-color-button-secondary-bg);border:1px solid var(--asm-color-border);color:var(--asm-color-button-secondary-text)}.DropdownTrigger-module_secondary__1NNLR:hover:not(:disabled){background-color:var(--asm-color-surface-muted);border-color:var(--asm-color-text)}.DropdownTrigger-module_secondary__1NNLR:active:not(:disabled){background-color:var(--asm-color-surface-muted)}.DropdownTrigger-module_success__bHgUD{background-color:var(--asm-color-success-400);border:1px solid transparent;color:#fff}.DropdownTrigger-module_success__bHgUD:hover:not(:disabled){background-color:var(--asm-color-success-500)}.DropdownTrigger-module_success__bHgUD:active:not(:disabled){background-color:var(--asm-color-success-600)}.DropdownTrigger-module_warning__ifDRF{background-color:var(--asm-color-warning-400);border:1px solid transparent;color:#fff}.DropdownTrigger-module_warning__ifDRF:hover:not(:disabled){background-color:var(--asm-color-warning-500)}.DropdownTrigger-module_warning__ifDRF:active:not(:disabled){background-color:var(--asm-color-warning-600)}.DropdownTrigger-module_danger__v-d7N{background-color:var(--asm-color-button-destructive-bg);border:1px solid transparent;color:var(--asm-color-button-destructive-text)}.DropdownTrigger-module_danger__v-d7N:hover:not(:disabled){background-color:var(--asm-color-danger-500)}.DropdownTrigger-module_danger__v-d7N:active:not(:disabled){background-color:var(--asm-color-danger-600)}.DropdownTrigger-module_info__3czXi{background-color:var(--asm-color-info-400);border:1px solid transparent;color:#fff}.DropdownTrigger-module_info__3czXi:hover:not(:disabled){background-color:var(--asm-color-info-500)}.DropdownTrigger-module_info__3czXi:active:not(:disabled){background-color:var(--asm-color-info-600)}.DropdownTrigger-module_ghost__dbCKD{background-color:transparent;border:1px solid transparent;color:var(--asm-color-text)}.DropdownTrigger-module_ghost__dbCKD:active:not(:disabled),.DropdownTrigger-module_ghost__dbCKD:hover:not(:disabled){background-color:var(--asm-color-button-ghost-bg-hover)}.DropdownTrigger-module_outline__VnDA7{background-color:transparent;border:1px solid var(--asm-color-border);color:var(--asm-color-text)}.DropdownTrigger-module_outline__VnDA7:hover:not(:disabled){background-color:var(--asm-color-surface-muted);border-color:var(--asm-color-text)}.DropdownTrigger-module_outline__VnDA7:active:not(:disabled){background-color:var(--asm-color-surface-muted)}.DropdownTrigger-module_link__BWU0o{background-color:transparent;border:none;color:var(--asm-color-primary-500);padding:0;text-decoration:none}.DropdownTrigger-module_link__BWU0o:hover:not(:disabled){color:var(--asm-color-primary-600);text-decoration:underline}.DropdownTrigger-module_link__BWU0o:active:not(:disabled){color:var(--asm-color-primary-700)}.DropdownTrigger-module_brand__SAI0y{background-color:var(--asm-color-brand-primary-500);border:1px solid transparent;color:#fff}.DropdownTrigger-module_brand__SAI0y:hover:not(:disabled){background-color:var(--asm-color-brand-primary-600)}.DropdownTrigger-module_brand__SAI0y:active:not(:disabled){background-color:var(--asm-color-brand-primary-700)}.DropdownTrigger-module_trigger__2aFGL:disabled{background-color:var(--asm-color-button-disabled-bg);border-color:transparent;color:var(--asm-color-button-disabled-text)}
@@ -0,0 +1,9 @@
1
+ import './styles/dropdown.css';
2
+ export { Dropdown } from './components/Dropdown';
3
+ export { DropdownItem } from './components/DropdownItem';
4
+ export { DropdownMenu } from './components/DropdownMenu';
5
+ export { DropdownTrigger } from './components/DropdownTrigger';
6
+ export { useDropdown } from './hooks/useDropdown';
7
+ export { useClickOutside } from './hooks/useClickOutside';
8
+ export { useKeyboardNavigation } from './hooks/useKeyboardNavigation';
9
+ export type { DropdownProps, DropdownItemProps, DropdownMenuProps, DropdownTriggerProps, DropdownPosition, DropdownPlacement, DropdownSize, DropdownVariant, DropdownItemData } from './types';
@@ -0,0 +1 @@
1
+ .dropdown_asm-dropdown__h1OJq{display:inline-block;position:relative}.dropdown_asm-dropdown-trigger__NJPo2{align-items:center;background:none;border:none;cursor:pointer;display:inline-flex;justify-content:center;margin:0;padding:0}.dropdown_asm-dropdown-trigger__NJPo2:disabled{cursor:not-allowed;opacity:.6}.dropdown_asm-dropdown-trigger__NJPo2:focus-visible{border-radius:var(--asm-radius-sm);outline:2px solid var(--asm-color-primary-500);outline-offset:2px}.dropdown_asm-dropdown-menu__YMlWB{animation:dropdown_asm-dropdown-enter__rh5Tw .15s ease-out;background-color:var(--asm-color-surface);border:1px solid var(--asm-color-border);border-radius:var(--asm-radius-lg);box-shadow:var(--asm-effect-shadow-lg);max-height:400px;max-width:320px;min-width:160px;overflow-y:auto;padding:var(--asm-space-1);transform-origin:top;z-index:var(--asm-z-dropdown)}@keyframes dropdown_asm-dropdown-enter__rh5Tw{0%{opacity:0;transform:scale(.95) translateY(-8px)}to{opacity:1;transform:scale(1) translateY(0)}}.dropdown_asm-dropdown-menu--sm__jecEV{min-width:120px;padding:var(--asm-space-0-5)}.dropdown_asm-dropdown-menu--md__X4BwH{min-width:160px;padding:var(--asm-space-1)}.dropdown_asm-dropdown-menu--lg__BQ3dL{min-width:200px;padding:var(--asm-space-1-5)}.dropdown_asm-dropdown-item__8UHDs{align-items:center;background:transparent;border:none;border-radius:var(--asm-radius-md);color:var(--asm-color-text);cursor:pointer;display:flex;font-size:var(--asm-font-size-sm);font-weight:var(--asm-font-weight-400);gap:var(--asm-space-2);min-height:36px;padding:var(--asm-space-2) var(--asm-space-3);text-align:left;transition:var(--asm-transition-fade);width:100%}.dropdown_asm-dropdown-item__8UHDs:focus,.dropdown_asm-dropdown-item__8UHDs:hover:not(:disabled){background-color:var(--asm-color-button-ghost-bg-hover);color:var(--asm-color-text)}.dropdown_asm-dropdown-item__8UHDs:focus{outline:none}.dropdown_asm-dropdown-item__8UHDs:active:not(:disabled){background-color:var(--asm-color-button-ghost-bg-hover)}.dropdown_asm-dropdown-item--disabled__FiaRm{color:var(--asm-color-text-muted);cursor:not-allowed;opacity:.6}.dropdown_asm-dropdown-item--danger__8yZZC{color:var(--asm-color-danger-600)}.dropdown_asm-dropdown-item--danger__8yZZC:focus,.dropdown_asm-dropdown-item--danger__8yZZC:hover:not(:disabled){background-color:var(--asm-color-danger-50);color:var(--asm-color-danger-700)}.dropdown_asm-dropdown-item__icon__r1aA0{align-items:center;display:flex;flex-shrink:0;height:16px;justify-content:center;width:16px}.dropdown_asm-dropdown-item__label__UVmKu{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dropdown_asm-dropdown-divider__JN-Gh{background-color:var(--asm-color-border);height:1px;margin:var(--asm-space-1) 0}[data-theme=dark] .dropdown_asm-dropdown-menu__YMlWB{background-color:var(--asm-color-surface);border-color:var(--asm-color-border);box-shadow:var(--asm-effect-shadow-lg)}[data-theme=dark] .dropdown_asm-dropdown-item__8UHDs{color:var(--asm-color-text)}[data-theme=dark] .dropdown_asm-dropdown-item__8UHDs:hover:not(:disabled){background-color:var(--asm-color-button-ghost-bg-hover)}[data-theme=dark] .dropdown_asm-dropdown-item--danger__8yZZC{color:var(--asm-color-danger-400)}[data-theme=dark] .dropdown_asm-dropdown-item--danger__8yZZC:hover:not(:disabled){background-color:var(--asm-color-danger-900);color:var(--asm-color-danger-300)}@media (max-width:640px){.dropdown_asm-dropdown-menu__YMlWB{max-height:60vh;max-width:calc(100vw - 32px);min-width:200px}.dropdown_asm-dropdown-item__8UHDs{font-size:var(--asm-font-size-md);min-height:44px;padding:var(--asm-space-3) var(--asm-space-4)}.dropdown_asm-dropdown-item__icon__r1aA0{height:20px;width:20px}}@media (hover:none) and (pointer:coarse){.dropdown_asm-dropdown-item__8UHDs{min-height:44px;padding:var(--asm-space-3) var(--asm-space-4)}}@media (prefers-reduced-motion:reduce){.dropdown_asm-dropdown-menu__YMlWB{animation:none}.dropdown_asm-dropdown-item__8UHDs{transition:none}}@media (prefers-contrast:high){.dropdown_asm-dropdown-menu__YMlWB{border-width:2px}.dropdown_asm-dropdown-item__8UHDs:focus{outline:2px solid currentColor;outline-offset:-2px}}@import "@asafarim/design-tokens/css/index.css";.DropdownTrigger-module_trigger__2aFGL{align-items:center;border:none;border-radius:var(--asm-radius-md);cursor:pointer;display:inline-flex;font-family:var(--asm-font-family-primary);font-size:var(--asm-font-size-md);font-weight:var(--asm-font-weight-500);gap:var(--asm-space-2);justify-content:center;transition:all var(--asm-motion-duration-normal) var(--asm-motion-easing-standard);white-space:nowrap}.DropdownTrigger-module_trigger__2aFGL:disabled{cursor:not-allowed;opacity:.6}.DropdownTrigger-module_trigger__2aFGL:focus-visible{outline:2px solid var(--asm-color-focus-ring);outline-offset:2px}.DropdownTrigger-module_sm__J-u1E{font-size:var(--asm-font-size-sm);padding:calc(var(--asm-space-control-padding-y)*.75) calc(var(--asm-space-control-padding-x)*.75)}.DropdownTrigger-module_md__9rX9v{font-size:var(--asm-font-size-md);padding:var(--asm-space-control-padding-y) var(--asm-space-control-padding-x)}.DropdownTrigger-module_lg__Q-JAS{font-size:var(--asm-font-size-lg);padding:calc(var(--asm-space-control-padding-y)*1.25) calc(var(--asm-space-control-padding-x)*1.25)}.DropdownTrigger-module_primary__UQ1Xa{background-color:var(--asm-color-button-primary-bg);border:1px solid transparent;color:var(--asm-color-button-primary-text)}.DropdownTrigger-module_primary__UQ1Xa:hover:not(:disabled){background-color:var(--asm-color-button-primary-bg-hover)}.DropdownTrigger-module_primary__UQ1Xa:active:not(:disabled){background-color:var(--asm-color-button-primary-bg-active)}.DropdownTrigger-module_secondary__1NNLR{background-color:var(--asm-color-button-secondary-bg);border:1px solid var(--asm-color-border);color:var(--asm-color-button-secondary-text)}.DropdownTrigger-module_secondary__1NNLR:hover:not(:disabled){background-color:var(--asm-color-surface-muted);border-color:var(--asm-color-text)}.DropdownTrigger-module_secondary__1NNLR:active:not(:disabled){background-color:var(--asm-color-surface-muted)}.DropdownTrigger-module_success__bHgUD{background-color:var(--asm-color-success-400);border:1px solid transparent;color:#fff}.DropdownTrigger-module_success__bHgUD:hover:not(:disabled){background-color:var(--asm-color-success-500)}.DropdownTrigger-module_success__bHgUD:active:not(:disabled){background-color:var(--asm-color-success-600)}.DropdownTrigger-module_warning__ifDRF{background-color:var(--asm-color-warning-400);border:1px solid transparent;color:#fff}.DropdownTrigger-module_warning__ifDRF:hover:not(:disabled){background-color:var(--asm-color-warning-500)}.DropdownTrigger-module_warning__ifDRF:active:not(:disabled){background-color:var(--asm-color-warning-600)}.DropdownTrigger-module_danger__v-d7N{background-color:var(--asm-color-button-destructive-bg);border:1px solid transparent;color:var(--asm-color-button-destructive-text)}.DropdownTrigger-module_danger__v-d7N:hover:not(:disabled){background-color:var(--asm-color-danger-500)}.DropdownTrigger-module_danger__v-d7N:active:not(:disabled){background-color:var(--asm-color-danger-600)}.DropdownTrigger-module_info__3czXi{background-color:var(--asm-color-info-400);border:1px solid transparent;color:#fff}.DropdownTrigger-module_info__3czXi:hover:not(:disabled){background-color:var(--asm-color-info-500)}.DropdownTrigger-module_info__3czXi:active:not(:disabled){background-color:var(--asm-color-info-600)}.DropdownTrigger-module_ghost__dbCKD{background-color:transparent;border:1px solid transparent;color:var(--asm-color-text)}.DropdownTrigger-module_ghost__dbCKD:active:not(:disabled),.DropdownTrigger-module_ghost__dbCKD:hover:not(:disabled){background-color:var(--asm-color-button-ghost-bg-hover)}.DropdownTrigger-module_outline__VnDA7{background-color:transparent;border:1px solid var(--asm-color-border);color:var(--asm-color-text)}.DropdownTrigger-module_outline__VnDA7:hover:not(:disabled){background-color:var(--asm-color-surface-muted);border-color:var(--asm-color-text)}.DropdownTrigger-module_outline__VnDA7:active:not(:disabled){background-color:var(--asm-color-surface-muted)}.DropdownTrigger-module_link__BWU0o{background-color:transparent;border:none;color:var(--asm-color-primary-500);padding:0;text-decoration:none}.DropdownTrigger-module_link__BWU0o:hover:not(:disabled){color:var(--asm-color-primary-600);text-decoration:underline}.DropdownTrigger-module_link__BWU0o:active:not(:disabled){color:var(--asm-color-primary-700)}.DropdownTrigger-module_brand__SAI0y{background-color:var(--asm-color-brand-primary-500);border:1px solid transparent;color:#fff}.DropdownTrigger-module_brand__SAI0y:hover:not(:disabled){background-color:var(--asm-color-brand-primary-600)}.DropdownTrigger-module_brand__SAI0y:active:not(:disabled){background-color:var(--asm-color-brand-primary-700)}.DropdownTrigger-module_trigger__2aFGL:disabled{background-color:var(--asm-color-button-disabled-bg);border-color:transparent;color:var(--asm-color-button-disabled-text)}