@de-kit/st-ui 0.1.8 → 0.1.9

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 (34) hide show
  1. package/README.md +143 -143
  2. package/dist/components/button/button.cjs.map +1 -1
  3. package/dist/components/button/button.d.cts +1 -1
  4. package/dist/components/button/button.d.ts +1 -1
  5. package/dist/components/button/button.js.map +1 -1
  6. package/dist/components/button/button.scss +201 -147
  7. package/dist/components/checkbox/checkbox.cjs.map +1 -1
  8. package/dist/components/checkbox/checkbox.js.map +1 -1
  9. package/dist/components/checkbox/checkbox.scss +137 -137
  10. package/dist/components/field/field-context.cjs.map +1 -1
  11. package/dist/components/field/field-context.js.map +1 -1
  12. package/dist/components/field/field.cjs.map +1 -1
  13. package/dist/components/field/field.js.map +1 -1
  14. package/dist/components/field/field.scss +43 -43
  15. package/dist/components/input/input.cjs.map +1 -1
  16. package/dist/components/input/input.js.map +1 -1
  17. package/dist/components/input/input.scss +127 -127
  18. package/dist/components/radio/radio.cjs.map +1 -1
  19. package/dist/components/radio/radio.js.map +1 -1
  20. package/dist/components/radio/radio.scss +144 -144
  21. package/dist/components/spinner/spinner.cjs.map +1 -1
  22. package/dist/components/spinner/spinner.js.map +1 -1
  23. package/dist/components/spinner/spinner.scss +29 -29
  24. package/dist/components/textarea/textarea.cjs.map +1 -1
  25. package/dist/components/textarea/textarea.js.map +1 -1
  26. package/dist/components/textarea/textarea.scss +85 -85
  27. package/dist/icons/svg.cjs.map +1 -1
  28. package/dist/icons/svg.js.map +1 -1
  29. package/dist/lib/cn.cjs.map +1 -1
  30. package/dist/lib/cn.js.map +1 -1
  31. package/dist/styles/global.scss +201 -201
  32. package/dist/styles/mixins.scss +51 -51
  33. package/dist/styles/vars.scss +87 -87
  34. package/package.json +1 -1
@@ -1,147 +1,201 @@
1
- .button {
2
- box-sizing: border-box;
3
- width: fit-content;
4
- display: flex;
5
- align-items: center;
6
- padding: 8px 18px;
7
- border-radius: 30px;
8
- font-size: var(--text-sm);
9
- line-height: var(--text-sm--line-height);
10
- background-color: var(--color-primary);
11
- color: var(--color-primary-foreground);
12
- fill: var(--color-primary-foreground);
13
- font-weight: bold;
14
- font-family: var(--font-sans);
15
- border: 2px solid var(--color-primary);
16
- flex-shrink: 0;
17
- cursor: pointer;
18
- transition: none;
19
- gap: 8px;
20
- text-decoration: none;
21
-
22
- &:hover:not(:active):not(:disabled) {
23
- background-color: var(--color-primary-hover);
24
- border-color: var(--color-primary-hover);
25
- }
26
-
27
- &:focus:not(:focus-visible) {
28
- outline: none;
29
- }
30
-
31
- &:focus-visible {
32
- outline: var(--focus-ring-width) solid var(--focus-ring-color);
33
- outline-offset: var(--focus-ring-offset);
34
- }
35
-
36
- &:active {
37
- background-color: var(--color-muted);
38
- color: var(--color-muted-foreground);
39
- fill: currentColor;
40
- border-color: var(--color-muted);
41
- }
42
-
43
- // pointer-events не гасим: нативный disabled и так не пускает клик, а так
44
- // на кнопку можно навести тултип «почему недоступна».
45
- &:disabled {
46
- background-color: var(--color-muted);
47
- color: var(--color-muted-foreground);
48
- fill: currentColor;
49
- border-color: var(--color-muted);
50
- cursor: default;
51
- user-select: none;
52
- }
53
-
54
- &--outline {
55
- background-color: transparent;
56
- color: var(--color-foreground);
57
- fill: currentColor;
58
- border: 2px solid var(--color-foreground);
59
-
60
- &:hover:not(:active):not(:disabled) {
61
- background-color: transparent;
62
- border-color: var(--color-foreground);
63
- color: var(--color-foreground);
64
- fill: currentColor;
65
- }
66
-
67
- &:disabled {
68
- background-color: transparent;
69
- }
70
- }
71
-
72
- &--link {
73
- border: none;
74
- background-color: transparent;
75
- color: var(--color-foreground);
76
- fill: currentColor;
77
- border-radius: 0;
78
- padding: 0;
79
-
80
- &:hover:not(:active):not(:disabled) {
81
- background-color: transparent;
82
- }
83
-
84
- &:active,
85
- &:disabled {
86
- background-color: transparent;
87
- }
88
- }
89
-
90
- &--loading {
91
- position: relative;
92
- }
93
-
94
- &__label {
95
- display: flex;
96
- align-items: center;
97
- gap: inherit;
98
- opacity: 0;
99
- }
100
-
101
- &__spinner {
102
- position: absolute;
103
- inset: 0;
104
- display: flex;
105
- align-items: center;
106
- justify-content: center;
107
- pointer-events: none;
108
- }
109
-
110
- // 12/16 и 16/24 у sm и lg сняты со старого макета и в шкалу --text-* не попадают.
111
- &--sm {
112
- padding: 5px 12px;
113
- font-size: 12px;
114
- line-height: 16px;
115
- }
116
-
117
- &--lg {
118
- padding: 12px 24px;
119
- font-size: 16px;
120
- line-height: 24px;
121
- }
122
-
123
- &--full-width {
124
- width: 100%;
125
- justify-content: center;
126
- }
127
-
128
- svg {
129
- flex-shrink: 0;
130
- }
131
- }
132
-
133
- .button__icon--spin {
134
- animation: button-spin 0.8s linear infinite;
135
- }
136
-
137
- @keyframes button-spin {
138
- to {
139
- transform: rotate(360deg);
140
- }
141
- }
142
-
143
- @media (prefers-reduced-motion: reduce) {
144
- .button__icon--spin {
145
- animation: none;
146
- }
147
- }
1
+ @use '../../styles/mixins.scss' as mixins;
2
+
3
+ .button {
4
+ box-sizing: border-box;
5
+ width: fit-content;
6
+ display: flex;
7
+ align-items: center;
8
+ padding: 8px 18px;
9
+ border-radius: 30px;
10
+ font-size: var(--text-sm);
11
+ line-height: var(--text-sm--line-height);
12
+ background-color: var(--color-primary);
13
+ color: var(--color-primary-foreground);
14
+ fill: var(--color-primary-foreground);
15
+ font-weight: bold;
16
+ font-family: var(--font-sans);
17
+ border: 2px solid var(--color-primary);
18
+ flex-shrink: 0;
19
+ cursor: pointer;
20
+ transition: none;
21
+ gap: 8px;
22
+ text-decoration: none;
23
+
24
+ &:hover:not(:active, :disabled) {
25
+ background-color: var(--color-primary-hover);
26
+ border-color: var(--color-primary-hover);
27
+ }
28
+
29
+ &:focus:not(:focus-visible) {
30
+ outline: none;
31
+ }
32
+
33
+ &:focus-visible {
34
+ outline: var(--focus-ring-width) solid var(--focus-ring-color);
35
+ outline-offset: var(--focus-ring-offset);
36
+ }
37
+
38
+ &:active {
39
+ background-color: var(--color-muted);
40
+ color: var(--color-muted-foreground);
41
+ fill: currentColor;
42
+ border-color: var(--color-muted);
43
+ }
44
+
45
+ // pointer-events не гасим: нативный disabled и так не пускает клик, а так
46
+ // на кнопку можно навести тултип «почему недоступна».
47
+ &:disabled {
48
+ background-color: var(--color-muted);
49
+ color: var(--color-muted-foreground);
50
+ fill: currentColor;
51
+ border-color: var(--color-muted);
52
+ cursor: default;
53
+ user-select: none;
54
+ }
55
+
56
+ &--outline {
57
+ background-color: transparent;
58
+ color: var(--color-foreground);
59
+ fill: currentColor;
60
+ border: 2px solid var(--color-foreground);
61
+
62
+ &:hover:not(:active, :disabled) {
63
+ background-color: transparent;
64
+ border-color: var(--color-foreground);
65
+ color: var(--color-foreground);
66
+ fill: currentColor;
67
+ }
68
+
69
+ &:disabled {
70
+ background-color: transparent;
71
+ }
72
+ }
73
+
74
+ &--link {
75
+ border: none;
76
+ background-color: transparent;
77
+ color: var(--color-foreground);
78
+ fill: currentColor;
79
+ border-radius: 0;
80
+ padding: 0;
81
+
82
+ &:hover:not(:active, :disabled) {
83
+ background-color: transparent;
84
+ }
85
+
86
+ &:active,
87
+ &:disabled {
88
+ background-color: transparent;
89
+ }
90
+ }
91
+
92
+ &--image {
93
+ --size: 60px;
94
+ background-color: var(--color-secondary);
95
+ border: none;
96
+ padding: 0;
97
+ border-radius: var(--radius-sm);
98
+ width: var(--size);
99
+ height: var(--size);
100
+ position: relative;
101
+
102
+ @include mixins.min-width(md) {
103
+ --size: 100px;
104
+ }
105
+
106
+ &:hover:not(:active, :disabled) {
107
+ background-color: var(--color-secondary);
108
+ }
109
+
110
+ &__icon {
111
+ --size-icon: 32px;
112
+ position: absolute;
113
+ top: 50%;
114
+ left: 50%;
115
+ z-index: 1;
116
+ display: flex;
117
+ width: var(--size-icon);
118
+ height: var(--size-icon);
119
+ border-radius: 50%;
120
+ background-color: var(--color-primary);
121
+ color: var(--color-primary-foreground);
122
+ justify-content: center;
123
+ align-items: center;
124
+ transform: translate(-50%, -50%);
125
+ pointer-events: none;
126
+
127
+ @include mixins.min-width(md) {
128
+ --size-icon: 40px;
129
+ }
130
+ }
131
+ }
132
+
133
+ &--icon {
134
+ --size: 40px;
135
+ width: var(--size);
136
+ height: var(--size);
137
+ border-radius: 50%;
138
+ justify-content: center;
139
+ padding: 0;
140
+ }
141
+
142
+ // 12/16 и 16/24 у sm и lg сняты со старого макета и в шкалу --text-* не попадают.
143
+ &--sm {
144
+ padding: 5px 12px;
145
+ font-size: 12px;
146
+ line-height: 16px;
147
+ --size: 30px;
148
+ }
149
+
150
+ &--lg {
151
+ --size: 52px;
152
+ padding: 12px 24px;
153
+ font-size: 16px;
154
+ line-height: 24px;
155
+ }
156
+
157
+ &--full-width {
158
+ width: 100%;
159
+ justify-content: center;
160
+ }
161
+
162
+ &--loading {
163
+ position: relative;
164
+ }
165
+
166
+ &__label {
167
+ display: flex;
168
+ align-items: center;
169
+ gap: inherit;
170
+ opacity: 0;
171
+ }
172
+
173
+ &__spinner {
174
+ position: absolute;
175
+ inset: 0;
176
+ display: flex;
177
+ align-items: center;
178
+ justify-content: center;
179
+ pointer-events: none;
180
+ }
181
+
182
+ svg {
183
+ flex-shrink: 0;
184
+ }
185
+ }
186
+
187
+ .button__icon--spin {
188
+ animation: button-spin 0.8s linear infinite;
189
+ }
190
+
191
+ @keyframes button-spin {
192
+ to {
193
+ transform: rotate(360deg);
194
+ }
195
+ }
196
+
197
+ @media (prefers-reduced-motion: reduce) {
198
+ .button__icon--spin {
199
+ animation: none;
200
+ }
201
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox.cjs","names":["forwardRef","useFieldControl","useId","useRef","useCallback","cn","when"],"sources":["../../../src/components/checkbox/checkbox.tsx"],"sourcesContent":["import {\r\n forwardRef,\r\n useCallback,\r\n useEffect,\r\n useId,\r\n useRef,\r\n type ChangeEvent,\r\n type InputHTMLAttributes,\r\n type ReactNode,\r\n type Ref,\r\n} from 'react';\r\n\r\nimport { useFieldControl } from '@/components/field/field-context';\r\nimport { cn, when } from '@/lib/cn';\r\nimport './checkbox.scss';\r\n\r\nexport interface CheckboxInputProps extends InputHTMLAttributes<HTMLInputElement> {\r\n label?: ReactNode;\r\n /** Красная рамка. Внутри `Field` состоянием ошибки распоряжается он. */\r\n error?: boolean;\r\n /** «Выбрать все»: IDL `indeterminate`, React его атрибутом не прокидывает. */\r\n indeterminate?: boolean;\r\n /**\r\n * false — `pointer-events: none` на input (`checkbox__input--no-events`).\r\n * Клик по лейблу по-прежнему переключает.\r\n */\r\n clickable?: boolean;\r\n}\r\n\r\nconst assignRef = (\r\n ref: Ref<HTMLInputElement> | null,\r\n node: HTMLInputElement | null,\r\n) => {\r\n if (typeof ref === 'function') {\r\n ref(node);\r\n return;\r\n }\r\n\r\n if (ref) ref.current = node;\r\n};\r\n\r\nconst mergeDescribedBy = (\r\n fromField: string | undefined,\r\n fromProps: string | undefined,\r\n) => {\r\n const value = [fromField, fromProps].filter(part => Boolean(part)).join(' ');\r\n return value || undefined;\r\n};\r\n\r\nexport const CheckboxInput = forwardRef<HTMLInputElement, CheckboxInputProps>(\r\n function CheckboxInput(\r\n {\r\n className,\r\n id,\r\n label,\r\n error,\r\n disabled,\r\n clickable = true,\r\n indeterminate = false,\r\n checked,\r\n onChange,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const field = useFieldControl();\r\n const reportValue = field?.reportValue;\r\n const autoId = useId();\r\n const inputId = field?.id ?? id ?? autoId;\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n const isInvalid = Boolean(error) || Boolean(field?.invalid);\r\n\r\n const setRef = useCallback(\r\n (node: HTMLInputElement | null) => {\r\n inputRef.current = node;\r\n assignRef(ref, node);\r\n },\r\n [ref],\r\n );\r\n\r\n useEffect(() => {\r\n if (inputRef.current) inputRef.current.indeterminate = indeterminate;\r\n }, [indeterminate]);\r\n\r\n // Field ждёт строку: отдаём то же, что ушло бы в FormData — 'on' или пусто.\r\n useEffect(() => {\r\n const node = inputRef.current;\r\n if (node) reportValue?.(node.checked ? 'on' : '');\r\n }, [checked, reportValue]);\r\n\r\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\r\n if (checked === undefined) {\r\n reportValue?.(event.target.checked ? 'on' : '');\r\n }\r\n onChange?.(event);\r\n };\r\n\r\n const describedBy = field\r\n ? mergeDescribedBy(field.describedBy, props['aria-describedby'])\r\n : undefined;\r\n\r\n const fieldAttrs: InputHTMLAttributes<HTMLInputElement> = {};\r\n\r\n if (field?.required) {\r\n fieldAttrs.required = true;\r\n fieldAttrs['aria-required'] = true;\r\n }\r\n\r\n if (isInvalid) fieldAttrs['aria-invalid'] = true;\r\n if (describedBy) fieldAttrs['aria-describedby'] = describedBy;\r\n if (field?.errorId) fieldAttrs['aria-errormessage'] = field.errorId;\r\n\r\n return (\r\n <div className={cn('checkbox', className)}>\r\n <input\r\n {...props}\r\n ref={setRef}\r\n type=\"checkbox\"\r\n id={inputId}\r\n disabled={disabled}\r\n {...(checked !== undefined ? { checked } : {})}\r\n onChange={handleChange}\r\n className={cn(\r\n 'checkbox__input',\r\n when(!clickable, 'checkbox__input--no-events'),\r\n )}\r\n {...fieldAttrs}\r\n />\r\n {label ? (\r\n <label className=\"checkbox__label\" htmlFor={inputId}>\r\n {label}\r\n </label>\r\n ) : null}\r\n </div>\r\n );\r\n },\r\n);\r\n"],"mappings":";;;;;;AA6BA,MAAM,aACJ,KACA,SACG;CACH,IAAI,OAAO,QAAQ,YAAY;EAC7B,IAAI,IAAI;EACR;CACF;CAEA,IAAI,KAAK,IAAI,UAAU;AACzB;AAEA,MAAM,oBACJ,WACA,cACG;CAEH,OADc,CAAC,WAAW,SAAS,CAAC,CAAC,QAAO,SAAQ,QAAQ,IAAI,CAAC,CAAC,CAAC,KAAK,GAC7D,KAAK,KAAA;AAClB;AAEA,MAAa,iBAAA,GAAgBA,MAAAA,WAAAA,CAC3B,SAAS,cACP,EACE,WACA,IACA,OACA,OACA,UACA,YAAY,MACZ,gBAAgB,OAChB,SACA,UACA,GAAG,SAEL,KACA;CACA,MAAM,QAAQC,sBAAAA,gBAAgB;CAC9B,MAAM,cAAc,OAAO;CAC3B,MAAM,UAAA,GAASC,MAAAA,MAAAA,CAAM;CACrB,MAAM,UAAU,OAAO,MAAM,MAAM;CACnC,MAAM,YAAA,GAAWC,MAAAA,OAAAA,CAAyB,IAAI;CAC9C,MAAM,YAAY,QAAQ,KAAK,KAAK,QAAQ,OAAO,OAAO;CAE1D,MAAM,UAAA,GAASC,MAAAA,YAAAA,EACZ,SAAkC;EACjC,SAAS,UAAU;EACnB,UAAU,KAAK,IAAI;CACrB,GACA,CAAC,GAAG,CACN;CAEA,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,SAAS,SAAS,SAAS,QAAQ,gBAAgB;CACzD,GAAG,CAAC,aAAa,CAAC;CAGlB,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,MAAM,OAAO,SAAS;EACtB,IAAI,MAAM,cAAc,KAAK,UAAU,OAAO,EAAE;CAClD,GAAG,CAAC,SAAS,WAAW,CAAC;CAEzB,MAAM,gBAAgB,UAAyC;EAC7D,IAAI,YAAY,KAAA,GACd,cAAc,MAAM,OAAO,UAAU,OAAO,EAAE;EAEhD,WAAW,KAAK;CAClB;CAEA,MAAM,cAAc,QAChB,iBAAiB,MAAM,aAAa,MAAM,mBAAmB,IAC7D,KAAA;CAEJ,MAAM,aAAoD,CAAC;CAE3D,IAAI,OAAO,UAAU;EACnB,WAAW,WAAW;EACtB,WAAW,mBAAmB;CAChC;CAEA,IAAI,WAAW,WAAW,kBAAkB;CAC5C,IAAI,aAAa,WAAW,sBAAsB;CAClD,IAAI,OAAO,SAAS,WAAW,uBAAuB,MAAM;CAE5D,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EAAK,WAAWC,WAAAA,GAAG,YAAY,SAAS;EAAxC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;GACE,GAAI;GACJ,KAAK;GACL,MAAK;GACL,IAAI;GACM;GACV,GAAK,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;GAC5C,UAAU;GACV,WAAWA,WAAAA,GACT,mBACAC,WAAAA,KAAK,CAAC,WAAW,4BAA4B,CAC/C;GACA,GAAI;EACL,CAAA,GACA,QACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;GAAO,WAAU;GAAkB,SAAS;GACzC,UAAA;EACI,CAAA,IACL,IACD;;AAET,CACF"}
1
+ {"version":3,"file":"checkbox.cjs","names":["forwardRef","useFieldControl","useId","useRef","useCallback","cn","when"],"sources":["../../../src/components/checkbox/checkbox.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n type ChangeEvent,\n type InputHTMLAttributes,\n type ReactNode,\n type Ref,\n} from 'react';\n\nimport { useFieldControl } from '@/components/field/field-context';\nimport { cn, when } from '@/lib/cn';\nimport './checkbox.scss';\n\nexport interface CheckboxInputProps extends InputHTMLAttributes<HTMLInputElement> {\n label?: ReactNode;\n /** Красная рамка. Внутри `Field` состоянием ошибки распоряжается он. */\n error?: boolean;\n /** «Выбрать все»: IDL `indeterminate`, React его атрибутом не прокидывает. */\n indeterminate?: boolean;\n /**\n * false — `pointer-events: none` на input (`checkbox__input--no-events`).\n * Клик по лейблу по-прежнему переключает.\n */\n clickable?: boolean;\n}\n\nconst assignRef = (\n ref: Ref<HTMLInputElement> | null,\n node: HTMLInputElement | null,\n) => {\n if (typeof ref === 'function') {\n ref(node);\n return;\n }\n\n if (ref) ref.current = node;\n};\n\nconst mergeDescribedBy = (\n fromField: string | undefined,\n fromProps: string | undefined,\n) => {\n const value = [fromField, fromProps].filter(part => Boolean(part)).join(' ');\n return value || undefined;\n};\n\nexport const CheckboxInput = forwardRef<HTMLInputElement, CheckboxInputProps>(\n function CheckboxInput(\n {\n className,\n id,\n label,\n error,\n disabled,\n clickable = true,\n indeterminate = false,\n checked,\n onChange,\n ...props\n },\n ref,\n ) {\n const field = useFieldControl();\n const reportValue = field?.reportValue;\n const autoId = useId();\n const inputId = field?.id ?? id ?? autoId;\n const inputRef = useRef<HTMLInputElement>(null);\n const isInvalid = Boolean(error) || Boolean(field?.invalid);\n\n const setRef = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n assignRef(ref, node);\n },\n [ref],\n );\n\n useEffect(() => {\n if (inputRef.current) inputRef.current.indeterminate = indeterminate;\n }, [indeterminate]);\n\n // Field ждёт строку: отдаём то же, что ушло бы в FormData — 'on' или пусто.\n useEffect(() => {\n const node = inputRef.current;\n if (node) reportValue?.(node.checked ? 'on' : '');\n }, [checked, reportValue]);\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (checked === undefined) {\n reportValue?.(event.target.checked ? 'on' : '');\n }\n onChange?.(event);\n };\n\n const describedBy = field\n ? mergeDescribedBy(field.describedBy, props['aria-describedby'])\n : undefined;\n\n const fieldAttrs: InputHTMLAttributes<HTMLInputElement> = {};\n\n if (field?.required) {\n fieldAttrs.required = true;\n fieldAttrs['aria-required'] = true;\n }\n\n if (isInvalid) fieldAttrs['aria-invalid'] = true;\n if (describedBy) fieldAttrs['aria-describedby'] = describedBy;\n if (field?.errorId) fieldAttrs['aria-errormessage'] = field.errorId;\n\n return (\n <div className={cn('checkbox', className)}>\n <input\n {...props}\n ref={setRef}\n type=\"checkbox\"\n id={inputId}\n disabled={disabled}\n {...(checked !== undefined ? { checked } : {})}\n onChange={handleChange}\n className={cn(\n 'checkbox__input',\n when(!clickable, 'checkbox__input--no-events'),\n )}\n {...fieldAttrs}\n />\n {label ? (\n <label className=\"checkbox__label\" htmlFor={inputId}>\n {label}\n </label>\n ) : null}\n </div>\n );\n },\n);\n"],"mappings":";;;;;;AA6BA,MAAM,aACJ,KACA,SACG;CACH,IAAI,OAAO,QAAQ,YAAY;EAC7B,IAAI,IAAI;EACR;CACF;CAEA,IAAI,KAAK,IAAI,UAAU;AACzB;AAEA,MAAM,oBACJ,WACA,cACG;CAEH,OADc,CAAC,WAAW,SAAS,CAAC,CAAC,QAAO,SAAQ,QAAQ,IAAI,CAAC,CAAC,CAAC,KAAK,GAC7D,KAAK,KAAA;AAClB;AAEA,MAAa,iBAAA,GAAgBA,MAAAA,WAAAA,CAC3B,SAAS,cACP,EACE,WACA,IACA,OACA,OACA,UACA,YAAY,MACZ,gBAAgB,OAChB,SACA,UACA,GAAG,SAEL,KACA;CACA,MAAM,QAAQC,sBAAAA,gBAAgB;CAC9B,MAAM,cAAc,OAAO;CAC3B,MAAM,UAAA,GAASC,MAAAA,MAAAA,CAAM;CACrB,MAAM,UAAU,OAAO,MAAM,MAAM;CACnC,MAAM,YAAA,GAAWC,MAAAA,OAAAA,CAAyB,IAAI;CAC9C,MAAM,YAAY,QAAQ,KAAK,KAAK,QAAQ,OAAO,OAAO;CAE1D,MAAM,UAAA,GAASC,MAAAA,YAAAA,EACZ,SAAkC;EACjC,SAAS,UAAU;EACnB,UAAU,KAAK,IAAI;CACrB,GACA,CAAC,GAAG,CACN;CAEA,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,SAAS,SAAS,SAAS,QAAQ,gBAAgB;CACzD,GAAG,CAAC,aAAa,CAAC;CAGlB,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,MAAM,OAAO,SAAS;EACtB,IAAI,MAAM,cAAc,KAAK,UAAU,OAAO,EAAE;CAClD,GAAG,CAAC,SAAS,WAAW,CAAC;CAEzB,MAAM,gBAAgB,UAAyC;EAC7D,IAAI,YAAY,KAAA,GACd,cAAc,MAAM,OAAO,UAAU,OAAO,EAAE;EAEhD,WAAW,KAAK;CAClB;CAEA,MAAM,cAAc,QAChB,iBAAiB,MAAM,aAAa,MAAM,mBAAmB,IAC7D,KAAA;CAEJ,MAAM,aAAoD,CAAC;CAE3D,IAAI,OAAO,UAAU;EACnB,WAAW,WAAW;EACtB,WAAW,mBAAmB;CAChC;CAEA,IAAI,WAAW,WAAW,kBAAkB;CAC5C,IAAI,aAAa,WAAW,sBAAsB;CAClD,IAAI,OAAO,SAAS,WAAW,uBAAuB,MAAM;CAE5D,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EAAK,WAAWC,WAAAA,GAAG,YAAY,SAAS;EAAxC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;GACE,GAAI;GACJ,KAAK;GACL,MAAK;GACL,IAAI;GACM;GACV,GAAK,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;GAC5C,UAAU;GACV,WAAWA,WAAAA,GACT,mBACAC,WAAAA,KAAK,CAAC,WAAW,4BAA4B,CAC/C;GACA,GAAI;EACL,CAAA,GACA,QACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;GAAO,WAAU;GAAkB,SAAS;GACzC,UAAA;EACI,CAAA,IACL,IACD;;AAET,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox.js","names":[],"sources":["../../../src/components/checkbox/checkbox.tsx"],"sourcesContent":["import {\r\n forwardRef,\r\n useCallback,\r\n useEffect,\r\n useId,\r\n useRef,\r\n type ChangeEvent,\r\n type InputHTMLAttributes,\r\n type ReactNode,\r\n type Ref,\r\n} from 'react';\r\n\r\nimport { useFieldControl } from '@/components/field/field-context';\r\nimport { cn, when } from '@/lib/cn';\r\nimport './checkbox.scss';\r\n\r\nexport interface CheckboxInputProps extends InputHTMLAttributes<HTMLInputElement> {\r\n label?: ReactNode;\r\n /** Красная рамка. Внутри `Field` состоянием ошибки распоряжается он. */\r\n error?: boolean;\r\n /** «Выбрать все»: IDL `indeterminate`, React его атрибутом не прокидывает. */\r\n indeterminate?: boolean;\r\n /**\r\n * false — `pointer-events: none` на input (`checkbox__input--no-events`).\r\n * Клик по лейблу по-прежнему переключает.\r\n */\r\n clickable?: boolean;\r\n}\r\n\r\nconst assignRef = (\r\n ref: Ref<HTMLInputElement> | null,\r\n node: HTMLInputElement | null,\r\n) => {\r\n if (typeof ref === 'function') {\r\n ref(node);\r\n return;\r\n }\r\n\r\n if (ref) ref.current = node;\r\n};\r\n\r\nconst mergeDescribedBy = (\r\n fromField: string | undefined,\r\n fromProps: string | undefined,\r\n) => {\r\n const value = [fromField, fromProps].filter(part => Boolean(part)).join(' ');\r\n return value || undefined;\r\n};\r\n\r\nexport const CheckboxInput = forwardRef<HTMLInputElement, CheckboxInputProps>(\r\n function CheckboxInput(\r\n {\r\n className,\r\n id,\r\n label,\r\n error,\r\n disabled,\r\n clickable = true,\r\n indeterminate = false,\r\n checked,\r\n onChange,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const field = useFieldControl();\r\n const reportValue = field?.reportValue;\r\n const autoId = useId();\r\n const inputId = field?.id ?? id ?? autoId;\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n const isInvalid = Boolean(error) || Boolean(field?.invalid);\r\n\r\n const setRef = useCallback(\r\n (node: HTMLInputElement | null) => {\r\n inputRef.current = node;\r\n assignRef(ref, node);\r\n },\r\n [ref],\r\n );\r\n\r\n useEffect(() => {\r\n if (inputRef.current) inputRef.current.indeterminate = indeterminate;\r\n }, [indeterminate]);\r\n\r\n // Field ждёт строку: отдаём то же, что ушло бы в FormData — 'on' или пусто.\r\n useEffect(() => {\r\n const node = inputRef.current;\r\n if (node) reportValue?.(node.checked ? 'on' : '');\r\n }, [checked, reportValue]);\r\n\r\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\r\n if (checked === undefined) {\r\n reportValue?.(event.target.checked ? 'on' : '');\r\n }\r\n onChange?.(event);\r\n };\r\n\r\n const describedBy = field\r\n ? mergeDescribedBy(field.describedBy, props['aria-describedby'])\r\n : undefined;\r\n\r\n const fieldAttrs: InputHTMLAttributes<HTMLInputElement> = {};\r\n\r\n if (field?.required) {\r\n fieldAttrs.required = true;\r\n fieldAttrs['aria-required'] = true;\r\n }\r\n\r\n if (isInvalid) fieldAttrs['aria-invalid'] = true;\r\n if (describedBy) fieldAttrs['aria-describedby'] = describedBy;\r\n if (field?.errorId) fieldAttrs['aria-errormessage'] = field.errorId;\r\n\r\n return (\r\n <div className={cn('checkbox', className)}>\r\n <input\r\n {...props}\r\n ref={setRef}\r\n type=\"checkbox\"\r\n id={inputId}\r\n disabled={disabled}\r\n {...(checked !== undefined ? { checked } : {})}\r\n onChange={handleChange}\r\n className={cn(\r\n 'checkbox__input',\r\n when(!clickable, 'checkbox__input--no-events'),\r\n )}\r\n {...fieldAttrs}\r\n />\r\n {label ? (\r\n <label className=\"checkbox__label\" htmlFor={inputId}>\r\n {label}\r\n </label>\r\n ) : null}\r\n </div>\r\n );\r\n },\r\n);\r\n"],"mappings":";;;;;;AA6BA,MAAM,aACJ,KACA,SACG;CACH,IAAI,OAAO,QAAQ,YAAY;EAC7B,IAAI,IAAI;EACR;CACF;CAEA,IAAI,KAAK,IAAI,UAAU;AACzB;AAEA,MAAM,oBACJ,WACA,cACG;CAEH,OADc,CAAC,WAAW,SAAS,CAAC,CAAC,QAAO,SAAQ,QAAQ,IAAI,CAAC,CAAC,CAAC,KAAK,GAC7D,KAAK,KAAA;AAClB;AAEA,MAAa,gBAAgB,WAC3B,SAAS,cACP,EACE,WACA,IACA,OACA,OACA,UACA,YAAY,MACZ,gBAAgB,OAChB,SACA,UACA,GAAG,SAEL,KACA;CACA,MAAM,QAAQ,gBAAgB;CAC9B,MAAM,cAAc,OAAO;CAC3B,MAAM,SAAS,MAAM;CACrB,MAAM,UAAU,OAAO,MAAM,MAAM;CACnC,MAAM,WAAW,OAAyB,IAAI;CAC9C,MAAM,YAAY,QAAQ,KAAK,KAAK,QAAQ,OAAO,OAAO;CAE1D,MAAM,SAAS,aACZ,SAAkC;EACjC,SAAS,UAAU;EACnB,UAAU,KAAK,IAAI;CACrB,GACA,CAAC,GAAG,CACN;CAEA,gBAAgB;EACd,IAAI,SAAS,SAAS,SAAS,QAAQ,gBAAgB;CACzD,GAAG,CAAC,aAAa,CAAC;CAGlB,gBAAgB;EACd,MAAM,OAAO,SAAS;EACtB,IAAI,MAAM,cAAc,KAAK,UAAU,OAAO,EAAE;CAClD,GAAG,CAAC,SAAS,WAAW,CAAC;CAEzB,MAAM,gBAAgB,UAAyC;EAC7D,IAAI,YAAY,KAAA,GACd,cAAc,MAAM,OAAO,UAAU,OAAO,EAAE;EAEhD,WAAW,KAAK;CAClB;CAEA,MAAM,cAAc,QAChB,iBAAiB,MAAM,aAAa,MAAM,mBAAmB,IAC7D,KAAA;CAEJ,MAAM,aAAoD,CAAC;CAE3D,IAAI,OAAO,UAAU;EACnB,WAAW,WAAW;EACtB,WAAW,mBAAmB;CAChC;CAEA,IAAI,WAAW,WAAW,kBAAkB;CAC5C,IAAI,aAAa,WAAW,sBAAsB;CAClD,IAAI,OAAO,SAAS,WAAW,uBAAuB,MAAM;CAE5D,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,YAAY,SAAS;EAAxC,UAAA,CACE,oBAAC,SAAD;GACE,GAAI;GACJ,KAAK;GACL,MAAK;GACL,IAAI;GACM;GACV,GAAK,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;GAC5C,UAAU;GACV,WAAW,GACT,mBACA,KAAK,CAAC,WAAW,4BAA4B,CAC/C;GACA,GAAI;EACL,CAAA,GACA,QACC,oBAAC,SAAD;GAAO,WAAU;GAAkB,SAAS;GACzC,UAAA;EACI,CAAA,IACL,IACD;;AAET,CACF"}
1
+ {"version":3,"file":"checkbox.js","names":[],"sources":["../../../src/components/checkbox/checkbox.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n type ChangeEvent,\n type InputHTMLAttributes,\n type ReactNode,\n type Ref,\n} from 'react';\n\nimport { useFieldControl } from '@/components/field/field-context';\nimport { cn, when } from '@/lib/cn';\nimport './checkbox.scss';\n\nexport interface CheckboxInputProps extends InputHTMLAttributes<HTMLInputElement> {\n label?: ReactNode;\n /** Красная рамка. Внутри `Field` состоянием ошибки распоряжается он. */\n error?: boolean;\n /** «Выбрать все»: IDL `indeterminate`, React его атрибутом не прокидывает. */\n indeterminate?: boolean;\n /**\n * false — `pointer-events: none` на input (`checkbox__input--no-events`).\n * Клик по лейблу по-прежнему переключает.\n */\n clickable?: boolean;\n}\n\nconst assignRef = (\n ref: Ref<HTMLInputElement> | null,\n node: HTMLInputElement | null,\n) => {\n if (typeof ref === 'function') {\n ref(node);\n return;\n }\n\n if (ref) ref.current = node;\n};\n\nconst mergeDescribedBy = (\n fromField: string | undefined,\n fromProps: string | undefined,\n) => {\n const value = [fromField, fromProps].filter(part => Boolean(part)).join(' ');\n return value || undefined;\n};\n\nexport const CheckboxInput = forwardRef<HTMLInputElement, CheckboxInputProps>(\n function CheckboxInput(\n {\n className,\n id,\n label,\n error,\n disabled,\n clickable = true,\n indeterminate = false,\n checked,\n onChange,\n ...props\n },\n ref,\n ) {\n const field = useFieldControl();\n const reportValue = field?.reportValue;\n const autoId = useId();\n const inputId = field?.id ?? id ?? autoId;\n const inputRef = useRef<HTMLInputElement>(null);\n const isInvalid = Boolean(error) || Boolean(field?.invalid);\n\n const setRef = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n assignRef(ref, node);\n },\n [ref],\n );\n\n useEffect(() => {\n if (inputRef.current) inputRef.current.indeterminate = indeterminate;\n }, [indeterminate]);\n\n // Field ждёт строку: отдаём то же, что ушло бы в FormData — 'on' или пусто.\n useEffect(() => {\n const node = inputRef.current;\n if (node) reportValue?.(node.checked ? 'on' : '');\n }, [checked, reportValue]);\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (checked === undefined) {\n reportValue?.(event.target.checked ? 'on' : '');\n }\n onChange?.(event);\n };\n\n const describedBy = field\n ? mergeDescribedBy(field.describedBy, props['aria-describedby'])\n : undefined;\n\n const fieldAttrs: InputHTMLAttributes<HTMLInputElement> = {};\n\n if (field?.required) {\n fieldAttrs.required = true;\n fieldAttrs['aria-required'] = true;\n }\n\n if (isInvalid) fieldAttrs['aria-invalid'] = true;\n if (describedBy) fieldAttrs['aria-describedby'] = describedBy;\n if (field?.errorId) fieldAttrs['aria-errormessage'] = field.errorId;\n\n return (\n <div className={cn('checkbox', className)}>\n <input\n {...props}\n ref={setRef}\n type=\"checkbox\"\n id={inputId}\n disabled={disabled}\n {...(checked !== undefined ? { checked } : {})}\n onChange={handleChange}\n className={cn(\n 'checkbox__input',\n when(!clickable, 'checkbox__input--no-events'),\n )}\n {...fieldAttrs}\n />\n {label ? (\n <label className=\"checkbox__label\" htmlFor={inputId}>\n {label}\n </label>\n ) : null}\n </div>\n );\n },\n);\n"],"mappings":";;;;;;AA6BA,MAAM,aACJ,KACA,SACG;CACH,IAAI,OAAO,QAAQ,YAAY;EAC7B,IAAI,IAAI;EACR;CACF;CAEA,IAAI,KAAK,IAAI,UAAU;AACzB;AAEA,MAAM,oBACJ,WACA,cACG;CAEH,OADc,CAAC,WAAW,SAAS,CAAC,CAAC,QAAO,SAAQ,QAAQ,IAAI,CAAC,CAAC,CAAC,KAAK,GAC7D,KAAK,KAAA;AAClB;AAEA,MAAa,gBAAgB,WAC3B,SAAS,cACP,EACE,WACA,IACA,OACA,OACA,UACA,YAAY,MACZ,gBAAgB,OAChB,SACA,UACA,GAAG,SAEL,KACA;CACA,MAAM,QAAQ,gBAAgB;CAC9B,MAAM,cAAc,OAAO;CAC3B,MAAM,SAAS,MAAM;CACrB,MAAM,UAAU,OAAO,MAAM,MAAM;CACnC,MAAM,WAAW,OAAyB,IAAI;CAC9C,MAAM,YAAY,QAAQ,KAAK,KAAK,QAAQ,OAAO,OAAO;CAE1D,MAAM,SAAS,aACZ,SAAkC;EACjC,SAAS,UAAU;EACnB,UAAU,KAAK,IAAI;CACrB,GACA,CAAC,GAAG,CACN;CAEA,gBAAgB;EACd,IAAI,SAAS,SAAS,SAAS,QAAQ,gBAAgB;CACzD,GAAG,CAAC,aAAa,CAAC;CAGlB,gBAAgB;EACd,MAAM,OAAO,SAAS;EACtB,IAAI,MAAM,cAAc,KAAK,UAAU,OAAO,EAAE;CAClD,GAAG,CAAC,SAAS,WAAW,CAAC;CAEzB,MAAM,gBAAgB,UAAyC;EAC7D,IAAI,YAAY,KAAA,GACd,cAAc,MAAM,OAAO,UAAU,OAAO,EAAE;EAEhD,WAAW,KAAK;CAClB;CAEA,MAAM,cAAc,QAChB,iBAAiB,MAAM,aAAa,MAAM,mBAAmB,IAC7D,KAAA;CAEJ,MAAM,aAAoD,CAAC;CAE3D,IAAI,OAAO,UAAU;EACnB,WAAW,WAAW;EACtB,WAAW,mBAAmB;CAChC;CAEA,IAAI,WAAW,WAAW,kBAAkB;CAC5C,IAAI,aAAa,WAAW,sBAAsB;CAClD,IAAI,OAAO,SAAS,WAAW,uBAAuB,MAAM;CAE5D,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,YAAY,SAAS;EAAxC,UAAA,CACE,oBAAC,SAAD;GACE,GAAI;GACJ,KAAK;GACL,MAAK;GACL,IAAI;GACM;GACV,GAAK,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;GAC5C,UAAU;GACV,WAAW,GACT,mBACA,KAAK,CAAC,WAAW,4BAA4B,CAC/C;GACA,GAAI;EACL,CAAA,GACA,QACC,oBAAC,SAAD;GAAO,WAAU;GAAkB,SAAS;GACzC,UAAA;EACI,CAAA,IACL,IACD;;AAET,CACF"}