hallo-kit 0.3.0 → 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.
@@ -1,128 +1,128 @@
1
- 'use client'
2
-
3
- import * as React from 'react'
4
-
5
- import * as DialogPrimitive from '@radix-ui/react-dialog'
6
-
7
- import { Icon } from '../Icon'
8
- import { cn } from '../../lib/utils'
9
-
10
- // Modal на Radix Dialog: фокус-трап, Esc, клик по оверлею, портал, aria — из коробки.
11
- // Composition-API: Modal / ModalTrigger / ModalContent / ModalHeader / ModalTitle / …
12
- export const Modal = DialogPrimitive.Root
13
- export const ModalTrigger = DialogPrimitive.Trigger
14
- export const ModalClose = DialogPrimitive.Close
15
-
16
- function ModalOverlay({
17
- className,
18
- ...props
19
- }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
20
- return (
21
- <DialogPrimitive.Overlay
22
- className={cn(
23
- 'fixed inset-0 z-50 bg-navy/40 backdrop-blur-sm data-[state=open]:animate-in data-[state=open]:fade-in data-[state=closed]:animate-out data-[state=closed]:fade-out',
24
- className,
25
- )}
26
- {...props}
27
- />
28
- )
29
- }
30
-
31
- export interface ModalContentProps extends React.ComponentProps<
32
- typeof DialogPrimitive.Content
33
- > {
34
- /** Показывать крестик закрытия в углу. По умолчанию true. */
35
- showClose?: boolean
36
- }
37
-
38
- export function ModalContent({
39
- className,
40
- children,
41
- showClose = true,
42
- ...props
43
- }: ModalContentProps) {
44
- return (
45
- <DialogPrimitive.Portal>
46
- <ModalOverlay />
47
- {/* Центрирующая обёртка: флекс по центру экрана. pointer-events-none — клик мимо
48
- контента проходит на оверлей (закрытие). Анимируется ВНУТРЕННИЙ Content
49
- (scale/blur/opacity, без translate) — потому центрирование и анимация не спорят. */}
50
- <div className='pointer-events-none fixed inset-0 z-50 flex items-center justify-center p-4'>
51
- <DialogPrimitive.Content
52
- // Не переводим фокус на первый интерактивный элемент при открытии: он
53
- // оказывался подсвечен до всякого действия пользователя (первый таб
54
- // в окне оплаты). Фокус-ловушка и закрытие по Esc продолжают работать —
55
- // Radix ставит фокус на сам контейнер (у него tabIndex=-1).
56
- onOpenAutoFocus={event => event.preventDefault()}
57
- className={cn(
58
- 'pointer-events-auto relative flex w-full max-w-xl flex-col gap-fl-12/16 rounded-xl border border-border bg-card p-fl-20/30 text-card-foreground shadow-lg outline-none data-[state=open]:modal-blur-in data-[state=closed]:modal-blur-out',
59
- className,
60
- )}
61
- {...props}
62
- >
63
- {children}
64
- {showClose ? (
65
- <DialogPrimitive.Close
66
- aria-label='Закрыть'
67
- className='absolute top-6 right-6 inline-flex size-8 cursor-pointer items-center justify-center text-muted-foreground outline-none transition-colors hover:text-foreground active:text-foreground focus-visible:ring-2 focus-visible:ring-ring'
68
- >
69
- <Icon type='close' isCurrentColor size={18} />
70
- </DialogPrimitive.Close>
71
- ) : null}
72
- </DialogPrimitive.Content>
73
- </div>
74
- </DialogPrimitive.Portal>
75
- )
76
- }
77
-
78
- // pr-8 — чтобы заголовок не залезал под крестик.
79
- export function ModalHeader({
80
- className,
81
- ...props
82
- }: React.ComponentProps<'div'>) {
83
- return (
84
- <div
85
- className={cn('flex flex-col gap-1.5 pr-8 text-left', className)}
86
- {...props}
87
- />
88
- )
89
- }
90
-
91
- export function ModalFooter({
92
- className,
93
- ...props
94
- }: React.ComponentProps<'div'>) {
95
- return (
96
- <div
97
- className={cn(
98
- 'flex flex-col-reverse gap-2 sm:flex-row sm:justify-end',
99
- className,
100
- )}
101
- {...props}
102
- />
103
- )
104
- }
105
-
106
- export function ModalTitle({
107
- className,
108
- ...props
109
- }: React.ComponentProps<typeof DialogPrimitive.Title>) {
110
- return (
111
- <DialogPrimitive.Title
112
- className={cn('text-h3 text-foreground', className)}
113
- {...props}
114
- />
115
- )
116
- }
117
-
118
- export function ModalDescription({
119
- className,
120
- ...props
121
- }: React.ComponentProps<typeof DialogPrimitive.Description>) {
122
- return (
123
- <DialogPrimitive.Description
124
- className={cn('text-body-l text-foreground', className)}
125
- {...props}
126
- />
127
- )
128
- }
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+
5
+ import * as DialogPrimitive from '@radix-ui/react-dialog'
6
+
7
+ import { Icon } from '../Icon'
8
+ import { cn } from '../../lib/utils'
9
+
10
+ // Modal на Radix Dialog: фокус-трап, Esc, клик по оверлею, портал, aria — из коробки.
11
+ // Composition-API: Modal / ModalTrigger / ModalContent / ModalHeader / ModalTitle / …
12
+ export const Modal = DialogPrimitive.Root
13
+ export const ModalTrigger = DialogPrimitive.Trigger
14
+ export const ModalClose = DialogPrimitive.Close
15
+
16
+ function ModalOverlay({
17
+ className,
18
+ ...props
19
+ }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
20
+ return (
21
+ <DialogPrimitive.Overlay
22
+ className={cn(
23
+ 'fixed inset-0 z-50 bg-navy/40 backdrop-blur-sm data-[state=open]:animate-in data-[state=open]:fade-in data-[state=closed]:animate-out data-[state=closed]:fade-out',
24
+ className,
25
+ )}
26
+ {...props}
27
+ />
28
+ )
29
+ }
30
+
31
+ export interface ModalContentProps extends React.ComponentProps<
32
+ typeof DialogPrimitive.Content
33
+ > {
34
+ /** Показывать крестик закрытия в углу. По умолчанию true. */
35
+ showClose?: boolean
36
+ }
37
+
38
+ export function ModalContent({
39
+ className,
40
+ children,
41
+ showClose = true,
42
+ ...props
43
+ }: ModalContentProps) {
44
+ return (
45
+ <DialogPrimitive.Portal>
46
+ <ModalOverlay />
47
+ {/* Центрирующая обёртка: флекс по центру экрана. pointer-events-none — клик мимо
48
+ контента проходит на оверлей (закрытие). Анимируется ВНУТРЕННИЙ Content
49
+ (scale/blur/opacity, без translate) — потому центрирование и анимация не спорят. */}
50
+ <div className='pointer-events-none fixed inset-0 z-50 flex items-center justify-center p-4'>
51
+ <DialogPrimitive.Content
52
+ // Не переводим фокус на первый интерактивный элемент при открытии: он
53
+ // оказывался подсвечен до всякого действия пользователя (первый таб
54
+ // в окне оплаты). Фокус-ловушка и закрытие по Esc продолжают работать —
55
+ // Radix ставит фокус на сам контейнер (у него tabIndex=-1).
56
+ onOpenAutoFocus={event => event.preventDefault()}
57
+ className={cn(
58
+ 'pointer-events-auto relative flex w-full max-w-xl flex-col gap-fl-12/16 rounded-xl border border-border bg-card p-fl-20/30 text-card-foreground shadow-lg outline-none data-[state=open]:modal-blur-in data-[state=closed]:modal-blur-out',
59
+ className,
60
+ )}
61
+ {...props}
62
+ >
63
+ {children}
64
+ {showClose ? (
65
+ <DialogPrimitive.Close
66
+ aria-label='Закрыть'
67
+ className='absolute top-6 right-6 inline-flex size-8 cursor-pointer items-center justify-center text-muted-foreground outline-none transition-colors hover:text-foreground active:text-foreground focus-visible:ring-2 focus-visible:ring-ring'
68
+ >
69
+ <Icon type='close' isCurrentColor size={18} />
70
+ </DialogPrimitive.Close>
71
+ ) : null}
72
+ </DialogPrimitive.Content>
73
+ </div>
74
+ </DialogPrimitive.Portal>
75
+ )
76
+ }
77
+
78
+ // pr-8 — чтобы заголовок не залезал под крестик.
79
+ export function ModalHeader({
80
+ className,
81
+ ...props
82
+ }: React.ComponentProps<'div'>) {
83
+ return (
84
+ <div
85
+ className={cn('flex flex-col gap-1.5 pr-8 text-left', className)}
86
+ {...props}
87
+ />
88
+ )
89
+ }
90
+
91
+ export function ModalFooter({
92
+ className,
93
+ ...props
94
+ }: React.ComponentProps<'div'>) {
95
+ return (
96
+ <div
97
+ className={cn(
98
+ 'flex flex-col-reverse gap-2 sm:flex-row sm:justify-end',
99
+ className,
100
+ )}
101
+ {...props}
102
+ />
103
+ )
104
+ }
105
+
106
+ export function ModalTitle({
107
+ className,
108
+ ...props
109
+ }: React.ComponentProps<typeof DialogPrimitive.Title>) {
110
+ return (
111
+ <DialogPrimitive.Title
112
+ className={cn('text-h3 text-foreground', className)}
113
+ {...props}
114
+ />
115
+ )
116
+ }
117
+
118
+ export function ModalDescription({
119
+ className,
120
+ ...props
121
+ }: React.ComponentProps<typeof DialogPrimitive.Description>) {
122
+ return (
123
+ <DialogPrimitive.Description
124
+ className={cn('text-body-l text-foreground', className)}
125
+ {...props}
126
+ />
127
+ )
128
+ }