even-toolkit 1.4.2 → 1.5.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.
Files changed (75) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +7 -5
  3. package/dist/glasses/action-bar.d.ts +3 -3
  4. package/dist/glasses/action-bar.js +7 -7
  5. package/dist/glasses/action-bar.js.map +1 -1
  6. package/dist/glasses/action-map.js +3 -3
  7. package/dist/glasses/action-map.js.map +1 -1
  8. package/dist/glasses/gestures.d.ts +4 -0
  9. package/dist/glasses/gestures.d.ts.map +1 -1
  10. package/dist/glasses/gestures.js +44 -0
  11. package/dist/glasses/gestures.js.map +1 -1
  12. package/dist/glasses/glass-chat-display.d.ts +43 -0
  13. package/dist/glasses/glass-chat-display.d.ts.map +1 -0
  14. package/dist/glasses/glass-chat-display.js +102 -0
  15. package/dist/glasses/glass-chat-display.js.map +1 -0
  16. package/dist/glasses/glass-format.d.ts +50 -0
  17. package/dist/glasses/glass-format.d.ts.map +1 -0
  18. package/dist/glasses/glass-format.js +65 -0
  19. package/dist/glasses/glass-format.js.map +1 -0
  20. package/dist/glasses/index.d.ts +2 -0
  21. package/dist/glasses/index.d.ts.map +1 -1
  22. package/dist/glasses/index.js +2 -0
  23. package/dist/glasses/index.js.map +1 -1
  24. package/dist/glasses/useGlasses.js +1 -1
  25. package/dist/glasses/useGlasses.js.map +1 -1
  26. package/dist/stt/providers/deepgram.d.ts +1 -0
  27. package/dist/stt/providers/deepgram.d.ts.map +1 -1
  28. package/dist/stt/providers/deepgram.js +25 -8
  29. package/dist/stt/providers/deepgram.js.map +1 -1
  30. package/dist/web/components/dialog.d.ts.map +1 -1
  31. package/dist/web/components/dialog.js +13 -1
  32. package/dist/web/components/dialog.js.map +1 -1
  33. package/dist/web/components/drawer-shell.d.ts.map +1 -1
  34. package/dist/web/components/drawer-shell.js +11 -1
  35. package/dist/web/components/drawer-shell.js.map +1 -1
  36. package/dist/web/components/list-item.d.ts +1 -1
  37. package/dist/web/components/list-item.d.ts.map +1 -1
  38. package/dist/web/components/list-item.js +20 -5
  39. package/dist/web/components/list-item.js.map +1 -1
  40. package/dist/web/components/multi-select.d.ts +22 -0
  41. package/dist/web/components/multi-select.d.ts.map +1 -0
  42. package/dist/web/components/multi-select.js +52 -0
  43. package/dist/web/components/multi-select.js.map +1 -0
  44. package/dist/web/components/paged-carousel.d.ts +20 -0
  45. package/dist/web/components/paged-carousel.d.ts.map +1 -0
  46. package/dist/web/components/paged-carousel.js +140 -0
  47. package/dist/web/components/paged-carousel.js.map +1 -0
  48. package/dist/web/components/select.d.ts +13 -3
  49. package/dist/web/components/select.d.ts.map +1 -1
  50. package/dist/web/components/select.js +36 -3
  51. package/dist/web/components/select.js.map +1 -1
  52. package/dist/web/icons/svg-icons.js +1 -1
  53. package/dist/web/icons/svg-icons.js.map +1 -1
  54. package/dist/web/index.d.ts +4 -0
  55. package/dist/web/index.d.ts.map +1 -1
  56. package/dist/web/index.js +2 -0
  57. package/dist/web/index.js.map +1 -1
  58. package/glasses/action-bar.ts +7 -7
  59. package/glasses/action-map.ts +3 -3
  60. package/glasses/gestures.ts +50 -0
  61. package/glasses/glass-chat-display.ts +152 -0
  62. package/glasses/glass-format.ts +75 -0
  63. package/glasses/index.ts +2 -0
  64. package/glasses/useGlasses.ts +1 -1
  65. package/package.json +10 -1
  66. package/stt/providers/deepgram.ts +23 -7
  67. package/web/components/dialog.tsx +14 -3
  68. package/web/components/drawer-shell.tsx +11 -5
  69. package/web/components/list-item.tsx +25 -10
  70. package/web/components/multi-select.tsx +118 -0
  71. package/web/components/paged-carousel.tsx +201 -0
  72. package/web/components/select.tsx +90 -20
  73. package/web/icons/svg-icons.tsx +1 -2
  74. package/web/index.ts +6 -0
  75. package/web/theme/utilities.css +11 -0
@@ -0,0 +1,118 @@
1
+ import { useState, useRef, useEffect, useCallback } from 'react';
2
+ import { cn } from '../utils/cn';
3
+ import { IcStatusCheckbox, IcStatusSelectedBox } from '../icons/svg-icons';
4
+
5
+ interface MultiSelectOption {
6
+ value: string;
7
+ label: string;
8
+ }
9
+
10
+ interface MultiSelectProps {
11
+ values: string[];
12
+ options: MultiSelectOption[];
13
+ onValuesChange: (values: string[]) => void;
14
+ placeholder?: string;
15
+ className?: string;
16
+ disabled?: boolean;
17
+ }
18
+
19
+ /**
20
+ * Custom multi-select dropdown with checkboxes. No native <select>.
21
+ */
22
+ function MultiSelect({ values, options, onValuesChange, placeholder, className, disabled }: MultiSelectProps) {
23
+ const [open, setOpen] = useState(false);
24
+ const ref = useRef<HTMLDivElement>(null);
25
+
26
+ const selectedLabels = options
27
+ .filter((o) => values.includes(o.value))
28
+ .map((o) => o.label);
29
+
30
+ const displayText = selectedLabels.length > 0
31
+ ? selectedLabels.join(', ')
32
+ : placeholder ?? 'Select...';
33
+
34
+ useEffect(() => {
35
+ if (!open) return;
36
+ const handler = (e: MouseEvent) => {
37
+ if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);
38
+ };
39
+ document.addEventListener('mousedown', handler);
40
+ return () => document.removeEventListener('mousedown', handler);
41
+ }, [open]);
42
+
43
+ useEffect(() => {
44
+ if (!open) return;
45
+ const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false); };
46
+ document.addEventListener('keydown', handler);
47
+ return () => document.removeEventListener('keydown', handler);
48
+ }, [open]);
49
+
50
+ const toggleValue = useCallback((v: string) => {
51
+ if (values.includes(v)) {
52
+ onValuesChange(values.filter((x) => x !== v));
53
+ } else {
54
+ onValuesChange([...values, v]);
55
+ }
56
+ }, [values, onValuesChange]);
57
+
58
+ return (
59
+ <div ref={ref} className={cn('relative', className)} style={{ minWidth: 0 }}>
60
+ <button
61
+ type="button"
62
+ disabled={disabled}
63
+ onClick={() => !disabled && setOpen(!open)}
64
+ className={cn(
65
+ 'h-9 w-full bg-input-bg text-text rounded-[6px] pl-3 pr-8 text-[13px] tracking-[-0.13px] text-left cursor-pointer border-none flex items-center',
66
+ 'transition-colors hover:bg-surface-light',
67
+ disabled && 'opacity-50 cursor-default',
68
+ selectedLabels.length === 0 && 'text-text-dim',
69
+ )}
70
+ >
71
+ <span className="truncate flex-1">{displayText}</span>
72
+ <svg
73
+ className="absolute right-3 top-1/2 text-text-dim shrink-0"
74
+ width="10"
75
+ height="10"
76
+ viewBox="0 0 10 10"
77
+ fill="none"
78
+ style={{ transform: open ? 'translateY(-50%) rotate(180deg)' : 'translateY(-50%)', transition: 'transform 150ms ease' }}
79
+ >
80
+ <path d="M2.5 3.75L5 6.25L7.5 3.75" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
81
+ </svg>
82
+ </button>
83
+
84
+ {open && (
85
+ <div
86
+ className="absolute z-50 top-full left-0 right-0 mt-1 bg-surface rounded-[6px] border border-border overflow-hidden"
87
+ style={{ maxHeight: 200, overflowY: 'auto', boxShadow: '0 4px 12px rgba(0,0,0,0.1)' }}
88
+ >
89
+ {options.map((o) => {
90
+ const checked = values.includes(o.value);
91
+ return (
92
+ <button
93
+ key={o.value}
94
+ type="button"
95
+ className={cn(
96
+ 'w-full text-left px-3 py-2 text-[13px] tracking-[-0.13px] cursor-pointer border-none transition-colors font-normal flex items-center gap-2',
97
+ checked ? 'bg-accent/5' : 'bg-transparent hover:bg-surface-light',
98
+ )}
99
+ onClick={() => toggleValue(o.value)}
100
+ >
101
+ {checked
102
+ ? <IcStatusSelectedBox width={18} height={18} className="shrink-0" />
103
+ : <IcStatusCheckbox width={18} height={18} className="shrink-0 text-text-dim" />
104
+ }
105
+ <span className="text-text">{o.label}</span>
106
+ </button>
107
+ );
108
+ })}
109
+ </div>
110
+ )}
111
+ </div>
112
+ );
113
+ }
114
+
115
+ MultiSelect.displayName = 'MultiSelect';
116
+
117
+ export { MultiSelect };
118
+ export type { MultiSelectProps, MultiSelectOption };
@@ -0,0 +1,201 @@
1
+ import * as React from 'react';
2
+ import { cn } from '../utils/cn';
3
+
4
+ interface PagedCarouselProps {
5
+ children: React.ReactNode;
6
+ currentIndex?: number;
7
+ defaultIndex?: number;
8
+ onIndexChange?: (index: number) => void;
9
+ className?: string;
10
+ viewportClassName?: string;
11
+ trackClassName?: string;
12
+ slideClassName?: string;
13
+ allowWheel?: boolean;
14
+ allowSwipe?: boolean;
15
+ }
16
+
17
+ interface CardCarouselProps extends PagedCarouselProps {}
18
+
19
+ function useCarouselIndex(
20
+ slideCount: number,
21
+ currentIndex?: number,
22
+ defaultIndex?: number,
23
+ onIndexChange?: (index: number) => void,
24
+ ) {
25
+ const [internalIndex, setInternalIndex] = React.useState(defaultIndex ?? 0);
26
+ const controlled = typeof currentIndex === 'number';
27
+ const activeIndex = controlled ? currentIndex! : internalIndex;
28
+
29
+ const setIndex = React.useCallback((nextIndex: number) => {
30
+ if (slideCount <= 0) return;
31
+ const clamped = Math.max(0, Math.min(nextIndex, slideCount - 1));
32
+ if (!controlled) setInternalIndex(clamped);
33
+ onIndexChange?.(clamped);
34
+ }, [controlled, onIndexChange, slideCount]);
35
+
36
+ return { activeIndex, setIndex };
37
+ }
38
+
39
+ function PagedCarousel({
40
+ children,
41
+ currentIndex,
42
+ defaultIndex = 0,
43
+ onIndexChange,
44
+ className,
45
+ viewportClassName,
46
+ trackClassName,
47
+ slideClassName,
48
+ allowWheel = true,
49
+ allowSwipe = true,
50
+ }: PagedCarouselProps) {
51
+ const slides = React.Children.toArray(children);
52
+ const slideCount = slides.length;
53
+ const { activeIndex, setIndex } = useCarouselIndex(slideCount, currentIndex, defaultIndex, onIndexChange);
54
+
55
+ const touchStartRef = React.useRef<{ x: number; y: number } | null>(null);
56
+ const pointerStartRef = React.useRef<{ x: number; y: number } | null>(null);
57
+ const wheelLockRef = React.useRef(0);
58
+
59
+ const moveBy = React.useCallback((delta: number) => {
60
+ setIndex(activeIndex + delta);
61
+ }, [activeIndex, setIndex]);
62
+
63
+ const handleTouchStart = React.useCallback((event: React.TouchEvent<HTMLDivElement>) => {
64
+ if (!allowSwipe) return;
65
+ const touch = event.touches[0];
66
+ touchStartRef.current = { x: touch.clientX, y: touch.clientY };
67
+ }, [allowSwipe]);
68
+
69
+ const handleTouchMove = React.useCallback((event: React.TouchEvent<HTMLDivElement>) => {
70
+ if (!allowSwipe) return;
71
+ const start = touchStartRef.current;
72
+ const touch = event.touches[0];
73
+ if (!start || !touch) return;
74
+
75
+ const deltaX = touch.clientX - start.x;
76
+ const deltaY = touch.clientY - start.y;
77
+ if (Math.abs(deltaX) < 32 || Math.abs(deltaX) <= Math.abs(deltaY)) return;
78
+
79
+ touchStartRef.current = null;
80
+ event.preventDefault();
81
+ if (deltaX < 0) moveBy(1);
82
+ else moveBy(-1);
83
+ }, [allowSwipe, moveBy]);
84
+
85
+ const handleTouchEnd = React.useCallback((event: React.TouchEvent<HTMLDivElement>) => {
86
+ if (!allowSwipe) return;
87
+ const start = touchStartRef.current;
88
+ const touch = event.changedTouches[0];
89
+ touchStartRef.current = null;
90
+ if (!start || !touch) return;
91
+
92
+ const deltaX = touch.clientX - start.x;
93
+ const deltaY = touch.clientY - start.y;
94
+ if (Math.abs(deltaX) < 32 || Math.abs(deltaX) <= Math.abs(deltaY)) return;
95
+
96
+ if (deltaX < 0) moveBy(1);
97
+ else moveBy(-1);
98
+ }, [allowSwipe, moveBy]);
99
+
100
+ const handlePointerDown = React.useCallback((event: React.PointerEvent<HTMLDivElement>) => {
101
+ if (!allowSwipe) return;
102
+ if (event.pointerType !== 'mouse' && event.pointerType !== 'pen') return;
103
+ event.currentTarget.setPointerCapture?.(event.pointerId);
104
+ pointerStartRef.current = { x: event.clientX, y: event.clientY };
105
+ }, [allowSwipe]);
106
+
107
+ const handlePointerMove = React.useCallback((event: React.PointerEvent<HTMLDivElement>) => {
108
+ if (!allowSwipe) return;
109
+ const start = pointerStartRef.current;
110
+ if (!start) return;
111
+
112
+ const deltaX = event.clientX - start.x;
113
+ const deltaY = event.clientY - start.y;
114
+ if (Math.abs(deltaX) < 32 || Math.abs(deltaX) <= Math.abs(deltaY)) return;
115
+
116
+ pointerStartRef.current = null;
117
+ if (deltaX < 0) moveBy(1);
118
+ else moveBy(-1);
119
+ }, [allowSwipe, moveBy]);
120
+
121
+ const handlePointerUp = React.useCallback((event: React.PointerEvent<HTMLDivElement>) => {
122
+ if (!allowSwipe) return;
123
+ const start = pointerStartRef.current;
124
+ pointerStartRef.current = null;
125
+ if (!start) return;
126
+
127
+ const deltaX = event.clientX - start.x;
128
+ const deltaY = event.clientY - start.y;
129
+ if (Math.abs(deltaX) < 32 || Math.abs(deltaX) <= Math.abs(deltaY)) return;
130
+
131
+ if (deltaX < 0) moveBy(1);
132
+ else moveBy(-1);
133
+ }, [allowSwipe, moveBy]);
134
+
135
+ const handleWheel = React.useCallback((event: React.WheelEvent<HTMLDivElement>) => {
136
+ if (!allowWheel) return;
137
+ if (Math.abs(event.deltaX) < 18 || Math.abs(event.deltaX) <= Math.abs(event.deltaY)) return;
138
+
139
+ const now = Date.now();
140
+ if (now - wheelLockRef.current < 280) return;
141
+ wheelLockRef.current = now;
142
+
143
+ event.preventDefault();
144
+ if (event.deltaX > 0) moveBy(1);
145
+ else moveBy(-1);
146
+ }, [allowWheel, moveBy]);
147
+
148
+ const handleKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLDivElement>) => {
149
+ if (event.key === 'ArrowRight') {
150
+ event.preventDefault();
151
+ moveBy(1);
152
+ } else if (event.key === 'ArrowLeft') {
153
+ event.preventDefault();
154
+ moveBy(-1);
155
+ }
156
+ }, [moveBy]);
157
+
158
+ return (
159
+ <div className={cn('min-w-0', className)}>
160
+ <div
161
+ role="region"
162
+ aria-roledescription="carousel"
163
+ tabIndex={0}
164
+ onKeyDown={handleKeyDown}
165
+ onWheel={handleWheel}
166
+ onPointerDown={handlePointerDown}
167
+ onPointerMove={handlePointerMove}
168
+ onPointerUp={handlePointerUp}
169
+ onTouchStart={handleTouchStart}
170
+ onTouchMove={handleTouchMove}
171
+ onTouchEnd={handleTouchEnd}
172
+ className={cn('min-w-0 overflow-hidden outline-none', viewportClassName)}
173
+ style={{ touchAction: 'none' }}
174
+ >
175
+ <div className={cn('min-w-0', trackClassName)}>
176
+ <div
177
+ key={activeIndex}
178
+ className={cn('w-full min-w-0', slideClassName)}
179
+ aria-hidden={false}
180
+ >
181
+ {slides[activeIndex] ?? null}
182
+ </div>
183
+ </div>
184
+ </div>
185
+ </div>
186
+ );
187
+ }
188
+
189
+ function CardCarousel(props: CardCarouselProps) {
190
+ return (
191
+ <PagedCarousel
192
+ {...props}
193
+ className={cn('min-w-0', props.className)}
194
+ viewportClassName={cn('rounded-[6px]', props.viewportClassName)}
195
+ slideClassName={cn('min-w-0', props.slideClassName)}
196
+ />
197
+ );
198
+ }
199
+
200
+ export { PagedCarousel, CardCarousel };
201
+ export type { PagedCarouselProps, CardCarouselProps };
@@ -1,4 +1,4 @@
1
- import * as React from 'react';
1
+ import { useState, useRef, useEffect, useCallback } from 'react';
2
2
  import { cn } from '../utils/cn';
3
3
 
4
4
  interface SelectOption {
@@ -6,30 +6,100 @@ interface SelectOption {
6
6
  label: string;
7
7
  }
8
8
 
9
- interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'onChange'> {
9
+ interface SelectProps {
10
+ value?: string;
10
11
  options: SelectOption[];
11
12
  onValueChange?: (value: string) => void;
13
+ placeholder?: string;
14
+ className?: string;
15
+ disabled?: boolean;
16
+ dropdownPosition?: 'top' | 'bottom';
12
17
  }
13
18
 
14
- const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
15
- ({ className, options, onValueChange, ...props }, ref) => (
16
- <select
17
- ref={ref}
18
- className={cn(
19
- 'h-9 w-full bg-input-bg text-text rounded-[6px] pl-4 pr-10 text-[17px] tracking-[-0.17px] outline-none transition-colors cursor-pointer',
20
- className,
19
+ /**
20
+ * Custom dropdown no native <select>. Fully styled, no browser arrow issues.
21
+ */
22
+ function Select({ value, options, onValueChange, placeholder, className, disabled, dropdownPosition = 'bottom' }: SelectProps) {
23
+ const [open, setOpen] = useState(false);
24
+ const ref = useRef<HTMLDivElement>(null);
25
+
26
+ const selected = options.find((o) => o.value === value);
27
+ const label = selected?.label ?? placeholder ?? 'Select...';
28
+
29
+ useEffect(() => {
30
+ if (!open) return;
31
+ const handler = (e: MouseEvent) => {
32
+ if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);
33
+ };
34
+ document.addEventListener('mousedown', handler);
35
+ return () => document.removeEventListener('mousedown', handler);
36
+ }, [open]);
37
+
38
+ useEffect(() => {
39
+ if (!open) return;
40
+ const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false); };
41
+ document.addEventListener('keydown', handler);
42
+ return () => document.removeEventListener('keydown', handler);
43
+ }, [open]);
44
+
45
+ const handleSelect = useCallback((v: string) => {
46
+ onValueChange?.(v);
47
+ setOpen(false);
48
+ }, [onValueChange]);
49
+
50
+ return (
51
+ <div ref={ref} className={cn('relative', className)} style={{ minWidth: 0 }}>
52
+ <button
53
+ type="button"
54
+ disabled={disabled}
55
+ onClick={() => !disabled && setOpen(!open)}
56
+ className={cn(
57
+ 'h-9 w-full bg-input-bg text-text rounded-[6px] pl-3 pr-8 text-[13px] tracking-[-0.13px] text-left cursor-pointer border-none flex items-center',
58
+ 'transition-colors hover:bg-surface-light',
59
+ disabled && 'opacity-50 cursor-default',
60
+ )}
61
+ >
62
+ <span className="truncate flex-1">{label}</span>
63
+ <svg
64
+ className="absolute right-3 top-1/2 text-text-dim shrink-0"
65
+ width="10"
66
+ height="10"
67
+ viewBox="0 0 10 10"
68
+ fill="none"
69
+ style={{ transform: open ? 'translateY(-50%) rotate(180deg)' : 'translateY(-50%)', transition: 'transform 150ms ease' }}
70
+ >
71
+ <path d="M2.5 3.75L5 6.25L7.5 3.75" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
72
+ </svg>
73
+ </button>
74
+
75
+ {open && (
76
+ <div
77
+ className={cn(
78
+ 'absolute z-50 left-0 right-0 bg-surface rounded-[6px] border border-border overflow-hidden',
79
+ dropdownPosition === 'top' ? 'bottom-full mb-1' : 'top-full mt-1',
80
+ )}
81
+ style={{ maxHeight: 200, overflowY: 'auto', boxShadow: '0 4px 12px rgba(0,0,0,0.1)' }}
82
+ >
83
+ {options.map((o) => (
84
+ <button
85
+ key={o.value}
86
+ type="button"
87
+ className={cn(
88
+ 'w-full text-left px-3 py-2 text-[13px] tracking-[-0.13px] cursor-pointer border-none transition-colors font-normal',
89
+ o.value === value
90
+ ? 'bg-accent text-text-highlight'
91
+ : 'bg-transparent text-text hover:bg-surface-light',
92
+ )}
93
+ onClick={() => handleSelect(o.value)}
94
+ >
95
+ {o.label}
96
+ </button>
97
+ ))}
98
+ </div>
21
99
  )}
22
- onChange={(e) => onValueChange?.(e.target.value)}
23
- {...props}
24
- >
25
- {options.map((o) => (
26
- <option key={o.value} value={o.value}>
27
- {o.label}
28
- </option>
29
- ))}
30
- </select>
31
- ),
32
- );
100
+ </div>
101
+ );
102
+ }
33
103
 
34
104
  Select.displayName = 'Select';
35
105
 
@@ -486,7 +486,7 @@ export const IcFeatMessage: SvgIcon = (props) => (
486
486
  export const IcFeatNavigate: SvgIcon = (props) => (
487
487
  <svg viewBox="0 0 32 32" fill="none" {...props}>
488
488
  <g clipPath="url(#clip0_10001_76324)">
489
- <path d="M6 30H4V12H6V30ZM22 20H20V18H22V20ZM24 18H22V16H24V18ZM26 16H24V14H26V16ZM28 14H26V12H28V14ZM26 12H6V10H26V12ZM30 12H28V10H30V12ZM28 10H26V8H28V10ZM26 8H24V6H26V8ZM24 6H22V4H24V6ZM22 2V4H20V2H22Z" fill="#232323"/>
489
+ <path d="M6 30H4V12H6V30ZM22 20H20V18H22V20ZM24 18H22V16H24V18ZM26 16H24V14H26V16ZM28 14H26V12H28V14ZM26 12H6V10H26V12ZM30 12H28V10H30V12ZM28 10H26V8H28V10ZM26 8H24V6H26V8ZM24 6H22V4H24V6ZM22 2V4H20V2H22Z" fill="currentColor"/>
490
490
  </g>
491
491
  <defs>
492
492
  <clipPath id="clip0_10001_76324">
@@ -2163,4 +2163,3 @@ export const IcShare = IcEditShare;
2163
2163
  export const IcCopy = IcEditCopy;
2164
2164
  export const IcCheck = IcStatusCheckmark;
2165
2165
  export const IcMore = IcStatusMore;
2166
-
package/web/index.ts CHANGED
@@ -40,6 +40,9 @@ export type { PillProps } from './components/pill';
40
40
  export { Toggle } from './components/toggle';
41
41
  export type { ToggleProps } from './components/toggle';
42
42
 
43
+ export { MultiSelect } from './components/multi-select';
44
+ export type { MultiSelectProps, MultiSelectOption } from './components/multi-select';
45
+
43
46
  export { SegmentedControl } from './components/segmented-control';
44
47
  export type { SegmentedControlProps, SegmentedControlOption } from './components/segmented-control';
45
48
 
@@ -118,6 +121,9 @@ export type { RadioGroupProps, RadioOption } from './components/radio-group';
118
121
  export { Slider } from './components/slider';
119
122
  export type { SliderProps } from './components/slider';
120
123
 
124
+ export { PagedCarousel, CardCarousel } from './components/paged-carousel';
125
+ export type { PagedCarouselProps, CardCarouselProps } from './components/paged-carousel';
126
+
121
127
  export { Skeleton, skeletonVariants } from './components/skeleton';
122
128
  export type { SkeletonProps } from './components/skeleton';
123
129
 
@@ -23,6 +23,17 @@
23
23
  transition: stroke-dashoffset 0.5s ease;
24
24
  }
25
25
 
26
+ /* Force hide native select arrow on all browsers */
27
+ select {
28
+ -webkit-appearance: none !important;
29
+ -moz-appearance: none !important;
30
+ appearance: none !important;
31
+ background-image: none !important;
32
+ }
33
+ select::-ms-expand {
34
+ display: none;
35
+ }
36
+
26
37
  /* Bottom sheet slide-up animation */
27
38
  @keyframes slideUp {
28
39
  from { transform: translateY(100%); }