@phpsoftbox/react-softbox 0.2.0 → 0.4.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/README.md +81 -1
- package/dist/components/Button/Button.d.ts +3 -1
- package/dist/components/Button/Button.js +16 -17
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/FileUploader/FileUploader.d.ts +22 -0
- package/dist/components/FileUploader/FileUploader.js +156 -0
- package/dist/components/FileUploader/FileUploader.js.map +1 -0
- package/dist/components/FileUploader/FileUploader.module.css +142 -0
- package/dist/components/Input/Checkbox/Checkbox.d.ts +8 -0
- package/dist/components/Input/Checkbox/Checkbox.js +15 -0
- package/dist/components/Input/Checkbox/Checkbox.js.map +1 -0
- package/dist/components/Input/Checkbox/Checkbox.module.css +105 -0
- package/dist/components/Input/ErrorTooltip/ErrorTooltip.d.ts +12 -0
- package/dist/components/Input/ErrorTooltip/ErrorTooltip.js +25 -0
- package/dist/components/Input/ErrorTooltip/ErrorTooltip.js.map +1 -0
- package/dist/components/Input/ErrorTooltip/ErrorTooltip.module.css +31 -0
- package/dist/components/Input/Field.js +8 -1
- package/dist/components/Input/Field.js.map +1 -1
- package/dist/components/Input/FloatLabel/FloatLabel.module.css +11 -9
- package/dist/components/Input/FormField/FormField.d.ts +2 -0
- package/dist/components/Input/FormField/FormField.js +12 -1
- package/dist/components/Input/FormField/FormField.js.map +1 -1
- package/dist/components/Input/FormField/FormField.module.css +1 -0
- package/dist/components/Input/Input.d.ts +4 -0
- package/dist/components/Input/Input.js +4 -0
- package/dist/components/Input/Input.js.map +1 -1
- package/dist/components/Input/Input.module.css +8 -1
- package/dist/components/Input/Select/Select.d.ts +10 -5
- package/dist/components/Input/Select/Select.js +62 -16
- package/dist/components/Input/Select/Select.js.map +1 -1
- package/dist/components/Input/Select/Select.module.css +65 -23
- package/dist/components/Modal/Modal.d.ts +2 -1
- package/dist/components/Modal/Modal.js +18 -1
- package/dist/components/Modal/Modal.js.map +1 -1
- package/dist/components/Table/Table.d.ts +81 -0
- package/dist/components/Table/Table.js +240 -0
- package/dist/components/Table/Table.js.map +1 -0
- package/dist/components/Table/Table.module.css +236 -0
- package/dist/components/Tooltip/Tooltip.d.ts +33 -0
- package/dist/components/Tooltip/Tooltip.js +294 -0
- package/dist/components/Tooltip/Tooltip.js.map +1 -0
- package/dist/components/Tooltip/Tooltip.module.css +124 -0
- package/dist/{components/Button/Button.module.css → foundations/buttons.css} +47 -19
- package/dist/foundations/index.css +1 -0
- package/dist/foundations/tokens.css +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/docs/README.md +3 -1
- package/docs/forms.md +60 -0
- package/docs/layout.md +16 -0
- package/docs/overlays.md +2 -2
- package/docs/table.md +114 -0
- package/docs/tooltip.md +68 -0
- package/package.json +5 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
.tooltip {
|
|
2
|
+
position: fixed;
|
|
3
|
+
z-index: 1200;
|
|
4
|
+
pointer-events: none;
|
|
5
|
+
opacity: 0;
|
|
6
|
+
transform: translateY(6px) scale(0.98);
|
|
7
|
+
transition: opacity 0.16s ease, transform 0.16s ease;
|
|
8
|
+
will-change: opacity, transform;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.tooltip[data-state='open'] {
|
|
12
|
+
opacity: 1;
|
|
13
|
+
transform: translateY(0) scale(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.interactive {
|
|
17
|
+
pointer-events: auto;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.bubble {
|
|
21
|
+
max-width: var(--tooltip-max-width, 280px);
|
|
22
|
+
background: var(--tooltip-bg, var(--surface-panel));
|
|
23
|
+
color: var(--tooltip-color, var(--color-text));
|
|
24
|
+
border: 1px solid var(--tooltip-border, var(--color-line));
|
|
25
|
+
border-radius: var(--radius-sm);
|
|
26
|
+
box-shadow: var(--shadow-soft);
|
|
27
|
+
padding: var(--spacing-2) var(--spacing-3);
|
|
28
|
+
font-size: var(--font-size-2);
|
|
29
|
+
line-height: 1.4;
|
|
30
|
+
position: relative;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.variantDefault {
|
|
34
|
+
--tooltip-bg: var(--surface-panel);
|
|
35
|
+
--tooltip-border: var(--color-line);
|
|
36
|
+
--tooltip-color: var(--color-text);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.variantInfo {
|
|
40
|
+
--tooltip-bg: rgba(20, 42, 76, 0.95);
|
|
41
|
+
--tooltip-border: rgba(64, 110, 200, 0.65);
|
|
42
|
+
--tooltip-color: #cfe0ff;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.variantSuccess {
|
|
46
|
+
--tooltip-bg: rgba(16, 59, 42, 0.95);
|
|
47
|
+
--tooltip-border: rgba(47, 186, 122, 0.6);
|
|
48
|
+
--tooltip-color: #d3f6e4;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.variantWarning {
|
|
52
|
+
--tooltip-bg: rgba(64, 46, 18, 0.95);
|
|
53
|
+
--tooltip-border: rgba(246, 200, 106, 0.6);
|
|
54
|
+
--tooltip-color: #ffe6b3;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.variantDanger {
|
|
58
|
+
--tooltip-bg: rgba(64, 26, 26, 0.95);
|
|
59
|
+
--tooltip-border: rgba(255, 107, 107, 0.7);
|
|
60
|
+
--tooltip-color: #ffd2d2;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.bubble::after {
|
|
64
|
+
content: '';
|
|
65
|
+
position: absolute;
|
|
66
|
+
width: 10px;
|
|
67
|
+
height: 10px;
|
|
68
|
+
background: var(--tooltip-bg, var(--surface-panel));
|
|
69
|
+
border: 1px solid var(--tooltip-border, var(--color-line));
|
|
70
|
+
transform: rotate(45deg);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.bubble[data-placement='top']::after {
|
|
74
|
+
left: 50%;
|
|
75
|
+
bottom: -6px;
|
|
76
|
+
transform: translateX(-50%) rotate(45deg);
|
|
77
|
+
border-left: none;
|
|
78
|
+
border-top: none;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.bubble[data-placement='bottom']::after {
|
|
82
|
+
left: 50%;
|
|
83
|
+
top: -6px;
|
|
84
|
+
transform: translateX(-50%) rotate(45deg);
|
|
85
|
+
border-right: none;
|
|
86
|
+
border-bottom: none;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.bubble[data-placement='left']::after {
|
|
90
|
+
top: 50%;
|
|
91
|
+
right: -6px;
|
|
92
|
+
transform: translateY(-50%) rotate(45deg);
|
|
93
|
+
border-left: none;
|
|
94
|
+
border-bottom: none;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.bubble[data-placement='right']::after {
|
|
98
|
+
top: 50%;
|
|
99
|
+
left: -6px;
|
|
100
|
+
transform: translateY(-50%) rotate(45deg);
|
|
101
|
+
border-right: none;
|
|
102
|
+
border-top: none;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.header {
|
|
106
|
+
font-weight: 600;
|
|
107
|
+
margin-bottom: var(--spacing-1);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.body {
|
|
111
|
+
font-size: inherit;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.footer {
|
|
115
|
+
margin-top: var(--spacing-2);
|
|
116
|
+
font-size: var(--font-size-2);
|
|
117
|
+
color: var(--color-muted);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@media (prefers-reduced-motion: reduce) {
|
|
121
|
+
.tooltip {
|
|
122
|
+
transition: none;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -1,45 +1,73 @@
|
|
|
1
|
-
.
|
|
1
|
+
.btn {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
gap: var(--spacing-2);
|
|
2
6
|
border: 1px solid var(--btn-border, rgba(30, 51, 85, 0.6));
|
|
3
7
|
cursor: pointer;
|
|
4
8
|
font-weight: 600;
|
|
9
|
+
font-family: inherit;
|
|
10
|
+
line-height: 1;
|
|
5
11
|
padding: 12px 18px;
|
|
6
12
|
border-radius: var(--radius-sm);
|
|
13
|
+
font-size: var(--font-size-3);
|
|
7
14
|
background: var(--btn-bg, rgba(15, 30, 51, 0.9));
|
|
8
15
|
color: var(--btn-color, var(--color-text));
|
|
9
16
|
box-shadow: var(--btn-shadow, none);
|
|
10
17
|
transition: transform 0.15s ease, box-shadow 0.2s ease, background 0.2s ease, border-color 0.2s ease,
|
|
11
18
|
color 0.2s ease;
|
|
19
|
+
text-decoration: none;
|
|
12
20
|
}
|
|
13
21
|
|
|
14
|
-
.
|
|
22
|
+
.btn:focus-visible {
|
|
15
23
|
outline: none;
|
|
16
24
|
box-shadow: 0 0 0 3px rgba(20, 201, 214, 0.3);
|
|
17
25
|
}
|
|
18
26
|
|
|
19
|
-
.
|
|
27
|
+
.btn:hover:not(.btn-disabled):not(:disabled) {
|
|
20
28
|
background: var(--btn-bg-hover, var(--btn-bg));
|
|
21
29
|
box-shadow: var(--btn-shadow-hover, var(--btn-shadow, none));
|
|
22
30
|
}
|
|
23
31
|
|
|
24
|
-
.
|
|
32
|
+
.btn:active:not(.btn-disabled):not(:disabled) {
|
|
25
33
|
transform: translateY(1px);
|
|
26
34
|
}
|
|
27
35
|
|
|
28
|
-
.
|
|
36
|
+
.btn:disabled,
|
|
37
|
+
.btn.btn-disabled {
|
|
29
38
|
opacity: 0.6;
|
|
30
39
|
cursor: not-allowed;
|
|
40
|
+
pointer-events: none;
|
|
31
41
|
}
|
|
32
42
|
|
|
33
|
-
.solid {
|
|
43
|
+
.btn-solid {
|
|
34
44
|
transform: translateY(0);
|
|
35
45
|
}
|
|
36
46
|
|
|
37
|
-
.solid:hover:not(:disabled) {
|
|
47
|
+
.btn-solid:hover:not(.btn-disabled):not(:disabled) {
|
|
38
48
|
transform: translateY(-1px);
|
|
39
49
|
}
|
|
40
50
|
|
|
41
|
-
.
|
|
42
|
-
|
|
51
|
+
.btn-sm {
|
|
52
|
+
padding: 8px 14px;
|
|
53
|
+
font-size: var(--font-size-2);
|
|
54
|
+
border-radius: var(--radius-xs);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.btn-md {
|
|
58
|
+
padding: 12px 18px;
|
|
59
|
+
font-size: var(--font-size-3);
|
|
60
|
+
border-radius: var(--radius-sm);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.btn-lg {
|
|
64
|
+
padding: 14px 22px;
|
|
65
|
+
font-size: var(--font-size-4);
|
|
66
|
+
border-radius: var(--radius-md);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.btn-outline,
|
|
70
|
+
.btn-ghost {
|
|
43
71
|
background: transparent;
|
|
44
72
|
color: var(--btn-accent, var(--color-teal));
|
|
45
73
|
border-color: var(--btn-accent, var(--color-teal));
|
|
@@ -48,16 +76,16 @@
|
|
|
48
76
|
--btn-shadow-hover: none;
|
|
49
77
|
}
|
|
50
78
|
|
|
51
|
-
.ghost {
|
|
79
|
+
.btn-ghost {
|
|
52
80
|
border-color: transparent;
|
|
53
81
|
}
|
|
54
82
|
|
|
55
|
-
.outline:hover:not(:disabled),
|
|
56
|
-
.ghost:hover:not(:disabled) {
|
|
83
|
+
.btn-outline:hover:not(.btn-disabled):not(:disabled),
|
|
84
|
+
.btn-ghost:hover:not(.btn-disabled):not(:disabled) {
|
|
57
85
|
background: var(--btn-accent-soft, rgba(20, 201, 214, 0.12));
|
|
58
86
|
}
|
|
59
87
|
|
|
60
|
-
.
|
|
88
|
+
.btn-default {
|
|
61
89
|
--btn-accent: var(--btn-default-accent, rgba(158, 178, 204, 0.9));
|
|
62
90
|
--btn-accent-soft: var(--btn-default-soft, rgba(30, 51, 85, 0.35));
|
|
63
91
|
--btn-bg: linear-gradient(135deg, var(--btn-default-start, #2a3750), var(--btn-default-end, #1b263c));
|
|
@@ -68,7 +96,7 @@
|
|
|
68
96
|
--btn-shadow-hover: 0 14px 30px rgba(10, 20, 35, 0.28);
|
|
69
97
|
}
|
|
70
98
|
|
|
71
|
-
.
|
|
99
|
+
.btn-primary {
|
|
72
100
|
--btn-accent: var(--btn-primary-accent, rgba(20, 201, 214, 0.9));
|
|
73
101
|
--btn-accent-soft: var(--btn-primary-soft, rgba(20, 201, 214, 0.18));
|
|
74
102
|
--btn-bg: linear-gradient(135deg, var(--btn-primary-start, #14c9d6), var(--btn-primary-end, #1e63e9));
|
|
@@ -79,7 +107,7 @@
|
|
|
79
107
|
--btn-shadow-hover: 0 16px 36px rgba(20, 201, 214, 0.4);
|
|
80
108
|
}
|
|
81
109
|
|
|
82
|
-
.
|
|
110
|
+
.btn-info {
|
|
83
111
|
--btn-accent: var(--btn-info-accent, rgba(30, 99, 233, 0.9));
|
|
84
112
|
--btn-accent-soft: var(--btn-info-soft, rgba(30, 99, 233, 0.18));
|
|
85
113
|
--btn-bg: linear-gradient(135deg, var(--btn-info-start, #4f7bff), var(--btn-info-end, #2e5be6));
|
|
@@ -90,7 +118,7 @@
|
|
|
90
118
|
--btn-shadow-hover: 0 16px 36px rgba(30, 99, 233, 0.4);
|
|
91
119
|
}
|
|
92
120
|
|
|
93
|
-
.
|
|
121
|
+
.btn-success {
|
|
94
122
|
--btn-accent: var(--btn-success-accent, rgba(79, 230, 163, 0.9));
|
|
95
123
|
--btn-accent-soft: var(--btn-success-soft, rgba(79, 230, 163, 0.16));
|
|
96
124
|
--btn-bg: linear-gradient(135deg, var(--btn-success-start, #35d092), var(--btn-success-end, #1faf75));
|
|
@@ -101,7 +129,7 @@
|
|
|
101
129
|
--btn-shadow-hover: 0 16px 36px rgba(79, 230, 163, 0.36);
|
|
102
130
|
}
|
|
103
131
|
|
|
104
|
-
.
|
|
132
|
+
.btn-warning {
|
|
105
133
|
--btn-accent: var(--btn-warning-accent, rgba(246, 200, 106, 0.95));
|
|
106
134
|
--btn-accent-soft: var(--btn-warning-soft, rgba(246, 200, 106, 0.2));
|
|
107
135
|
--btn-bg: linear-gradient(135deg, var(--btn-warning-start, #ffd166), var(--btn-warning-end, #f4a62a));
|
|
@@ -112,7 +140,7 @@
|
|
|
112
140
|
--btn-shadow-hover: 0 16px 36px rgba(246, 200, 106, 0.36);
|
|
113
141
|
}
|
|
114
142
|
|
|
115
|
-
.
|
|
143
|
+
.btn-danger {
|
|
116
144
|
--btn-accent: var(--btn-danger-accent, rgba(255, 107, 107, 0.95));
|
|
117
145
|
--btn-accent-soft: var(--btn-danger-soft, rgba(255, 107, 107, 0.2));
|
|
118
146
|
--btn-bg: linear-gradient(135deg, var(--btn-danger-start, #ff8f8f), var(--btn-danger-end, #ff5b5b));
|
|
@@ -124,7 +152,7 @@
|
|
|
124
152
|
}
|
|
125
153
|
|
|
126
154
|
@media (prefers-reduced-motion: reduce) {
|
|
127
|
-
.
|
|
155
|
+
.btn {
|
|
128
156
|
transition: none;
|
|
129
157
|
}
|
|
130
158
|
}
|
|
@@ -135,6 +135,12 @@
|
|
|
135
135
|
--spacing-8: 40px;
|
|
136
136
|
--spacing-9: 48px;
|
|
137
137
|
--spacing-10: 64px;
|
|
138
|
+
|
|
139
|
+
--ui-control-height: 48px;
|
|
140
|
+
--ui-control-padding-x: 16px;
|
|
141
|
+
--ui-control-padding-y: 12px;
|
|
142
|
+
--ui-control-font-size: var(--font-size-3);
|
|
143
|
+
--ui-control-line-height: 1.2;
|
|
138
144
|
}
|
|
139
145
|
|
|
140
146
|
:root[data-theme="light"] {
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { default as Input } from './components/Input/Input';
|
|
|
7
7
|
export { default as Textarea } from './components/Input/Textarea/Textarea';
|
|
8
8
|
export { default as Radio } from './components/Input/Radio/Radio';
|
|
9
9
|
export { default as Switch } from './components/Input/Switch/Switch';
|
|
10
|
+
export { default as Checkbox } from './components/Input/Checkbox/Checkbox';
|
|
10
11
|
export { default as Select } from './components/Input/Select/Select';
|
|
11
12
|
export { default as Alert } from './components/Alert/Alert';
|
|
12
13
|
export { default as Notifier } from './components/Notifier/Notifier';
|
|
@@ -23,6 +24,11 @@ export { default as Tabs } from './components/Tabs/Tabs';
|
|
|
23
24
|
export { default as Progress } from './components/Progress/Progress';
|
|
24
25
|
export { default as Breadcrumbs } from './components/Breadcrumbs/Breadcrumbs';
|
|
25
26
|
export { default as Image } from './components/Image/Image';
|
|
27
|
+
export { default as FileUploader } from './components/FileUploader/FileUploader';
|
|
28
|
+
export { default as Tooltip } from './components/Tooltip/Tooltip';
|
|
29
|
+
export { default as Table } from './components/Table/Table';
|
|
30
|
+
export type { TableBulkAction, TableBulkActions, TableColumn, TableRenderBulkAction, TableSelection, TableSortDirection, TableSortOptions, TableSortState, } from './components/Table/Table';
|
|
31
|
+
export type { TooltipPlacement, TooltipVariant } from './components/Tooltip/Tooltip';
|
|
26
32
|
export { default as Text } from './components/Typography/Text';
|
|
27
33
|
export { default as Heading } from './components/Typography/Heading';
|
|
28
34
|
export { default as useMediaQuery } from './hooks/useMediaQuery';
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export { default as Input } from './components/Input/Input';
|
|
|
7
7
|
export { default as Textarea } from './components/Input/Textarea/Textarea';
|
|
8
8
|
export { default as Radio } from './components/Input/Radio/Radio';
|
|
9
9
|
export { default as Switch } from './components/Input/Switch/Switch';
|
|
10
|
+
export { default as Checkbox } from './components/Input/Checkbox/Checkbox';
|
|
10
11
|
export { default as Select } from './components/Input/Select/Select';
|
|
11
12
|
export { default as Alert } from './components/Alert/Alert';
|
|
12
13
|
export { default as Notifier } from './components/Notifier/Notifier';
|
|
@@ -23,6 +24,9 @@ export { default as Tabs } from './components/Tabs/Tabs';
|
|
|
23
24
|
export { default as Progress } from './components/Progress/Progress';
|
|
24
25
|
export { default as Breadcrumbs } from './components/Breadcrumbs/Breadcrumbs';
|
|
25
26
|
export { default as Image } from './components/Image/Image';
|
|
27
|
+
export { default as FileUploader } from './components/FileUploader/FileUploader';
|
|
28
|
+
export { default as Tooltip } from './components/Tooltip/Tooltip';
|
|
29
|
+
export { default as Table } from './components/Table/Table';
|
|
26
30
|
export { default as Text } from './components/Typography/Text';
|
|
27
31
|
export { default as Heading } from './components/Typography/Heading';
|
|
28
32
|
export { default as useMediaQuery } from './hooks/useMediaQuery';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAY5D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC"}
|
package/docs/README.md
CHANGED
|
@@ -28,7 +28,9 @@ import { Button, Card, Menu } from '@phpsoftbox/react-softbox';
|
|
|
28
28
|
|
|
29
29
|
- `layout.md` — Grid, Flex, утилиты
|
|
30
30
|
- `navigation.md` — Menu, Dropdown, CollapseButton
|
|
31
|
-
- `forms.md` — Input (Field/Select/FloatLabel), Switch, Radio
|
|
31
|
+
- `forms.md` — Input (Field/Select/FloatLabel), Switch, Radio, Checkbox, FileUploader
|
|
32
|
+
- `table.md` — Table, сортировка, футер
|
|
33
|
+
- `tooltip.md` — Tooltip и варианты
|
|
32
34
|
- `overlays.md` — Modal, Drawer
|
|
33
35
|
- `feedback.md` — Badge, Alert, Notifier
|
|
34
36
|
- `card.md` — Card и его секции
|
package/docs/forms.md
CHANGED
|
@@ -20,6 +20,24 @@
|
|
|
20
20
|
</Input>
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
### Ошибка через Tooltip
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
<Input>
|
|
27
|
+
<Input.Label>Почта</Input.Label>
|
|
28
|
+
<Input.Control>
|
|
29
|
+
<Input.Field hasError placeholder="name@example.com" />
|
|
30
|
+
<Input.ErrorTooltip content="Некорректный email" />
|
|
31
|
+
</Input.Control>
|
|
32
|
+
</Input>
|
|
33
|
+
|
|
34
|
+
<Input>
|
|
35
|
+
<Input.Label>Телефон</Input.Label>
|
|
36
|
+
<Input.Field hasError placeholder="+7 (___) ___-__-__" />
|
|
37
|
+
<Input.ErrorTooltip target="input" content="Введите номер" placement="right" />
|
|
38
|
+
</Input>
|
|
39
|
+
```
|
|
40
|
+
|
|
23
41
|
## Textarea
|
|
24
42
|
|
|
25
43
|
```tsx
|
|
@@ -41,6 +59,13 @@
|
|
|
41
59
|
<Input.Radio name="mode" label="Резервный" />
|
|
42
60
|
```
|
|
43
61
|
|
|
62
|
+
## Checkbox
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
<Input.Checkbox label="Согласен с условиями" />
|
|
66
|
+
<Input.Checkbox label="Премиум" description="Расширенные права" />
|
|
67
|
+
```
|
|
68
|
+
|
|
44
69
|
## Switch
|
|
45
70
|
|
|
46
71
|
```tsx
|
|
@@ -90,6 +115,21 @@ const options = [
|
|
|
90
115
|
</Input>
|
|
91
116
|
```
|
|
92
117
|
|
|
118
|
+
### Пустое значение и сброс
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
<Input>
|
|
122
|
+
<Input.Label>Статус</Input.Label>
|
|
123
|
+
<Input.Select
|
|
124
|
+
options={options}
|
|
125
|
+
allowEmptyValue
|
|
126
|
+
emptyOptionLabel="Не выбрано"
|
|
127
|
+
searchable
|
|
128
|
+
clearable
|
|
129
|
+
/>
|
|
130
|
+
</Input>
|
|
131
|
+
```
|
|
132
|
+
|
|
93
133
|
### Загрузка через axios
|
|
94
134
|
|
|
95
135
|
```tsx
|
|
@@ -173,3 +213,23 @@ const options = [
|
|
|
173
213
|
</Input.Group>
|
|
174
214
|
</Input>
|
|
175
215
|
```
|
|
216
|
+
|
|
217
|
+
## FileUploader
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
<FileUploader
|
|
221
|
+
allowedTypes={['.jpg', '.png', '.pdf']}
|
|
222
|
+
maxFileSizeKb={2048}
|
|
223
|
+
multiple
|
|
224
|
+
showPreview
|
|
225
|
+
onChange={(files) => console.log(files)}
|
|
226
|
+
onUpload={(files) => api.upload(files)}
|
|
227
|
+
/>;
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Параметры:
|
|
231
|
+
- `allowedTypes` — допустимые типы (расширения `.png` или MIME `image/*`)
|
|
232
|
+
- `maxFileSizeKb` — ограничение размера
|
|
233
|
+
- `multiple` — разрешить множественный выбор
|
|
234
|
+
- `showPreview` — превью для изображений
|
|
235
|
+
- `onUpload` — колбэк загрузки (опционально)
|
package/docs/layout.md
CHANGED
|
@@ -52,3 +52,19 @@
|
|
|
52
52
|
- `p-`, `px-`, `py-`, `pt-`, `pr-`, `pb-`, `pl-`
|
|
53
53
|
- `m-`, `mx-`, `my-`, `mt-`, `mr-`, `mb-`, `ml-`
|
|
54
54
|
- `gap-`
|
|
55
|
+
|
|
56
|
+
## Классы кнопок
|
|
57
|
+
|
|
58
|
+
Глобальные классы для кнопок, которые можно применять к `a`/`button`.
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
<a className="btn btn-primary btn-solid" href="/create">Создать</a>
|
|
62
|
+
<a className="btn btn-info btn-outline" href="/details">Подробнее</a>
|
|
63
|
+
<button className="btn btn-danger btn-ghost">Удалить</button>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Доступны:
|
|
67
|
+
- базовый класс: `btn`
|
|
68
|
+
- варианты: `btn-default`, `btn-primary`, `btn-info`, `btn-success`, `btn-warning`, `btn-danger`
|
|
69
|
+
- внешность: `btn-solid`, `btn-outline`, `btn-ghost`
|
|
70
|
+
- размеры: `btn-sm`, `btn-md`, `btn-lg`
|
package/docs/overlays.md
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
## Modal
|
|
4
4
|
|
|
5
5
|
```tsx
|
|
6
|
-
<Modal open={open} title="Заголовок" onClose={() => setOpen(false)}>
|
|
6
|
+
<Modal open={open} title="Заголовок" lockScroll onClose={() => setOpen(false)}>
|
|
7
7
|
Контент модалки
|
|
8
8
|
</Modal>
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
Поддерживает `footer` для
|
|
11
|
+
Поддерживает `footer` для действий и `lockScroll` для блокировки скролла страницы (по умолчанию `true`).
|
|
12
12
|
|
|
13
13
|
## Drawer
|
|
14
14
|
|
package/docs/table.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Table
|
|
2
|
+
|
|
3
|
+
`Table` — табличный компонент с декларативными колонками, сортировкой и футером.
|
|
4
|
+
|
|
5
|
+
## Базовый пример
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
const columns = [
|
|
9
|
+
{ id: 'name', header: 'Название', accessor: 'name' },
|
|
10
|
+
{ id: 'status', header: 'Статус', accessor: 'status' },
|
|
11
|
+
{ id: 'amount', header: 'Сумма', accessor: (row) => `${row.amount} ₽`, align: 'right' },
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
<Table columns={columns} data={rows} />;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Колонки из бэкенда
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
const backendColumns = [
|
|
21
|
+
{ id: 'client', title: 'Клиент', field: 'client', sortable: true },
|
|
22
|
+
{ id: 'project', title: 'Проект', field: 'project' },
|
|
23
|
+
{ id: 'amount', title: 'Сумма', field: 'amount', sortable: true, align: 'right' },
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
<Table columns={backendColumns} data={rows} />;
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`header`, `label`, `title`, `field` используются по цепочке как заголовок. `accessor` может быть ключом или функцией.
|
|
30
|
+
|
|
31
|
+
## Сортировка с обновлением query‑параметров
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
const [sort, setSort] = useState({ key: 'amount', direction: 'asc' });
|
|
35
|
+
|
|
36
|
+
<Table
|
|
37
|
+
columns={[
|
|
38
|
+
{ id: 'client', header: 'Клиент', accessor: 'client', sortable: true },
|
|
39
|
+
{ id: 'amount', header: 'Сумма', accessor: 'amount', sortable: true, align: 'right' },
|
|
40
|
+
]}
|
|
41
|
+
data={rows}
|
|
42
|
+
sort={{
|
|
43
|
+
key: sort.key,
|
|
44
|
+
direction: sort.direction,
|
|
45
|
+
param: 'sort',
|
|
46
|
+
orderParam: 'order',
|
|
47
|
+
onChange: (next, url) => {
|
|
48
|
+
setSort(next);
|
|
49
|
+
window.history.replaceState(null, '', url);
|
|
50
|
+
},
|
|
51
|
+
}}
|
|
52
|
+
/>;
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Футер
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
const columns = [
|
|
59
|
+
{ id: 'name', header: 'Товар', accessor: 'name', footer: 'Итого' },
|
|
60
|
+
{
|
|
61
|
+
id: 'amount',
|
|
62
|
+
header: 'Сумма',
|
|
63
|
+
accessor: 'amount',
|
|
64
|
+
align: 'right',
|
|
65
|
+
footer: (rows) => rows.reduce((sum, row) => sum + row.amount, 0),
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
<Table columns={columns} data={rows} showFooter />;
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Футер только в нужных колонках
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
const columns = [
|
|
76
|
+
{ id: 'a', header: 'A', accessor: 'a' },
|
|
77
|
+
{ id: 'b', header: 'B', accessor: 'b' },
|
|
78
|
+
{ id: 'c', header: 'C', accessor: 'c' },
|
|
79
|
+
{ id: 'd', header: 'D', accessor: 'd', footer: 'Итого' },
|
|
80
|
+
{ id: 'e', header: 'E', accessor: 'e', footer: (rows) => rows.reduce((sum, row) => sum + row.e, 0) },
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
<Table columns={columns} data={rows} showFooter />;
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Выбор строк + renderBulkAction
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
const [selected, setSelected] = useState<React.Key[]>([]);
|
|
90
|
+
|
|
91
|
+
<Table
|
|
92
|
+
columns={columns}
|
|
93
|
+
data={rows}
|
|
94
|
+
selection={{
|
|
95
|
+
selectedIds: selected,
|
|
96
|
+
onToggle: (id) => setSelected((prev) => prev.includes(id) ? prev.filter((key) => key !== id) : [...prev, id]),
|
|
97
|
+
onToggleAll: (ids) => setSelected((prev) => ids.length > 0 && ids.every((id) => prev.includes(id)) ? [] : ids),
|
|
98
|
+
}}
|
|
99
|
+
renderBulkAction={(ids) => (
|
|
100
|
+
<div>
|
|
101
|
+
Выбрано: {ids.length}
|
|
102
|
+
</div>
|
|
103
|
+
)}
|
|
104
|
+
/>;
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Полезные поля колонки
|
|
108
|
+
|
|
109
|
+
- `field` / `accessor` / `cell` — источник данных
|
|
110
|
+
- `sortable`, `sortKey` — сортировка для колонки
|
|
111
|
+
- `footer` — значение в футере (node или функция)
|
|
112
|
+
- `hideOn` — скрыть колонку на `sm`/`md`/`lg`
|
|
113
|
+
- `width` / `minWidth` — размеры колонки
|
|
114
|
+
- `align` — `left` | `center` | `right`
|
package/docs/tooltip.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Tooltip
|
|
2
|
+
|
|
3
|
+
`Tooltip` — всплывающая подсказка для элементов интерфейса.
|
|
4
|
+
|
|
5
|
+
## Базовый пример
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
<Tooltip content="Подсказка">
|
|
9
|
+
<Button>Наведи</Button>
|
|
10
|
+
</Tooltip>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Направление
|
|
14
|
+
|
|
15
|
+
`placement`: `auto` | `top` | `bottom` | `left` | `right`.
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
<Tooltip content="Справа" placement="right">
|
|
19
|
+
<span>Help</span>
|
|
20
|
+
</Tooltip>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Интерактивный контент
|
|
24
|
+
|
|
25
|
+
Если нужно, чтобы подсказка не исчезала при наведении мышью на сам tooltip (например, есть ссылки), включите `interactive`.
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
<Tooltip
|
|
29
|
+
interactive
|
|
30
|
+
content={
|
|
31
|
+
<>
|
|
32
|
+
<Tooltip.Header>Подробности</Tooltip.Header>
|
|
33
|
+
<Tooltip.Body>
|
|
34
|
+
Перейдите в <a href="/docs">документацию</a>.
|
|
35
|
+
</Tooltip.Body>
|
|
36
|
+
<Tooltip.Footer>Последнее обновление: сегодня</Tooltip.Footer>
|
|
37
|
+
</>
|
|
38
|
+
}
|
|
39
|
+
>
|
|
40
|
+
<Button>Подробнее</Button>
|
|
41
|
+
</Tooltip>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Варианты
|
|
45
|
+
|
|
46
|
+
`variant`: `default` | `info` | `success` | `warning` | `danger`.
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<Tooltip content="Важно" variant="warning">
|
|
50
|
+
<span>!</span>
|
|
51
|
+
</Tooltip>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Header / Body / Footer
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
<Tooltip
|
|
58
|
+
content={
|
|
59
|
+
<>
|
|
60
|
+
<Tooltip.Header>Заголовок</Tooltip.Header>
|
|
61
|
+
<Tooltip.Body>Подробности и описание.</Tooltip.Body>
|
|
62
|
+
<Tooltip.Footer>Доп. инфо</Tooltip.Footer>
|
|
63
|
+
</>
|
|
64
|
+
}
|
|
65
|
+
>
|
|
66
|
+
<Button>Подробнее</Button>
|
|
67
|
+
</Tooltip>
|
|
68
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phpsoftbox/react-softbox",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -42,6 +42,10 @@
|
|
|
42
42
|
"axios": "^1.12.2"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
+
"@testing-library/dom": "^10.4.1",
|
|
46
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
47
|
+
"@testing-library/react": "^16.3.2",
|
|
48
|
+
"@types/jest": "^30.0.0",
|
|
45
49
|
"@types/react": "^19.2.0",
|
|
46
50
|
"@types/react-dom": "^19.2.0",
|
|
47
51
|
"typescript": "^5.9.3"
|