@kosmeo-ui/react 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/buttons/button/index.d.ts +2 -0
- package/dist/components/buttons/button/index.d.ts.map +1 -1
- package/dist/components/buttons/button/index.js +2 -2
- package/dist/components/buttons/button/index.js.map +1 -1
- package/dist/components/buttons/button/styles.css +6 -4
- package/dist/components/buttons/rowActions/styles.css +7 -0
- package/dist/components/data-display/addressBlock/styles.css +2 -4
- package/dist/components/data-display/dataTable/styles.css +15 -0
- package/dist/components/data-display/infiniteScroll/filters/searchFilter.d.ts.map +1 -1
- package/dist/components/data-display/infiniteScroll/filters/searchFilter.js +4 -35
- package/dist/components/data-display/infiniteScroll/filters/searchFilter.js.map +1 -1
- package/dist/components/data-display/infiniteScroll/filters/styles.css +4 -0
- package/dist/components/data-display/infiniteScroll/header/deleteButton.d.ts.map +1 -1
- package/dist/components/data-display/infiniteScroll/header/deleteButton.js +1 -1
- package/dist/components/data-display/infiniteScroll/header/deleteButton.js.map +1 -1
- package/dist/components/data-display/infiniteScroll/header/index.d.ts.map +1 -1
- package/dist/components/data-display/infiniteScroll/header/index.js +1 -1
- package/dist/components/data-display/infiniteScroll/header/index.js.map +1 -1
- package/dist/components/data-display/infiniteScroll/table/index.d.ts.map +1 -1
- package/dist/components/data-display/infiniteScroll/table/index.js +2 -2
- package/dist/components/data-display/infiniteScroll/table/index.js.map +1 -1
- package/dist/components/data-display/infiniteScroll/tags/index.d.ts.map +1 -1
- package/dist/components/data-display/infiniteScroll/tags/index.js +1 -6
- package/dist/components/data-display/infiniteScroll/tags/index.js.map +1 -1
- package/dist/components/data-display/infiniteScroll/tags/listFilterTag.d.ts.map +1 -1
- package/dist/components/data-display/infiniteScroll/tags/listFilterTag.js +3 -3
- package/dist/components/data-display/infiniteScroll/tags/listFilterTag.js.map +1 -1
- package/dist/components/data-display/infiniteScroll/tags/rangeFilterTag.d.ts.map +1 -1
- package/dist/components/data-display/infiniteScroll/tags/rangeFilterTag.js +3 -13
- package/dist/components/data-display/infiniteScroll/tags/rangeFilterTag.js.map +1 -1
- package/dist/components/data-display/infiniteScroll/tags/selectFilterTag.d.ts.map +1 -1
- package/dist/components/data-display/infiniteScroll/tags/selectFilterTag.js +3 -5
- package/dist/components/data-display/infiniteScroll/tags/selectFilterTag.js.map +1 -1
- package/dist/components/data-display/infiniteScroll/tags/styles.css +1 -29
- package/dist/components/data-display/recoveryCodeGrid/styles.css +1 -2
- package/dist/components/data-display/statCard/styles.css +1 -1
- package/dist/components/data-display/table/styles.css +12 -1
- package/dist/components/data-display/tagCard/index.d.ts.map +1 -1
- package/dist/components/data-display/tagCard/index.js +1 -1
- package/dist/components/data-display/tagCard/index.js.map +1 -1
- package/dist/components/feedback/badge/styles.css +8 -6
- package/dist/components/feedback/emptyState/styles.css +2 -4
- package/dist/components/feedback/progressBar/index.d.ts.map +1 -1
- package/dist/components/feedback/progressBar/index.js +7 -2
- package/dist/components/feedback/progressBar/index.js.map +1 -1
- package/dist/components/feedback/progressBar/styles.css +15 -6
- package/dist/components/feedback/spinner/styles.css +0 -13
- package/dist/components/forms/fieldShell/styles.css +1 -1
- package/dist/components/forms/formActions/styles.css +1 -1
- package/dist/components/forms/infoRow/styles.css +1 -2
- package/dist/components/forms/requiredAsterisk/styles.css +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/inputs/checkbox/index.d.ts +6 -1
- package/dist/components/inputs/checkbox/index.d.ts.map +1 -1
- package/dist/components/inputs/checkbox/index.js +9 -2
- package/dist/components/inputs/checkbox/index.js.map +1 -1
- package/dist/components/inputs/checkbox/styles.css +8 -0
- package/dist/components/inputs/colorPicker/styles.css +1 -1
- package/dist/components/inputs/dateInput/index.d.ts +3 -3
- package/dist/components/inputs/dateInput/index.d.ts.map +1 -1
- package/dist/components/inputs/dateInput/index.js +13 -3
- package/dist/components/inputs/dateInput/index.js.map +1 -1
- package/dist/components/inputs/dropdown/index.d.ts +2 -0
- package/dist/components/inputs/dropdown/index.d.ts.map +1 -1
- package/dist/components/inputs/dropdown/index.js +1 -1
- package/dist/components/inputs/dropdown/index.js.map +1 -1
- package/dist/components/inputs/dropdownArrowButton/index.d.ts.map +1 -1
- package/dist/components/inputs/dropdownArrowButton/index.js +1 -1
- package/dist/components/inputs/dropdownArrowButton/index.js.map +1 -1
- package/dist/components/inputs/dropdownArrowButton/styles.css +1 -1
- package/dist/components/inputs/input/index.d.ts +5 -1
- package/dist/components/inputs/input/index.d.ts.map +1 -1
- package/dist/components/inputs/input/index.js +25 -4
- package/dist/components/inputs/input/index.js.map +1 -1
- package/dist/components/inputs/input/styles.css +46 -2
- package/dist/components/inputs/multiSelect/index.d.ts.map +1 -1
- package/dist/components/inputs/multiSelect/index.js +1 -1
- package/dist/components/inputs/multiSelect/index.js.map +1 -1
- package/dist/components/inputs/multiSelect/styles.css +1 -1
- package/dist/components/inputs/phoneInput/index.d.ts.map +1 -1
- package/dist/components/inputs/phoneInput/index.js +1 -1
- package/dist/components/inputs/phoneInput/index.js.map +1 -1
- package/dist/components/inputs/richTextEditor/index.d.ts.map +1 -1
- package/dist/components/inputs/richTextEditor/index.js +14 -3
- package/dist/components/inputs/richTextEditor/index.js.map +1 -1
- package/dist/components/layout/borderedSection/index.d.ts +3 -1
- package/dist/components/layout/borderedSection/index.d.ts.map +1 -1
- package/dist/components/layout/borderedSection/index.js +2 -2
- package/dist/components/layout/borderedSection/index.js.map +1 -1
- package/dist/components/layout/card/styles.css +22 -0
- package/dist/components/layout/sectionHeader/styles.css +1 -2
- package/dist/components/navigation/pagination/index.d.ts +23 -0
- package/dist/components/navigation/pagination/index.d.ts.map +1 -0
- package/dist/components/navigation/pagination/index.js +29 -0
- package/dist/components/navigation/pagination/index.js.map +1 -0
- package/dist/components/navigation/pagination/styles.css +113 -0
- package/dist/components/navigation/pagination/utils.d.ts +9 -0
- package/dist/components/navigation/pagination/utils.d.ts.map +1 -0
- package/dist/components/navigation/pagination/utils.js +25 -0
- package/dist/components/navigation/pagination/utils.js.map +1 -0
- package/dist/components/navigation/sidebar/styles.css +9 -1
- package/dist/components/navigation/tabButton/styles.css +6 -6
- package/dist/components/navigation/tabs/styles.css +2 -2
- package/dist/components/overlays/confirmationModal/index.d.ts +5 -0
- package/dist/components/overlays/confirmationModal/index.d.ts.map +1 -1
- package/dist/components/overlays/confirmationModal/index.js +23 -4
- package/dist/components/overlays/confirmationModal/index.js.map +1 -1
- package/dist/components/overlays/confirmationModal/styles.css +3 -0
- package/dist/components/overlays/modal/index.d.ts +2 -0
- package/dist/components/overlays/modal/index.d.ts.map +1 -1
- package/dist/components/overlays/modal/index.js +13 -4
- package/dist/components/overlays/modal/index.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/usePaginated.d.ts +43 -0
- package/dist/hooks/usePaginated.d.ts.map +1 -0
- package/dist/hooks/usePaginated.js +60 -0
- package/dist/hooks/usePaginated.js.map +1 -0
- package/dist/styles.css +37 -14
- package/package.json +1 -1
- package/src/components/buttons/button/index.tsx +14 -5
- package/src/components/buttons/button/styles.css +6 -4
- package/src/components/buttons/rowActions/styles.css +7 -0
- package/src/components/data-display/addressBlock/styles.css +2 -4
- package/src/components/data-display/dataTable/styles.css +15 -0
- package/src/components/data-display/infiniteScroll/filters/searchFilter.tsx +16 -65
- package/src/components/data-display/infiniteScroll/filters/styles.css +4 -0
- package/src/components/data-display/infiniteScroll/header/deleteButton.tsx +1 -0
- package/src/components/data-display/infiniteScroll/header/index.tsx +4 -0
- package/src/components/data-display/infiniteScroll/table/index.tsx +2 -0
- package/src/components/data-display/infiniteScroll/tags/index.tsx +1 -11
- package/src/components/data-display/infiniteScroll/tags/listFilterTag.tsx +12 -16
- package/src/components/data-display/infiniteScroll/tags/rangeFilterTag.tsx +4 -22
- package/src/components/data-display/infiniteScroll/tags/selectFilterTag.tsx +4 -11
- package/src/components/data-display/infiniteScroll/tags/styles.css +1 -29
- package/src/components/data-display/recoveryCodeGrid/styles.css +1 -2
- package/src/components/data-display/statCard/styles.css +1 -1
- package/src/components/data-display/table/styles.css +12 -1
- package/src/components/data-display/tagCard/index.tsx +5 -3
- package/src/components/feedback/badge/styles.css +8 -6
- package/src/components/feedback/emptyState/styles.css +2 -4
- package/src/components/feedback/progressBar/index.tsx +14 -8
- package/src/components/feedback/progressBar/styles.css +15 -6
- package/src/components/feedback/spinner/styles.css +0 -13
- package/src/components/forms/fieldShell/styles.css +1 -1
- package/src/components/forms/formActions/styles.css +1 -1
- package/src/components/forms/infoRow/styles.css +1 -2
- package/src/components/forms/requiredAsterisk/styles.css +1 -1
- package/src/components/index.ts +2 -0
- package/src/components/inputs/checkbox/index.tsx +24 -4
- package/src/components/inputs/checkbox/styles.css +8 -0
- package/src/components/inputs/colorPicker/styles.css +1 -1
- package/src/components/inputs/dateInput/index.tsx +13 -4
- package/src/components/inputs/dropdown/index.tsx +4 -0
- package/src/components/inputs/dropdownArrowButton/index.tsx +1 -0
- package/src/components/inputs/dropdownArrowButton/styles.css +1 -1
- package/src/components/inputs/input/index.tsx +47 -4
- package/src/components/inputs/input/styles.css +46 -2
- package/src/components/inputs/multiSelect/index.tsx +1 -0
- package/src/components/inputs/multiSelect/styles.css +1 -1
- package/src/components/inputs/phoneInput/index.tsx +6 -2
- package/src/components/inputs/richTextEditor/index.tsx +27 -3
- package/src/components/layout/borderedSection/index.tsx +4 -1
- package/src/components/layout/card/styles.css +22 -0
- package/src/components/layout/sectionHeader/styles.css +1 -2
- package/src/components/navigation/pagination/index.tsx +134 -0
- package/src/components/navigation/pagination/styles.css +113 -0
- package/src/components/navigation/pagination/utils.ts +32 -0
- package/src/components/navigation/sidebar/styles.css +9 -1
- package/src/components/navigation/tabButton/styles.css +6 -6
- package/src/components/navigation/tabs/styles.css +2 -2
- package/src/components/overlays/confirmationModal/index.tsx +37 -1
- package/src/components/overlays/confirmationModal/styles.css +3 -0
- package/src/components/overlays/modal/index.tsx +23 -4
- package/src/hooks/index.ts +4 -0
- package/src/hooks/usePaginated.ts +123 -0
- package/src/styles.css +37 -14
- package/dist/components/data-display/infiniteScroll/tags/searchFilterTag.d.ts +0 -10
- package/dist/components/data-display/infiniteScroll/tags/searchFilterTag.d.ts.map +0 -1
- package/dist/components/data-display/infiniteScroll/tags/searchFilterTag.js +0 -22
- package/dist/components/data-display/infiniteScroll/tags/searchFilterTag.js.map +0 -1
- package/src/components/data-display/infiniteScroll/tags/searchFilterTag.tsx +0 -41
package/dist/styles.css
CHANGED
|
@@ -81,12 +81,14 @@ h6 {
|
|
|
81
81
|
--primary-color-active: #141f6c;
|
|
82
82
|
--primary-color-background: #3d52db;
|
|
83
83
|
--primary-color-background-light: #f0f2ff;
|
|
84
|
+
/* Primary as text (links, active tabs) on page and card surfaces. */
|
|
85
|
+
--primary-color-text: #17257d;
|
|
84
86
|
|
|
85
|
-
/* Secondary Colors */
|
|
86
|
-
--secondary-color: #
|
|
87
|
-
--secondary-color-hover: #
|
|
88
|
-
--secondary-color-active: #
|
|
89
|
-
--secondary-color-background: #
|
|
87
|
+
/* Secondary Colors — dark enough for white text (4.5:1) */
|
|
88
|
+
--secondary-color: #6b6b6b;
|
|
89
|
+
--secondary-color-hover: #757575;
|
|
90
|
+
--secondary-color-active: #616161;
|
|
91
|
+
--secondary-color-background: #6b6b6b;
|
|
90
92
|
|
|
91
93
|
/* Light Colors */
|
|
92
94
|
--light-color: #fafafa;
|
|
@@ -101,18 +103,22 @@ h6 {
|
|
|
101
103
|
--warning-color-background: #ffd24d;
|
|
102
104
|
--warning-color-background-light: #fff8e1;
|
|
103
105
|
--warning-color-text: #92400e;
|
|
106
|
+
/* Text on a warning fill. */
|
|
107
|
+
--warning-color-contrast: #333;
|
|
104
108
|
|
|
105
109
|
/* Danger Colors */
|
|
106
110
|
--danger-color: #dc3545;
|
|
107
111
|
--danger-color-hover: #e23243;
|
|
108
112
|
--danger-color-active: #d92638;
|
|
109
|
-
--danger-color-background: #
|
|
113
|
+
--danger-color-background: #c42b3b;
|
|
114
|
+
/* Danger as text (field errors) on page and card surfaces. */
|
|
115
|
+
--danger-color-text: #b92535;
|
|
110
116
|
|
|
111
117
|
/* Success Colors */
|
|
112
118
|
--success-color: #198754;
|
|
113
119
|
--success-color-hover: #1c975d;
|
|
114
120
|
--success-color-active: #188150;
|
|
115
|
-
--success-color-background: #
|
|
121
|
+
--success-color-background: #157347;
|
|
116
122
|
--success-color-background-light: #e8f5e8;
|
|
117
123
|
|
|
118
124
|
/* Background Colors */
|
|
@@ -136,7 +142,7 @@ h6 {
|
|
|
136
142
|
--text-color: #333;
|
|
137
143
|
--text-color-secondary: #666;
|
|
138
144
|
--text-color-light: white;
|
|
139
|
-
--text-color-link: #
|
|
145
|
+
--text-color-link: #0062cc;
|
|
140
146
|
--text-size-sm: 0.875rem;
|
|
141
147
|
--text-size-md: 1rem;
|
|
142
148
|
--text-size-lg: 1.125rem;
|
|
@@ -161,11 +167,12 @@ h6 {
|
|
|
161
167
|
--primary-color-active: #3d4f99;
|
|
162
168
|
--primary-color-background: #4a5fb5;
|
|
163
169
|
--primary-color-background-light: #1c2240;
|
|
170
|
+
--primary-color-text: #9aabf2;
|
|
164
171
|
|
|
165
172
|
/* Secondary Colors */
|
|
166
|
-
--secondary-color: #
|
|
167
|
-
--secondary-color-hover: #
|
|
168
|
-
--secondary-color-active: #
|
|
173
|
+
--secondary-color: #646a75;
|
|
174
|
+
--secondary-color-hover: #6e7480;
|
|
175
|
+
--secondary-color-active: #5a606a;
|
|
169
176
|
--secondary-color-background: #4a4f5a;
|
|
170
177
|
|
|
171
178
|
/* Light Colors — surface-toned (used for "light" variant buttons/pills) */
|
|
@@ -181,17 +188,19 @@ h6 {
|
|
|
181
188
|
--warning-color-background: #4d3a00;
|
|
182
189
|
--warning-color-background-light: #2e2200;
|
|
183
190
|
--warning-color-text: #f5c542;
|
|
191
|
+
--warning-color-contrast: #15181f;
|
|
184
192
|
|
|
185
193
|
/* Danger Colors */
|
|
186
194
|
--danger-color: #c94250;
|
|
187
195
|
--danger-color-hover: #d35261;
|
|
188
196
|
--danger-color-active: #b53847;
|
|
189
197
|
--danger-color-background: #4a1820;
|
|
198
|
+
--danger-color-text: #ff8f9a;
|
|
190
199
|
|
|
191
200
|
/* Success Colors */
|
|
192
|
-
--success-color: #
|
|
193
|
-
--success-color-hover: #
|
|
194
|
-
--success-color-active: #
|
|
201
|
+
--success-color: #1f7a4e;
|
|
202
|
+
--success-color-hover: #238556;
|
|
203
|
+
--success-color-active: #1b6d45;
|
|
195
204
|
--success-color-background: #133e2c;
|
|
196
205
|
--success-color-background-light: #0d2419;
|
|
197
206
|
|
|
@@ -384,3 +393,17 @@ code {
|
|
|
384
393
|
.k-flex-wrap {
|
|
385
394
|
flex-wrap: wrap;
|
|
386
395
|
}
|
|
396
|
+
|
|
397
|
+
/* Visually hidden, still read by screen readers. Global so any component can
|
|
398
|
+
use it without depending on another component's stylesheet. */
|
|
399
|
+
.k-sr-only {
|
|
400
|
+
position: absolute;
|
|
401
|
+
width: 0.0625rem;
|
|
402
|
+
height: 0.0625rem;
|
|
403
|
+
padding: 0;
|
|
404
|
+
margin: -0.0625rem;
|
|
405
|
+
overflow: hidden;
|
|
406
|
+
clip: rect(0, 0, 0, 0);
|
|
407
|
+
white-space: nowrap;
|
|
408
|
+
border: 0;
|
|
409
|
+
}
|
package/package.json
CHANGED
|
@@ -33,6 +33,8 @@ export interface ButtonProps extends PropsWithSize, PropsWithVariant {
|
|
|
33
33
|
fullWidth?: boolean;
|
|
34
34
|
/** Accessible label. Required for icon-only buttons. */
|
|
35
35
|
"aria-label"?: string;
|
|
36
|
+
/** Marks a toggle button as on or off. */
|
|
37
|
+
"aria-pressed"?: boolean;
|
|
36
38
|
/** ID of element describing this button (for additional context). */
|
|
37
39
|
"aria-describedby"?: string;
|
|
38
40
|
/** ID of element labelling this button. */
|
|
@@ -61,6 +63,8 @@ const Button = (props: ButtonProps) => {
|
|
|
61
63
|
aria-label={props["aria-label"]}
|
|
62
64
|
aria-describedby={props["aria-describedby"]}
|
|
63
65
|
aria-labelledby={props["aria-labelledby"]}
|
|
66
|
+
aria-busy={isLoading || undefined}
|
|
67
|
+
aria-pressed={props["aria-pressed"]}
|
|
64
68
|
title={props.title}
|
|
65
69
|
className={`k-button k-button-${variant} k-button-${size} k-button-${align} ${
|
|
66
70
|
shadow ? "k-button-shadow" : ""
|
|
@@ -68,11 +72,16 @@ const Button = (props: ButtonProps) => {
|
|
|
68
72
|
onClick={props.onClick}
|
|
69
73
|
>
|
|
70
74
|
{isLoading ? (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
<>
|
|
76
|
+
<FontAwesomeIcon
|
|
77
|
+
icon={faCircleNotch}
|
|
78
|
+
className="k-button-spinner"
|
|
79
|
+
spin
|
|
80
|
+
aria-hidden="true"
|
|
81
|
+
/>
|
|
82
|
+
{/* Keeps the button's accessible name while the spinner shows. */}
|
|
83
|
+
<span className="k-sr-only">{props.children}</span>
|
|
84
|
+
</>
|
|
76
85
|
) : (
|
|
77
86
|
props.children
|
|
78
87
|
)}
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
|
|
152
152
|
.k-button-warning {
|
|
153
153
|
background-color: var(--warning-color);
|
|
154
|
-
color: var(--
|
|
154
|
+
color: var(--warning-color-contrast);
|
|
155
155
|
}
|
|
156
156
|
.k-button-warning:not(:disabled):hover {
|
|
157
157
|
background-color: var(--warning-color-hover);
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
|
|
166
166
|
.k-button-link {
|
|
167
167
|
background-color: transparent;
|
|
168
|
-
color: var(--primary-color);
|
|
168
|
+
color: var(--primary-color-text);
|
|
169
169
|
padding: 0;
|
|
170
170
|
border-radius: 0;
|
|
171
171
|
font-weight: 500;
|
|
@@ -174,12 +174,14 @@
|
|
|
174
174
|
box-shadow: none;
|
|
175
175
|
}
|
|
176
176
|
.k-button-link:not(:disabled):hover {
|
|
177
|
-
color: var(--primary-color-
|
|
177
|
+
color: var(--primary-color-text);
|
|
178
|
+
/* One text color keeps contrast in both themes; hover shows as a heavier underline. */
|
|
179
|
+
text-decoration-thickness: 0.125rem;
|
|
178
180
|
background-color: transparent;
|
|
179
181
|
box-shadow: none;
|
|
180
182
|
}
|
|
181
183
|
.k-button-link:active {
|
|
182
|
-
color: var(--primary-color-
|
|
184
|
+
color: var(--primary-color-text);
|
|
183
185
|
background-color: transparent;
|
|
184
186
|
box-shadow: none;
|
|
185
187
|
}
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
display: flex;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
+
/* Never squeeze an action below its natural width: in a narrow table cell a
|
|
6
|
+
shrunk icon button collapses its icon to 0px (svg max-width: 100%). The
|
|
7
|
+
column grows to fit instead. */
|
|
8
|
+
.k-row-actions > * {
|
|
9
|
+
flex-shrink: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
5
12
|
.k-row-actions-start {
|
|
6
13
|
justify-content: flex-start;
|
|
7
14
|
}
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
font-weight: 600;
|
|
11
11
|
text-transform: uppercase;
|
|
12
12
|
letter-spacing: 0.04em;
|
|
13
|
-
color: var(--text-color);
|
|
14
|
-
opacity: 0.65;
|
|
13
|
+
color: var(--text-color-secondary);
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
.k-address-block-body {
|
|
@@ -30,8 +29,7 @@
|
|
|
30
29
|
|
|
31
30
|
.k-address-block-contact {
|
|
32
31
|
font-size: 0.8125rem;
|
|
33
|
-
color: var(--text-color);
|
|
34
|
-
opacity: 0.7;
|
|
32
|
+
color: var(--text-color-secondary);
|
|
35
33
|
margin-top: 0.125rem;
|
|
36
34
|
}
|
|
37
35
|
|
|
@@ -4,6 +4,21 @@
|
|
|
4
4
|
width: 3rem;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
/* Even padding, overriding the table's wider first-column inset, so the
|
|
8
|
+
checkbox stays centered. */
|
|
9
|
+
.k-table th.k-data-table-leading,
|
|
10
|
+
.k-table td.k-data-table-leading {
|
|
11
|
+
padding-left: 0.5rem;
|
|
12
|
+
padding-right: 0.5rem;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* text-align doesn't move flex items, and Checkbox's container is a
|
|
16
|
+
full-width flex column, so center flex content on both axes too. */
|
|
17
|
+
.k-data-table-leading > * {
|
|
18
|
+
justify-content: center;
|
|
19
|
+
align-items: center;
|
|
20
|
+
}
|
|
21
|
+
|
|
7
22
|
.k-data-table-spacer {
|
|
8
23
|
padding: 0;
|
|
9
24
|
border: 0;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons";
|
|
4
|
-
import {
|
|
5
|
-
import Dropdown from "../../../inputs/dropdown/index.js";
|
|
6
|
-
import Button from "../../../buttons/button/index.js";
|
|
4
|
+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
7
5
|
import Input from "../../../inputs/input/index.js";
|
|
8
6
|
import "./styles.css";
|
|
9
7
|
import {
|
|
@@ -16,68 +14,21 @@ interface InfiniteScrollSearchFilterProps {
|
|
|
16
14
|
onFilterChange: (filter: InfiniteScrollMenuGeneratedFilter) => void;
|
|
17
15
|
}
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
if (
|
|
26
|
-
props.filter.value === prevValue ||
|
|
27
|
-
(props.filter.value === undefined && prevValue === "")
|
|
28
|
-
)
|
|
29
|
-
return;
|
|
30
|
-
setValue(props.filter.value || "");
|
|
31
|
-
setPrevValue(props.filter.value || "");
|
|
32
|
-
return;
|
|
33
|
-
}, [props.filter.value, value, prevValue]);
|
|
34
|
-
|
|
35
|
-
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
36
|
-
setValue(e.target.value);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const handleSubmit = useCallback(() => {
|
|
40
|
-
setPrevValue(value);
|
|
41
|
-
props.onFilterChange({ ...props.filter, value: value });
|
|
42
|
-
setIsOpen(false);
|
|
43
|
-
}, [value, props]);
|
|
44
|
-
|
|
45
|
-
const handleKeydown = useCallback(
|
|
46
|
-
(e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
47
|
-
if (e.key !== "Enter") return;
|
|
48
|
-
e.preventDefault();
|
|
49
|
-
handleSubmit();
|
|
50
|
-
},
|
|
51
|
-
[handleSubmit]
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
const allowSubmit = useMemo(() => {
|
|
55
|
-
return value !== prevValue;
|
|
56
|
-
}, [value, prevValue]);
|
|
57
|
-
|
|
58
|
-
return (
|
|
59
|
-
<Dropdown
|
|
60
|
-
label={props.filter.title}
|
|
61
|
-
icon={faMagnifyingGlass}
|
|
62
|
-
align="left"
|
|
17
|
+
// Typing updates the pending filter, like the other filters; Apply applies it.
|
|
18
|
+
const SearchFilter = (props: InfiniteScrollSearchFilterProps) => (
|
|
19
|
+
<div className="k-search-filter">
|
|
20
|
+
<Input
|
|
63
21
|
size="sm"
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
<Button size="sm" disabled={!allowSubmit} onClick={handleSubmit}>
|
|
76
|
-
Add Filter
|
|
77
|
-
</Button>
|
|
78
|
-
</div>
|
|
79
|
-
</Dropdown>
|
|
80
|
-
);
|
|
81
|
-
};
|
|
22
|
+
label={props.filter.title}
|
|
23
|
+
placeholder="Search…"
|
|
24
|
+
prefix={<FontAwesomeIcon icon={faMagnifyingGlass} />}
|
|
25
|
+
value={props.filter.value ?? ""}
|
|
26
|
+
onChange={(e) =>
|
|
27
|
+
props.onFilterChange({ ...props.filter, value: e.target.value })
|
|
28
|
+
}
|
|
29
|
+
onClear={() => props.onFilterChange({ ...props.filter, value: "" })}
|
|
30
|
+
/>
|
|
31
|
+
</div>
|
|
32
|
+
);
|
|
82
33
|
|
|
83
34
|
export default SearchFilter;
|
|
@@ -47,6 +47,7 @@ const Header = <TData extends object>(props: HeaderProps<TData>) => {
|
|
|
47
47
|
size="sm"
|
|
48
48
|
variant="secondary"
|
|
49
49
|
onClick={props.onRefetch}
|
|
50
|
+
aria-label="Refresh"
|
|
50
51
|
icon={faRotate}
|
|
51
52
|
/>
|
|
52
53
|
{props.onDownload && (
|
|
@@ -54,6 +55,7 @@ const Header = <TData extends object>(props: HeaderProps<TData>) => {
|
|
|
54
55
|
size="sm"
|
|
55
56
|
variant="secondary"
|
|
56
57
|
onClick={props.onDownload}
|
|
58
|
+
aria-label="Download"
|
|
57
59
|
icon={faDownload}
|
|
58
60
|
/>
|
|
59
61
|
)}
|
|
@@ -62,6 +64,7 @@ const Header = <TData extends object>(props: HeaderProps<TData>) => {
|
|
|
62
64
|
size="sm"
|
|
63
65
|
variant="success"
|
|
64
66
|
onClick={props.onAddNew}
|
|
67
|
+
aria-label="Add new"
|
|
65
68
|
icon={faPlus}
|
|
66
69
|
/>
|
|
67
70
|
)}
|
|
@@ -74,6 +77,7 @@ const Header = <TData extends object>(props: HeaderProps<TData>) => {
|
|
|
74
77
|
{props.optionsDropdown && (
|
|
75
78
|
<Dropdown
|
|
76
79
|
icon={faEllipsisVertical}
|
|
80
|
+
aria-label="More options"
|
|
77
81
|
size="sm"
|
|
78
82
|
variant="secondary"
|
|
79
83
|
align="left"
|
|
@@ -32,12 +32,14 @@ const InfiniteScrollTable = <TData extends object>(
|
|
|
32
32
|
<Checkbox
|
|
33
33
|
checked={props.allSelected}
|
|
34
34
|
onChange={props.onSelectAll}
|
|
35
|
+
aria-label="Select all rows"
|
|
35
36
|
/>
|
|
36
37
|
),
|
|
37
38
|
cell: (row) => (
|
|
38
39
|
<Checkbox
|
|
39
40
|
checked={props.selectedRows.has(row.index) || props.allSelected}
|
|
40
41
|
onChange={() => props.onRowSelect(row.index)}
|
|
42
|
+
aria-label={`Select row ${row.index + 1}`}
|
|
41
43
|
/>
|
|
42
44
|
),
|
|
43
45
|
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { InfiniteScrollMenuGeneratedFilter } from "../types.js";
|
|
4
|
-
import SearchFilterTag from "./searchFilterTag.js";
|
|
5
4
|
import SelectFilterTag from "./selectFilterTag.js";
|
|
6
5
|
import RangeFilterTag from "./rangeFilterTag.js";
|
|
7
6
|
import ListFilterTag from "./listFilterTag.js";
|
|
@@ -13,6 +12,7 @@ interface InfiniteScrollMenuTagsProps {
|
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
const Tags = (props: InfiniteScrollMenuTagsProps) => {
|
|
15
|
+
// SEARCH filters get no tag: their search box already shows the value.
|
|
16
16
|
const filterTags = props.filters.reduce((tags, f) => {
|
|
17
17
|
if (f.type === "SELECT") {
|
|
18
18
|
const selectedFilters = f.options?.filter((o) => o.selected);
|
|
@@ -51,16 +51,6 @@ const Tags = (props: InfiniteScrollMenuTagsProps) => {
|
|
|
51
51
|
/>
|
|
52
52
|
);
|
|
53
53
|
}
|
|
54
|
-
} else if (f.type === "SEARCH") {
|
|
55
|
-
if (!f.value) return tags;
|
|
56
|
-
tags.push(
|
|
57
|
-
<SearchFilterTag
|
|
58
|
-
key={f.filterId}
|
|
59
|
-
filter={f}
|
|
60
|
-
filters={props.filters}
|
|
61
|
-
handleNewFilters={props.handleNewFilters}
|
|
62
|
-
/>
|
|
63
|
-
);
|
|
64
54
|
} else if (f.type === "LIST") {
|
|
65
55
|
if (!f.list) return tags;
|
|
66
56
|
tags.push(
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
4
3
|
import IconButton from "../../../buttons/iconButton/index.js";
|
|
5
4
|
import type { TableColumn } from "../../dataTable/types.js";
|
|
6
5
|
import Table from "../../../data-display/table/index.js";
|
|
7
6
|
import { useCallback, useMemo, useState } from "react";
|
|
7
|
+
import Badge from "../../../feedback/badge/index.js";
|
|
8
8
|
import Modal from "../../../overlays/modal/index.js";
|
|
9
9
|
import Input from "../../../inputs/input/index.js";
|
|
10
10
|
import Row from "../../../layout/row/index.js";
|
|
11
11
|
import "./styles.css";
|
|
12
12
|
import {
|
|
13
|
-
faList,
|
|
14
13
|
faPenToSquare,
|
|
15
14
|
faPlus,
|
|
16
15
|
faXmark,
|
|
@@ -111,20 +110,17 @@ const ListFilterTag = (props: InfiniteScrollListFilterTagProps) => {
|
|
|
111
110
|
);
|
|
112
111
|
|
|
113
112
|
return (
|
|
114
|
-
<div className="k-
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
<IconButton icon={faXmark} onClick={handleRemove} size="sm" />
|
|
126
|
-
</div>
|
|
127
|
-
</div>
|
|
113
|
+
<div className="k-lft-buttons">
|
|
114
|
+
<Badge onRemove={handleRemove}>
|
|
115
|
+
{props.filter.title}: {tagValue}
|
|
116
|
+
</Badge>
|
|
117
|
+
<IconButton
|
|
118
|
+
icon={faPenToSquare}
|
|
119
|
+
onClick={() => setShow(!show)}
|
|
120
|
+
size="sm"
|
|
121
|
+
variant="light"
|
|
122
|
+
aria-label={`Edit ${props.filter.title}`}
|
|
123
|
+
/>
|
|
128
124
|
<Modal show={show} onClose={handleClose} title={props.filter.title}>
|
|
129
125
|
<div className="k-lft-modal-body">
|
|
130
126
|
<Input
|
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import IconButton from "../../../buttons/iconButton/index.js";
|
|
3
|
+
import Badge from "../../../feedback/badge/index.js";
|
|
5
4
|
import { useCallback, useMemo } from "react";
|
|
6
5
|
import { DateTime } from "luxon";
|
|
7
6
|
import "./styles.css";
|
|
8
|
-
import {
|
|
9
|
-
faCalendarDays,
|
|
10
|
-
faFont,
|
|
11
|
-
faHashtag,
|
|
12
|
-
faXmark,
|
|
13
|
-
} from "@fortawesome/free-solid-svg-icons";
|
|
14
7
|
import {
|
|
15
8
|
GeneratedRangeFilter,
|
|
16
9
|
InfiniteScrollMenuGeneratedFilter,
|
|
@@ -48,12 +41,6 @@ const RangeFilterTag = (props: InfiniteScrollRangeFilterTagProps) => {
|
|
|
48
41
|
else if (filter.rangeType === "STRING") return value;
|
|
49
42
|
}, [filter, filterValue, filter.rangeType]);
|
|
50
43
|
|
|
51
|
-
const iconToUse = useMemo(() => {
|
|
52
|
-
if (isDate) return faCalendarDays;
|
|
53
|
-
else if (filter.rangeType === "NUMBER") return faHashtag;
|
|
54
|
-
else if (filter.rangeType === "STRING") return faFont;
|
|
55
|
-
}, [filter.rangeType]);
|
|
56
|
-
|
|
57
44
|
const handleRemove = useCallback(() => {
|
|
58
45
|
const newFilters = props.filters.map((f) => {
|
|
59
46
|
if (f.filterId !== props.filter.filterId) return f;
|
|
@@ -63,14 +50,9 @@ const RangeFilterTag = (props: InfiniteScrollRangeFilterTagProps) => {
|
|
|
63
50
|
}, [props.filters, filterValue]);
|
|
64
51
|
|
|
65
52
|
return (
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
{iconToUse && <FontAwesomeIcon icon={iconToUse} />}
|
|
70
|
-
<p className="k-tag-value">{tagValue}</p>
|
|
71
|
-
<IconButton icon={faXmark} onClick={handleRemove} size="sm" />
|
|
72
|
-
</div>
|
|
73
|
-
</div>
|
|
53
|
+
<Badge onRemove={handleRemove}>
|
|
54
|
+
{tagTitle}: {tagValue}
|
|
55
|
+
</Badge>
|
|
74
56
|
);
|
|
75
57
|
};
|
|
76
58
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
5
|
-
import IconButton from "../../../buttons/iconButton/index.js";
|
|
3
|
+
import Badge from "../../../feedback/badge/index.js";
|
|
6
4
|
import { useCallback } from "react";
|
|
7
5
|
import "../styles.css";
|
|
8
6
|
import {
|
|
@@ -32,14 +30,9 @@ const SelectFilterTag = (props: InfiniteScrollSelectFilterTagProps) => {
|
|
|
32
30
|
}, [props]);
|
|
33
31
|
|
|
34
32
|
return (
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
<FontAwesomeIcon icon={faCheckSquare} />
|
|
39
|
-
<p className="k-tag-value">{props.filterOption.name}</p>
|
|
40
|
-
<IconButton onClick={handleRemove} size="sm" icon={faXmark} />
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
33
|
+
<Badge onRemove={handleRemove}>
|
|
34
|
+
{props.filter.title}: {props.filterOption.name}
|
|
35
|
+
</Badge>
|
|
43
36
|
);
|
|
44
37
|
};
|
|
45
38
|
|
|
@@ -2,42 +2,14 @@
|
|
|
2
2
|
display: flex;
|
|
3
3
|
gap: 0.5rem;
|
|
4
4
|
flex-wrap: wrap;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
.k-tag-container {
|
|
8
|
-
display: flex;
|
|
9
|
-
flex-direction: column;
|
|
10
|
-
justify-content: center;
|
|
11
|
-
background-color: var(--primary-color);
|
|
12
|
-
border-radius: 0.375rem;
|
|
13
|
-
color: var(--text-color-light);
|
|
14
|
-
padding-left: 0.5rem;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.k-tag-title {
|
|
18
|
-
margin: 0;
|
|
19
|
-
margin-top: 0.25rem;
|
|
20
|
-
font-size: 0.75rem;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.k-tag-actions {
|
|
24
|
-
display: flex;
|
|
25
|
-
flex-direction: row;
|
|
26
5
|
align-items: center;
|
|
27
|
-
gap: 0.5rem;
|
|
28
|
-
margin-bottom: 0.25rem;
|
|
29
|
-
margin-top: -0.25rem;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.k-tag-value {
|
|
33
|
-
margin: 0;
|
|
34
|
-
font-size: 0.875rem;
|
|
35
6
|
}
|
|
36
7
|
|
|
37
8
|
.k-lft-buttons {
|
|
38
9
|
display: flex;
|
|
39
10
|
flex-direction: row;
|
|
40
11
|
align-items: center;
|
|
12
|
+
gap: 0.25rem;
|
|
41
13
|
}
|
|
42
14
|
|
|
43
15
|
.k-lft-modal-body {
|
|
@@ -8,7 +8,18 @@
|
|
|
8
8
|
|
|
9
9
|
.k-table th,
|
|
10
10
|
.k-table td {
|
|
11
|
-
padding: 0.5rem;
|
|
11
|
+
padding: 0.5rem 0.75rem;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Keep text clear of the table's outer edges. */
|
|
15
|
+
.k-table th:first-child,
|
|
16
|
+
.k-table td:first-child {
|
|
17
|
+
padding-left: 1rem;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.k-table th:last-child,
|
|
21
|
+
.k-table td:last-child {
|
|
22
|
+
padding-right: 1rem;
|
|
12
23
|
}
|
|
13
24
|
|
|
14
25
|
.k-table th {
|
|
@@ -21,9 +21,11 @@ const TagCard = (props: TagCardProps) => {
|
|
|
21
21
|
{props.tags.length ? (
|
|
22
22
|
<ul className="k-tag-card-list">
|
|
23
23
|
{props.tags.map((t) => (
|
|
24
|
-
<
|
|
25
|
-
{
|
|
26
|
-
|
|
24
|
+
<li key={t}>
|
|
25
|
+
<Badge variant={color} size="md" pill>
|
|
26
|
+
{t}
|
|
27
|
+
</Badge>
|
|
28
|
+
</li>
|
|
27
29
|
))}
|
|
28
30
|
</ul>
|
|
29
31
|
) : (
|