@moontra/moonui 3.3.0 → 4.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/dist/index.d.mts +25 -7
- package/dist/index.d.ts +25 -7
- package/dist/index.global.js +20 -20
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +503 -353
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +467 -318
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/ui/__tests__/alert.test.tsx +5 -5
- package/src/components/ui/__tests__/avatar.test.tsx +12 -12
- package/src/components/ui/__tests__/badge.test.tsx +17 -1
- package/src/components/ui/__tests__/checkbox.test.tsx +16 -12
- package/src/components/ui/__tests__/color-picker.test.tsx +147 -331
- package/src/components/ui/__tests__/radio-group.test.tsx +60 -0
- package/src/components/ui/__tests__/select.test.tsx +24 -2
- package/src/components/ui/__tests__/slider.test.tsx +96 -0
- package/src/components/ui/__tests__/switch.test.tsx +36 -3
- package/src/components/ui/__tests__/toggle-group.test.tsx +30 -0
- package/src/components/ui/alert.tsx +5 -2
- package/src/components/ui/avatar.tsx +18 -6
- package/src/components/ui/badge.tsx +18 -11
- package/src/components/ui/checkbox.tsx +20 -18
- package/src/components/ui/color-picker.tsx +12 -0
- package/src/components/ui/index.ts +17 -0
- package/src/components/ui/radio-group.tsx +47 -8
- package/src/components/ui/select.tsx +59 -23
- package/src/components/ui/slider.tsx +56 -2
- package/src/components/ui/switch.tsx +108 -51
- package/src/components/ui/toggle-group.tsx +4 -0
package/package.json
CHANGED
|
@@ -75,9 +75,9 @@ describe('Alert Components', () => {
|
|
|
75
75
|
it('renders info variant correctly', () => {
|
|
76
76
|
render(<Alert variant="info" data-testid="alert">Test</Alert>)
|
|
77
77
|
const alert = screen.getByTestId('alert')
|
|
78
|
-
expect(alert).toHaveClass('bg-
|
|
79
|
-
expect(alert).toHaveClass('text-
|
|
80
|
-
expect(alert).toHaveClass('border-
|
|
78
|
+
expect(alert).toHaveClass('bg-info/10')
|
|
79
|
+
expect(alert).toHaveClass('text-info')
|
|
80
|
+
expect(alert).toHaveClass('border-info/30')
|
|
81
81
|
})
|
|
82
82
|
|
|
83
83
|
it('uses default variant as default', () => {
|
|
@@ -222,7 +222,7 @@ describe('Alert Components', () => {
|
|
|
222
222
|
const alert = screen.getByTestId('alert')
|
|
223
223
|
const closeButton = alert.querySelector('button')
|
|
224
224
|
expect(closeButton).toBeInTheDocument()
|
|
225
|
-
expect(closeButton).toHaveAttribute('aria-label', '
|
|
225
|
+
expect(closeButton).toHaveAttribute('aria-label', 'Close alert')
|
|
226
226
|
})
|
|
227
227
|
|
|
228
228
|
it('does not render close button when closable is true but onClose is not provided', () => {
|
|
@@ -281,7 +281,7 @@ describe('Alert Components', () => {
|
|
|
281
281
|
render(<Alert closable onClose={handleClose} data-testid="alert">Test</Alert>)
|
|
282
282
|
const alert = screen.getByTestId('alert')
|
|
283
283
|
const closeButton = alert.querySelector('button')
|
|
284
|
-
expect(closeButton).toHaveAttribute('aria-label', '
|
|
284
|
+
expect(closeButton).toHaveAttribute('aria-label', 'Close alert')
|
|
285
285
|
})
|
|
286
286
|
})
|
|
287
287
|
})
|
|
@@ -300,8 +300,8 @@ describe('Avatar Component', () => {
|
|
|
300
300
|
<Avatar key="5"><AvatarFallback>A5</AvatarFallback></Avatar>,
|
|
301
301
|
]
|
|
302
302
|
|
|
303
|
-
it('renders all avatars when no
|
|
304
|
-
render(<AvatarGroup
|
|
303
|
+
it('renders all avatars when no max is set', () => {
|
|
304
|
+
render(<AvatarGroup>{mockAvatars}</AvatarGroup>)
|
|
305
305
|
expect(screen.getByText('A1')).toBeInTheDocument()
|
|
306
306
|
expect(screen.getByText('A2')).toBeInTheDocument()
|
|
307
307
|
expect(screen.getByText('A3')).toBeInTheDocument()
|
|
@@ -309,8 +309,8 @@ describe('Avatar Component', () => {
|
|
|
309
309
|
expect(screen.getByText('A5')).toBeInTheDocument()
|
|
310
310
|
})
|
|
311
311
|
|
|
312
|
-
it('limits avatars when
|
|
313
|
-
render(<AvatarGroup
|
|
312
|
+
it('limits avatars when max is set', () => {
|
|
313
|
+
render(<AvatarGroup max={3}>{mockAvatars}</AvatarGroup>)
|
|
314
314
|
expect(screen.getByText('A1')).toBeInTheDocument()
|
|
315
315
|
expect(screen.getByText('A2')).toBeInTheDocument()
|
|
316
316
|
expect(screen.getByText('A3')).toBeInTheDocument()
|
|
@@ -318,31 +318,31 @@ describe('Avatar Component', () => {
|
|
|
318
318
|
expect(screen.queryByText('A5')).not.toBeInTheDocument()
|
|
319
319
|
})
|
|
320
320
|
|
|
321
|
-
it('shows remaining count when
|
|
322
|
-
render(<AvatarGroup
|
|
321
|
+
it('shows remaining count when max is exceeded', () => {
|
|
322
|
+
render(<AvatarGroup max={3}>{mockAvatars}</AvatarGroup>)
|
|
323
323
|
expect(screen.getByText('+2')).toBeInTheDocument()
|
|
324
324
|
})
|
|
325
325
|
|
|
326
326
|
it('applies custom className', () => {
|
|
327
|
-
render(<AvatarGroup
|
|
327
|
+
render(<AvatarGroup className="custom-group">{mockAvatars}</AvatarGroup>)
|
|
328
328
|
const group = screen.getByText('A1').closest('.custom-group')
|
|
329
329
|
expect(group).toBeInTheDocument()
|
|
330
330
|
})
|
|
331
331
|
|
|
332
332
|
it('forwards ref correctly', () => {
|
|
333
333
|
const ref = React.createRef<HTMLDivElement>()
|
|
334
|
-
render(<AvatarGroup ref={ref}
|
|
334
|
+
render(<AvatarGroup ref={ref}>{mockAvatars}</AvatarGroup>)
|
|
335
335
|
expect(ref.current).toBeInstanceOf(HTMLDivElement)
|
|
336
336
|
})
|
|
337
337
|
|
|
338
338
|
it('applies custom overlap offset', () => {
|
|
339
|
-
render(<AvatarGroup
|
|
339
|
+
render(<AvatarGroup overlapOffset={-12}>{mockAvatars}</AvatarGroup>)
|
|
340
340
|
// This test verifies the component renders without error with custom offset
|
|
341
341
|
expect(screen.getByText('A1')).toBeInTheDocument()
|
|
342
342
|
})
|
|
343
343
|
|
|
344
|
-
it('handles empty
|
|
345
|
-
render(<AvatarGroup
|
|
344
|
+
it('handles empty children', () => {
|
|
345
|
+
render(<AvatarGroup data-testid="avatar-group" />)
|
|
346
346
|
const group = screen.getByTestId('avatar-group')
|
|
347
347
|
expect(group).toBeInTheDocument()
|
|
348
348
|
expect(group).toHaveClass('flex')
|
|
@@ -351,7 +351,7 @@ describe('Avatar Component', () => {
|
|
|
351
351
|
|
|
352
352
|
it('handles single avatar', () => {
|
|
353
353
|
const singleAvatar = [<Avatar key="1"><AvatarFallback>SA</AvatarFallback></Avatar>]
|
|
354
|
-
render(<AvatarGroup
|
|
354
|
+
render(<AvatarGroup>{singleAvatar}</AvatarGroup>)
|
|
355
355
|
expect(screen.getByText('SA')).toBeInTheDocument()
|
|
356
356
|
expect(screen.queryByText('+')).not.toBeInTheDocument()
|
|
357
357
|
})
|
|
@@ -357,8 +357,24 @@ describe('Badge Component', () => {
|
|
|
357
357
|
|
|
358
358
|
const badge = screen.getByText('Focusable').parentElement!
|
|
359
359
|
fireEvent.focus(badge)
|
|
360
|
-
|
|
360
|
+
|
|
361
361
|
expect(onFocus).toHaveBeenCalledTimes(1)
|
|
362
362
|
})
|
|
363
363
|
})
|
|
364
|
+
|
|
365
|
+
describe('forwardRef (#261)', () => {
|
|
366
|
+
it('ref kök elemana iletilir', () => {
|
|
367
|
+
// Regresyon: Badge düz `function Badge(...)` idi — batch'teki diğer 7
|
|
368
|
+
// bileşen forwardRef kullanırken Badge ref alamıyordu.
|
|
369
|
+
const ref = React.createRef<HTMLDivElement>()
|
|
370
|
+
render(<Badge ref={ref}>Etiket</Badge>)
|
|
371
|
+
|
|
372
|
+
expect(ref.current).toBeInstanceOf(HTMLDivElement)
|
|
373
|
+
expect(ref.current).toHaveTextContent('Etiket')
|
|
374
|
+
})
|
|
375
|
+
|
|
376
|
+
it('displayName tanımlı', () => {
|
|
377
|
+
expect(Badge.displayName).toBe('Badge')
|
|
378
|
+
})
|
|
379
|
+
})
|
|
364
380
|
})
|
|
@@ -193,22 +193,28 @@ describe('Checkbox Components', () => {
|
|
|
193
193
|
it('renders indeterminate state correctly', () => {
|
|
194
194
|
render(<Checkbox indeterminate data-testid="checkbox" />)
|
|
195
195
|
const checkbox = screen.getByTestId('checkbox')
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
// Radix'in "indeterminate" CheckedState'i `aria-checked="mixed"` üretir —
|
|
197
|
+
// ekran okuyucu "kısmen seçili" durumunu ancak böyle duyurabilir.
|
|
198
|
+
expect(checkbox).toHaveAttribute('aria-checked', 'mixed')
|
|
199
|
+
expect(checkbox).toHaveAttribute('data-state', 'indeterminate')
|
|
198
200
|
})
|
|
199
201
|
|
|
200
202
|
it('shows minus icon when indeterminate and checked', () => {
|
|
201
203
|
render(<Checkbox indeterminate checked data-testid="checkbox" />)
|
|
202
204
|
const checkbox = screen.getByTestId('checkbox')
|
|
203
|
-
//
|
|
204
|
-
expect(checkbox).toHaveAttribute('aria-checked', '
|
|
205
|
-
expect(checkbox).toHaveAttribute('data-state', '
|
|
205
|
+
// indeterminate, checked'i ezer: durum "mixed" olur.
|
|
206
|
+
expect(checkbox).toHaveAttribute('aria-checked', 'mixed')
|
|
207
|
+
expect(checkbox).toHaveAttribute('data-state', 'indeterminate')
|
|
208
|
+
// Radix Indicator yalnızca checked VEYA indeterminate durumda render edilir.
|
|
209
|
+
// Eskiden state "unchecked" kaldığı için Minus ikonu hiç görünmüyordu —
|
|
210
|
+
// bu assertion o regresyonu bir daha geçirmez.
|
|
211
|
+
expect(checkbox.querySelector('svg')).toBeInTheDocument()
|
|
206
212
|
})
|
|
207
213
|
|
|
208
214
|
it('overrides checked state when indeterminate', () => {
|
|
209
215
|
render(<Checkbox checked indeterminate data-testid="checkbox" />)
|
|
210
216
|
const checkbox = screen.getByTestId('checkbox')
|
|
211
|
-
expect(checkbox).toHaveAttribute('aria-checked', '
|
|
217
|
+
expect(checkbox).toHaveAttribute('aria-checked', 'mixed')
|
|
212
218
|
})
|
|
213
219
|
|
|
214
220
|
it('updates indeterminate state via prop', () => {
|
|
@@ -218,7 +224,7 @@ describe('Checkbox Components', () => {
|
|
|
218
224
|
|
|
219
225
|
rerender(<Checkbox indeterminate={true} data-testid="checkbox" />)
|
|
220
226
|
checkbox = screen.getByTestId('checkbox')
|
|
221
|
-
expect(checkbox).toHaveAttribute('aria-checked', '
|
|
227
|
+
expect(checkbox).toHaveAttribute('aria-checked', 'mixed')
|
|
222
228
|
})
|
|
223
229
|
})
|
|
224
230
|
|
|
@@ -244,12 +250,10 @@ describe('Checkbox Components', () => {
|
|
|
244
250
|
/>
|
|
245
251
|
)
|
|
246
252
|
expect(screen.queryByTestId('custom-icon')).not.toBeInTheDocument()
|
|
247
|
-
|
|
253
|
+
|
|
248
254
|
const checkbox = screen.getByTestId('checkbox')
|
|
249
|
-
//
|
|
250
|
-
expect(
|
|
251
|
-
// Indeterminate state should show as unchecked
|
|
252
|
-
expect(checkbox).toHaveAttribute('aria-checked', 'false')
|
|
255
|
+
// indeterminate, özel ikonu bastırır ve durumu "mixed" yapar.
|
|
256
|
+
expect(checkbox).toHaveAttribute('aria-checked', 'mixed')
|
|
253
257
|
})
|
|
254
258
|
})
|
|
255
259
|
|