@companix/uikit 0.0.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 (124) hide show
  1. package/.eslintrc +54 -0
  2. package/declaration.d.ts +4 -0
  3. package/index.html +12 -0
  4. package/package.json +66 -0
  5. package/playground/App.tsx +166 -0
  6. package/playground/Example.tsx +14 -0
  7. package/playground/Test.tsx +44 -0
  8. package/playground/animation-test-1/index.scss +20 -0
  9. package/playground/animation-test-1/index.tsx +17 -0
  10. package/playground/animation-test-2/index.scss +62 -0
  11. package/playground/animation-test-2/index.tsx +32 -0
  12. package/playground/bootstrap.tsx +19 -0
  13. package/playground/buttons/index.tsx +132 -0
  14. package/playground/checkbox/index.tsx +64 -0
  15. package/playground/date-input/index.tsx +45 -0
  16. package/playground/date-picker/index.tsx +41 -0
  17. package/playground/dialog/index.tsx +92 -0
  18. package/playground/dialog-alert/index.tsx +47 -0
  19. package/playground/drawer/index.tsx +55 -0
  20. package/playground/index.css +33 -0
  21. package/playground/index.scss +270 -0
  22. package/playground/input/index.tsx +112 -0
  23. package/playground/number-inputs/index.tsx +50 -0
  24. package/playground/popovers/index.tsx +70 -0
  25. package/playground/radio-group/index.tsx +69 -0
  26. package/playground/select/index.tsx +72 -0
  27. package/playground/select-tags/index.tsx +36 -0
  28. package/playground/styles.scss +2 -0
  29. package/playground/switch/index.tsx +44 -0
  30. package/playground/tabs/index.tsx +16 -0
  31. package/playground/test.scss +0 -0
  32. package/playground/text-area/index.tsx +17 -0
  33. package/playground/text-input/index.tsx +12 -0
  34. package/playground/toaster/index.tsx +156 -0
  35. package/playground/tooltip/index.tsx +26 -0
  36. package/src/Button/Button.scss +128 -0
  37. package/src/Button/index.tsx +72 -0
  38. package/src/ButtonGroup/ButtonGroup.scss +18 -0
  39. package/src/ButtonGroup/index.tsx +20 -0
  40. package/src/Checkbox/Checkbox.scss +115 -0
  41. package/src/Checkbox/index.tsx +46 -0
  42. package/src/Countdown/index.tsx +54 -0
  43. package/src/DateInput/DateInput.scss +11 -0
  44. package/src/DateInput/index.tsx +96 -0
  45. package/src/DatePicker/Calendar.scss +125 -0
  46. package/src/DatePicker/Calendar.tsx +157 -0
  47. package/src/DatePicker/CalendarHeader.tsx +139 -0
  48. package/src/DatePicker/DatePicker.scss +0 -0
  49. package/src/DatePicker/index.tsx +177 -0
  50. package/src/Dialog/Dialog.scss +25 -0
  51. package/src/Dialog/Popup.scss +55 -0
  52. package/src/Dialog/index.tsx +31 -0
  53. package/src/DialogAlert/Alert.scss +52 -0
  54. package/src/DialogAlert/Alert.tsx +78 -0
  55. package/src/DialogAlert/Viewport.tsx +52 -0
  56. package/src/DialogAlert/index.tsx +37 -0
  57. package/src/Drawer/Drawer.scss +112 -0
  58. package/src/Drawer/index.tsx +46 -0
  59. package/src/File/index.tsx +60 -0
  60. package/src/Form/Form.scss +70 -0
  61. package/src/Form/Input.scss +24 -0
  62. package/src/Form/index.tsx +131 -0
  63. package/src/Icon/icon.scss +18 -0
  64. package/src/Icon/index.tsx +43 -0
  65. package/src/LoadButton/index.tsx +17 -0
  66. package/src/NumberInput/index.tsx +74 -0
  67. package/src/OptionItem/Option.scss +89 -0
  68. package/src/OptionItem/OptionItem.tsx +49 -0
  69. package/src/OptionItem/OptionsList.tsx +26 -0
  70. package/src/Popover/Popover.scss +80 -0
  71. package/src/Popover/index.tsx +117 -0
  72. package/src/Radio/Radio.scss +148 -0
  73. package/src/Radio/index.tsx +68 -0
  74. package/src/Scrollable/ImitateScroll.tsx +141 -0
  75. package/src/Scrollable/Scrollable.scss +50 -0
  76. package/src/Scrollable/index.tsx +141 -0
  77. package/src/Select/Select.scss +80 -0
  78. package/src/Select/SelectInput.tsx +131 -0
  79. package/src/Select/index.tsx +134 -0
  80. package/src/SelectTags/SelectTags.scss +66 -0
  81. package/src/SelectTags/index.tsx +192 -0
  82. package/src/Spinner/Spinner.scss +14 -0
  83. package/src/Spinner/index.tsx +19 -0
  84. package/src/Stepper/StepperInput.scss +35 -0
  85. package/src/Stepper/index.tsx +76 -0
  86. package/src/Switch/Switch.scss +102 -0
  87. package/src/Switch/index.tsx +49 -0
  88. package/src/Tabs/Tabs.scss +58 -0
  89. package/src/Tabs/index.tsx +89 -0
  90. package/src/TextArea/TextArea.scss +34 -0
  91. package/src/TextArea/index.tsx +51 -0
  92. package/src/Toaster/RemoveListener.tsx +11 -0
  93. package/src/Toaster/Toast.tsx +69 -0
  94. package/src/Toaster/Toaster.scss +151 -0
  95. package/src/Toaster/Viewport.tsx +117 -0
  96. package/src/Toaster/index.tsx +52 -0
  97. package/src/Tooltip/Tooltip.scss +28 -0
  98. package/src/Tooltip/index.tsx +33 -0
  99. package/src/__hooks/use-frooze-closing.ts +51 -0
  100. package/src/__hooks/use-loading.ts +34 -0
  101. package/src/__hooks/use-local-storage.ts +19 -0
  102. package/src/__hooks/use-popover-position.ts +24 -0
  103. package/src/__hooks/use-previos.ts +25 -0
  104. package/src/__hooks/use-resize.ts +41 -0
  105. package/src/__hooks/use-scrollbox.ts +45 -0
  106. package/src/__hooks/use-stepper-input.ts +82 -0
  107. package/src/__hooks/use-update.ts +19 -0
  108. package/src/__hooks/useCalendar.ts +104 -0
  109. package/src/__hooks/useCalendarOptions-copy.ts +87 -0
  110. package/src/__hooks/useCalendarOptions.ts +68 -0
  111. package/src/__libs/calendar.ts +175 -0
  112. package/src/__utils/utils.ts +137 -0
  113. package/src/css.scss +120 -0
  114. package/src/index.scss +22 -0
  115. package/src/index.ts +36 -0
  116. package/src/mixins.scss +99 -0
  117. package/src/theme.scss +103 -0
  118. package/src/types.ts +14 -0
  119. package/tailwind.config.js +91 -0
  120. package/themes/classic/animations.scss +179 -0
  121. package/themes/classic/classic.scss +493 -0
  122. package/tsconfig.json +27 -0
  123. package/vite.build.ts +35 -0
  124. package/vite.config.ts +33 -0
@@ -0,0 +1,43 @@
1
+ import classNames from 'classnames'
2
+ import { IconDefinition } from '@fortawesome/free-solid-svg-icons'
3
+ import { forwardRef } from 'react'
4
+
5
+ export interface IconProps {
6
+ icon: IconDefinition
7
+ size?: 'xxxs' | 'xxs' | 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl' | 'xxxl'
8
+ className?: string
9
+ }
10
+
11
+ export const Icon = forwardRef<SVGSVGElement, IconProps>(
12
+ ({ icon, className, size = 'm', ...restProps }, ref) => {
13
+ const [width, height, , , svgPathData] = icon.icon
14
+
15
+ return (
16
+ <svg
17
+ ref={ref}
18
+ data-prefix={icon.prefix}
19
+ data-icon={icon.iconName}
20
+ viewBox={`0 0 ${width} ${height}`}
21
+ className={classNames(`icon icon-size-${size}`, className)}
22
+ {...restProps}
23
+ role="img"
24
+ >
25
+ <Paths paths={svgPathData} />
26
+ </svg>
27
+ )
28
+ }
29
+ )
30
+
31
+ const Paths = ({ paths }: { paths: string[] | string }) => {
32
+ if (Array.isArray(paths)) {
33
+ return (
34
+ <g>
35
+ {paths.map((d, i) => (
36
+ <path key={`-d-${i}`} fill="currentColor" d={d} />
37
+ ))}
38
+ </g>
39
+ )
40
+ }
41
+
42
+ return <path fill="currentColor" d={paths} />
43
+ }
@@ -0,0 +1,17 @@
1
+ import { Button, ButtonProps } from '../Button'
2
+ import { UseLoadingProps, useLoading } from '../__hooks/use-loading'
3
+
4
+ export interface LoadButtonProps extends UseLoadingProps, Omit<ButtonProps, 'onClick'> {}
5
+
6
+ export const LoadButton = ({ onClick, appearance = 'primary', ...rest }: LoadButtonProps) => {
7
+ const { isLoading, isError, handleClick } = useLoading({ onClick })
8
+
9
+ return (
10
+ <Button
11
+ appearance={isError ? 'negative' : appearance}
12
+ {...rest}
13
+ loading={isLoading}
14
+ onClick={handleClick}
15
+ />
16
+ )
17
+ }
@@ -0,0 +1,74 @@
1
+ import { useRef, useState } from 'react'
2
+ import { Form, FormProps } from '../Form'
3
+
4
+ export interface NumberInputProps extends Omit<FormProps, 'value' | 'onChange'> {
5
+ value: number | null
6
+ onChange: (value: number | null) => void
7
+ }
8
+
9
+ export const NumberInput = ({ value, onChange, ...props }: NumberInputProps) => {
10
+ const [, rerender] = useState([])
11
+ const input = useRef<string>(getInputValue(value))
12
+
13
+ if (+input.current !== value) {
14
+ input.current = getInputValue(value)
15
+ }
16
+
17
+ return (
18
+ <Form
19
+ {...props}
20
+ value={input.current}
21
+ onChange={(e) => {
22
+ const source = (e.currentTarget.value as string).trim()
23
+
24
+ if (source === '') {
25
+ input.current = ''
26
+ return onChange(null)
27
+ }
28
+
29
+ if (source.startsWith('.')) {
30
+ return
31
+ }
32
+
33
+ const numbersigns = source.replace('.', '').split('')
34
+
35
+ if (numbersigns.some((symbol) => isNaN(parseInt(symbol)))) {
36
+ return
37
+ }
38
+
39
+ input.current = clean(source.split(''))
40
+
41
+ if (+input.current === value) {
42
+ return rerender([])
43
+ }
44
+
45
+ onChange(+input.current)
46
+ }}
47
+ />
48
+ )
49
+ }
50
+
51
+ const getInputValue = (value: number | null) => {
52
+ return value === null ? '' : value.toString()
53
+ }
54
+
55
+ const clean = (signs: string[]) => {
56
+ const result = [...signs]
57
+ const source = [...signs]
58
+
59
+ if (source.every((value) => value === '0')) {
60
+ return '0'
61
+ }
62
+
63
+ for (let i = 0; i < source.length; i++) {
64
+ if (source[i] !== '0') {
65
+ break
66
+ }
67
+
68
+ if (source[i] === '0' && source[i + 1] !== '.') {
69
+ result.shift()
70
+ }
71
+ }
72
+
73
+ return result.join('')
74
+ }
@@ -0,0 +1,89 @@
1
+ @use '../mixins.scss';
2
+
3
+ .option-list {
4
+ display: flex;
5
+ flex-direction: column;
6
+
7
+ @include mixins.use-styles(option, list);
8
+ }
9
+
10
+ .option {
11
+ display: flex;
12
+ align-items: center;
13
+
14
+ @include mixins.use-styles(option);
15
+
16
+ &-icon {
17
+ @include mixins.use-styles(option, icon);
18
+
19
+ svg {
20
+ @include mixins.use-size(option, icon, size);
21
+ }
22
+ }
23
+
24
+ &-content {
25
+ display: flex;
26
+ flex-direction: column;
27
+ flex-grow: 1;
28
+ min-width: 0;
29
+ max-width: 100%;
30
+
31
+ &-inner {
32
+ @include mixins.use-styles(option, content, layout);
33
+ }
34
+ }
35
+
36
+ &-title {
37
+ word-break: break-word;
38
+ }
39
+
40
+ &-label {
41
+ @include mixins.use-styles(option, label);
42
+ }
43
+
44
+ &-check {
45
+ @include mixins.use-styles(option, check);
46
+
47
+ svg {
48
+ @include mixins.use-size(option, check, size);
49
+ }
50
+ }
51
+
52
+ & > * {
53
+ margin-right: 8px;
54
+ }
55
+
56
+ & > :last-child {
57
+ margin-right: 0;
58
+ }
59
+
60
+ &:not([data-disabled]) {
61
+ cursor: pointer;
62
+
63
+ &:hover {
64
+ @include mixins.use-styles(option, hover);
65
+ }
66
+
67
+ &:active {
68
+ @include mixins.use-styles(option, active);
69
+ }
70
+ }
71
+
72
+ &[data-selected] {
73
+ @include mixins.use-styles(option, selected);
74
+ }
75
+
76
+ &[data-disabled] {
77
+ user-select: none;
78
+
79
+ @include mixins.use-styles(option, disabled);
80
+ }
81
+
82
+ &[data-minimal] {
83
+ @include mixins.use-styles(option, minimal);
84
+
85
+ &[data-selected] {
86
+ @include mixins.use-styles(option, minimal, selected);
87
+ }
88
+ }
89
+ }
@@ -0,0 +1,49 @@
1
+ import cn from 'classnames'
2
+
3
+ import { Icon } from '../Icon'
4
+ import { attr } from '@companix/utils-browser'
5
+ import { forwardRef } from 'react'
6
+ import { faCheck } from '@fortawesome/free-solid-svg-icons'
7
+ import { Option } from '../types'
8
+
9
+ interface OptionProps
10
+ extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'>,
11
+ Omit<Option<unknown>, 'value'> {
12
+ active?: boolean
13
+ minimal?: boolean
14
+ }
15
+
16
+ export const OptionItem = forwardRef<HTMLDivElement, OptionProps>(
17
+ ({ title, icon, active, label, disabled, minimal, onClick, className, ...rest }, ref) => {
18
+ const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
19
+ if (!disabled) {
20
+ onClick?.(event)
21
+ }
22
+ }
23
+
24
+ return (
25
+ <div
26
+ ref={ref}
27
+ {...rest}
28
+ className={cn('option', className)}
29
+ data-selected={attr(active)}
30
+ data-disabled={attr(disabled)}
31
+ data-minimal={attr(minimal)}
32
+ onClick={handleClick}
33
+ >
34
+ <div className="option-content">
35
+ {icon && <div className="option-icon">{icon}</div>}
36
+ <div className="option-content-layout">
37
+ <div className="option-title">{title}</div>
38
+ {label && <div className="option-label">{label}</div>}
39
+ </div>
40
+ </div>
41
+ {active && !minimal && (
42
+ <div className="option-check">
43
+ <Icon icon={faCheck} />
44
+ </div>
45
+ )}
46
+ </div>
47
+ )
48
+ }
49
+ )
@@ -0,0 +1,26 @@
1
+ import { Scrollable } from '../Scrollable'
2
+
3
+ interface MenuProps {
4
+ children: React.ReactNode
5
+ maxHeight?: number
6
+ scrollboxRef?: React.Ref<HTMLDivElement>
7
+ optionsWrapperRef?: React.Ref<HTMLDivElement>
8
+ }
9
+
10
+ export const OptionsList = ({ children, maxHeight, scrollboxRef, optionsWrapperRef }: MenuProps) => {
11
+ return (
12
+ <Scrollable
13
+ ref={scrollboxRef}
14
+ implementation="inner"
15
+ padding={10}
16
+ thumbPadding={3}
17
+ thumbColor="#0000002b"
18
+ maxHeight={maxHeight}
19
+ scrollY
20
+ >
21
+ <div className="option-list" ref={optionsWrapperRef}>
22
+ {children}
23
+ </div>
24
+ </Scrollable>
25
+ )
26
+ }
@@ -0,0 +1,80 @@
1
+ @use '../mixins.scss';
2
+
3
+ .popover {
4
+ outline: none;
5
+ @include mixins.use-styles(popover);
6
+
7
+ &[data-match-target='width'] {
8
+ width: var(--radix-popover-trigger-width);
9
+ }
10
+
11
+ &[data-match-target='min-width'] {
12
+ min-width: var(--radix-popover-trigger-width);
13
+ }
14
+
15
+ &-content {
16
+ position: relative;
17
+ display: flex;
18
+ flex-direction: column;
19
+
20
+ &[data-fit-max-height] {
21
+ max-height: var(--radix-popover-content-available-height);
22
+ }
23
+
24
+ @include mixins.use-styles(popover, content);
25
+ }
26
+
27
+ &-arrow {
28
+ position: relative;
29
+
30
+ &-icon {
31
+ position: relative;
32
+ }
33
+
34
+ &-border {
35
+ fill: #111418;
36
+ fill-opacity: 0.1;
37
+ }
38
+
39
+ &-fill {
40
+ fill: mixins.get-var-name(popover, content, background);
41
+ }
42
+
43
+ &:before {
44
+ border-radius: 1px;
45
+ content: '';
46
+ display: block;
47
+ position: absolute;
48
+ transform: rotate(45deg);
49
+ height: 20px;
50
+ margin: 5px;
51
+ width: 20px;
52
+ box-shadow: 1px 1px 6px rgba(17, 20, 24, 0.2);
53
+ margin-top: -14px;
54
+ }
55
+ }
56
+
57
+ &[data-appearance='default'] {
58
+ &[data-state='open'] {
59
+ transform-origin: var(--radix-popover-content-transform-origin);
60
+ @include mixins.use-styles(popover, default, in);
61
+ }
62
+
63
+ &[data-state='closed'] {
64
+ transform-origin: var(--radix-popover-content-transform-origin);
65
+ @include mixins.use-styles(popover, default, out);
66
+ }
67
+ }
68
+
69
+ &[data-appearance='minimal'] {
70
+ &[data-state='open'] {
71
+ transform-origin: var(--radix-popover-content-transform-origin);
72
+ @include mixins.use-styles(popover, minimal, in);
73
+ }
74
+
75
+ &[data-state='closed'] {
76
+ transform-origin: var(--radix-popover-content-transform-origin);
77
+ @include mixins.use-styles(popover, minimal, out);
78
+ }
79
+ }
80
+ }
@@ -0,0 +1,117 @@
1
+ import * as PopoverPrimitive from '@radix-ui/react-popover'
2
+ import { attr } from '@companix/utils-browser'
3
+ import classNames from 'classnames'
4
+ import { forwardRef, useRef } from 'react'
5
+
6
+ export type Align = 'start' | 'center' | 'end'
7
+ export type Side = 'top' | 'right' | 'bottom' | 'left'
8
+
9
+ export interface PopoverProps {
10
+ children: React.ReactNode
11
+ open?: boolean
12
+ triggerRef?: React.Ref<HTMLButtonElement>
13
+ triggerProps?: React.ButtonHTMLAttributes<HTMLButtonElement>
14
+ onOpenChange?: (open: boolean) => void
15
+ content: ({ close }: { close: () => void }) => React.ReactNode
16
+ onAnimationEnd?: () => void
17
+ onAnimationStart?: () => void
18
+ onOpenAutoFocus?: (event: Event) => void
19
+ onCloseAutoFocus?: (event: Event) => void
20
+ side?: Side
21
+ align?: Align
22
+ showArrows?: boolean
23
+ minimal?: boolean
24
+ sideOffset?: number
25
+ matchTarget?: 'width' | 'min-width'
26
+ className?: string
27
+ fitMaxHeight?: boolean
28
+ disabled?: boolean
29
+ }
30
+
31
+ export const Popover = forwardRef<HTMLDivElement, PopoverProps>((props, ref) => {
32
+ const {
33
+ children,
34
+ sideOffset,
35
+ matchTarget,
36
+ onAnimationEnd,
37
+ onAnimationStart,
38
+ onOpenAutoFocus,
39
+ onCloseAutoFocus,
40
+ triggerRef,
41
+ triggerProps,
42
+ open,
43
+ content,
44
+ onOpenChange,
45
+ align,
46
+ disabled,
47
+ minimal,
48
+ className,
49
+ fitMaxHeight = true,
50
+ side,
51
+ showArrows
52
+ } = props
53
+
54
+ const buttonRef = useRef<HTMLButtonElement>(null)
55
+
56
+ const close = () => {
57
+ if (buttonRef.current) {
58
+ buttonRef.current.click()
59
+ }
60
+ }
61
+
62
+ const handleOpen = (e: React.MouseEvent) => {
63
+ if (disabled) {
64
+ e.preventDefault()
65
+ }
66
+ }
67
+
68
+ return (
69
+ <PopoverPrimitive.Root open={open} onOpenChange={onOpenChange}>
70
+ <PopoverPrimitive.Trigger ref={triggerRef} {...triggerProps} onClick={handleOpen} asChild>
71
+ {children}
72
+ </PopoverPrimitive.Trigger>
73
+ <PopoverPrimitive.Portal>
74
+ <PopoverPrimitive.Content
75
+ ref={ref}
76
+ className={classNames('popover', className)}
77
+ side={side}
78
+ align={align}
79
+ data-appearance={minimal ? 'minimal' : 'default'}
80
+ data-match-target={matchTarget}
81
+ sideOffset={sideOffset ?? 6}
82
+ avoidCollisions
83
+ arrowPadding={10}
84
+ onAnimationStart={onAnimationStart}
85
+ onAnimationEnd={onAnimationEnd}
86
+ onOpenAutoFocus={onOpenAutoFocus}
87
+ onCloseAutoFocus={onCloseAutoFocus}
88
+ >
89
+ <PopoverPrimitive.Close ref={buttonRef} style={{ display: 'none' }} />
90
+ {showArrows && (
91
+ <PopoverPrimitive.Arrow width={30} height={11} asChild>
92
+ <div className="popover-arrow">
93
+ <svg className="popover-arrow-icon" viewBox="0 0 30 11" width={30} height={11}>
94
+ <path
95
+ className="popover-arrow-border"
96
+ d="M 18.112 -2.704 C 19.127 -3.64 19.999 -5.626 19.999 -7.001 L 19.999 18.999 C 19.999 17.621 19.131 15.642 18.111 14.702 L 10.927 8.084 C 9.69 6.944 9.694 5.05 10.927 3.914 L 18.112 -2.704 Z"
97
+ style={{ transformBox: 'fill-box', transformOrigin: '50% 50%' }}
98
+ transform="matrix(0, -1, 1, 0, 0.000001, 0)"
99
+ />
100
+ <path
101
+ className="popover-arrow-fill"
102
+ d="M 17.789 -2.965 C 19.009 -4.09 19.999 -6.341 19.999 -7.995 L 19.999 -10.001 L 19.999 19.999 L 19.999 17.994 C 19.999 16.34 19.016 14.094 17.789 12.964 L 10.606 6.348 C 9.796 5.602 9.804 4.388 10.606 3.648 L 17.789 -2.966 L 17.789 -2.965 Z"
103
+ style={{ transformBox: 'fill-box', transformOrigin: '50% 50%' }}
104
+ transform="matrix(0, -1, 1, 0, 0, 0)"
105
+ />
106
+ </svg>
107
+ </div>
108
+ </PopoverPrimitive.Arrow>
109
+ )}
110
+ <div className="popover-content" data-fit-max-height={attr(fitMaxHeight)}>
111
+ {content({ close })}
112
+ </div>
113
+ </PopoverPrimitive.Content>
114
+ </PopoverPrimitive.Portal>
115
+ </PopoverPrimitive.Root>
116
+ )
117
+ })
@@ -0,0 +1,148 @@
1
+ @use '../mixins.scss';
2
+
3
+ .radio {
4
+ display: inline-table;
5
+ -webkit-user-select: none;
6
+ -moz-user-select: none;
7
+ -ms-user-select: none;
8
+ user-select: none;
9
+ -webkit-tap-highlight-color: transparent;
10
+ -ms-touch-action: manipulation;
11
+ touch-action: manipulation;
12
+ max-width: max-content;
13
+
14
+ @include mixins.use-styles(radio);
15
+
16
+ &:not([data-required]):not([data-disabled]):hover {
17
+ .radio-box[data-state='unchecked'] {
18
+ @include mixins.use-styles(radio, box, hover);
19
+ }
20
+ }
21
+
22
+ &:not([data-required]):not([data-disabled]):active {
23
+ .radio-box[data-state='unchecked'] {
24
+ @include mixins.use-styles(radio, box, active);
25
+ }
26
+ }
27
+
28
+ &[data-disabled] {
29
+ @include mixins.use-styles(radio, disabled);
30
+ }
31
+
32
+ &[data-required] {
33
+ @include mixins.use-styles(radio, required);
34
+
35
+ .radio-box {
36
+ &::before {
37
+ content: ' ';
38
+ position: absolute;
39
+ width: 100%;
40
+ height: 100%;
41
+ left: 0;
42
+
43
+ @include mixins.use-styles(radio, required, box);
44
+ border-radius: mixins.get-var-name(radio, box, border-radius);
45
+ }
46
+ }
47
+ }
48
+
49
+ &[data-size='sm'] {
50
+ @include mixins.use-styles(radio, size, sm);
51
+
52
+ .radio-box {
53
+ @include mixins.use-size(radio, size, sm, box);
54
+ }
55
+
56
+ .radio-mark {
57
+ @include mixins.use-size(radio, size, sm, mark);
58
+ }
59
+ }
60
+
61
+ &[data-size='md'] {
62
+ @include mixins.use-styles(radio, size, md);
63
+
64
+ .radio-box {
65
+ @include mixins.use-size(radio, size, md, box);
66
+ }
67
+
68
+ .radio-mark {
69
+ @include mixins.use-size(radio, size, md, mark);
70
+ }
71
+ }
72
+
73
+ &-box {
74
+ cursor: pointer;
75
+ outline: none;
76
+ transition: background-color 0.1s linear;
77
+ position: relative;
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: center;
81
+
82
+ @include mixins.use-styles(radio, box);
83
+
84
+ &[data-disabled] {
85
+ cursor: default;
86
+ }
87
+
88
+ &:after {
89
+ visibility: hidden;
90
+ content: '\00A0';
91
+ }
92
+
93
+ &[data-state='checked'] {
94
+ @include mixins.use-styles(radio, box, checked);
95
+ }
96
+ }
97
+
98
+ &-mark {
99
+ position: absolute;
100
+ @include mixins.use-styles(radio, mark);
101
+
102
+ &[data-state='checked'] {
103
+ @include mixins.use-styles(radio, mark, in);
104
+ }
105
+
106
+ &[data-state='unchecked'] {
107
+ @include mixins.use-styles(radio, mark, out);
108
+ }
109
+ }
110
+
111
+ &-label {
112
+ cursor: pointer;
113
+ display: table-cell;
114
+ word-break: break-word;
115
+
116
+ &[data-disabled] {
117
+ cursor: default;
118
+ }
119
+
120
+ @include mixins.use-styles(radio, label);
121
+ }
122
+ }
123
+
124
+ .radio-group {
125
+ display: flex;
126
+ flex-direction: column;
127
+ @include mixins.use-styles(radio, group);
128
+ }
129
+
130
+ // .radio-icon {
131
+ // width: 16px;
132
+ // height: 16px;
133
+ // background-color: transparent;
134
+ // border: 1px solid #ffffff75;
135
+ // border-radius: 100px;
136
+
137
+ // &[data-checked] {
138
+ // background-color: #fff;
139
+ // }
140
+ // }
141
+
142
+ // .radio {
143
+ // display: flex;
144
+ // align-items: center;
145
+ // outline: none;
146
+ // cursor: pointer;
147
+ // gap: 6px;
148
+ // }