no-frills-ui 0.0.14-alpha.3 → 0.0.14-alpha.5
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/index.js +1622 -539
- package/dist/index.js.map +1 -1
- package/lib-esm/components/Accordion/AccordionStep.d.ts.map +1 -1
- package/lib-esm/components/Accordion/AccordionStep.js +27 -38
- package/lib-esm/components/Accordion/AccordionStep.js.map +1 -1
- package/lib-esm/components/Badge/Badge.js +7 -7
- package/lib-esm/components/Badge/Badge.js.map +1 -1
- package/lib-esm/components/Button/ActionButton.d.ts.map +1 -1
- package/lib-esm/components/Button/ActionButton.js +12 -11
- package/lib-esm/components/Button/ActionButton.js.map +1 -1
- package/lib-esm/components/Button/Button.d.ts +2 -2
- package/lib-esm/components/Button/Button.d.ts.map +1 -1
- package/lib-esm/components/Button/Button.js +19 -14
- package/lib-esm/components/Button/Button.js.map +1 -1
- package/lib-esm/components/Button/IconButton.d.ts.map +1 -1
- package/lib-esm/components/Button/IconButton.js +15 -14
- package/lib-esm/components/Button/IconButton.js.map +1 -1
- package/lib-esm/components/Button/LinkButton.d.ts.map +1 -1
- package/lib-esm/components/Button/LinkButton.js +7 -6
- package/lib-esm/components/Button/LinkButton.js.map +1 -1
- package/lib-esm/components/Button/RaisedButton.d.ts.map +1 -1
- package/lib-esm/components/Button/RaisedButton.js +15 -14
- package/lib-esm/components/Button/RaisedButton.js.map +1 -1
- package/lib-esm/components/Card/Card.d.ts.map +1 -1
- package/lib-esm/components/Card/Card.js +4 -4
- package/lib-esm/components/Card/Card.js.map +1 -1
- package/lib-esm/components/Chip/Chip.d.ts +5 -2
- package/lib-esm/components/Chip/Chip.d.ts.map +1 -1
- package/lib-esm/components/Chip/Chip.js +20 -14
- package/lib-esm/components/Chip/Chip.js.map +1 -1
- package/lib-esm/components/ChipInput/ChipInput.d.ts +9 -0
- package/lib-esm/components/ChipInput/ChipInput.d.ts.map +1 -1
- package/lib-esm/components/ChipInput/ChipInput.js +63 -24
- package/lib-esm/components/ChipInput/ChipInput.js.map +1 -1
- package/lib-esm/components/Dialog/AlertDialog.d.ts.map +1 -1
- package/lib-esm/components/Dialog/AlertDialog.js +4 -1
- package/lib-esm/components/Dialog/AlertDialog.js.map +1 -1
- package/lib-esm/components/Dialog/Dialog.d.ts +32 -2
- package/lib-esm/components/Dialog/Dialog.d.ts.map +1 -1
- package/lib-esm/components/Dialog/Dialog.js +84 -1
- package/lib-esm/components/Dialog/Dialog.js.map +1 -1
- package/lib-esm/components/DragAndDrop/DragAndDrop.d.ts +24 -0
- package/lib-esm/components/DragAndDrop/DragAndDrop.d.ts.map +1 -1
- package/lib-esm/components/DragAndDrop/DragAndDrop.js +85 -3
- package/lib-esm/components/DragAndDrop/DragAndDrop.js.map +1 -1
- package/lib-esm/components/DragAndDrop/DragItem.d.ts +4 -0
- package/lib-esm/components/DragAndDrop/DragItem.d.ts.map +1 -1
- package/lib-esm/components/DragAndDrop/DragItem.js +92 -12
- package/lib-esm/components/DragAndDrop/DragItem.js.map +1 -1
- package/lib-esm/components/DragAndDrop/types.d.ts +19 -0
- package/lib-esm/components/DragAndDrop/types.d.ts.map +1 -1
- package/lib-esm/components/DragAndDrop/types.js.map +1 -1
- package/lib-esm/components/Drawer/Drawer.d.ts +76 -1
- package/lib-esm/components/Drawer/Drawer.d.ts.map +1 -1
- package/lib-esm/components/Drawer/Drawer.js +158 -24
- package/lib-esm/components/Drawer/Drawer.js.map +1 -1
- package/lib-esm/components/Groups/Group.d.ts.map +1 -1
- package/lib-esm/components/Groups/Group.js +10 -8
- package/lib-esm/components/Groups/Group.js.map +1 -1
- package/lib-esm/components/Groups/GroupLabel.d.ts.map +1 -1
- package/lib-esm/components/Groups/GroupLabel.js +3 -3
- package/lib-esm/components/Groups/GroupLabel.js.map +1 -1
- package/lib-esm/components/Input/Checkbox.d.ts.map +1 -1
- package/lib-esm/components/Input/Checkbox.js +63 -58
- package/lib-esm/components/Input/Checkbox.js.map +1 -1
- package/lib-esm/components/Input/Dropdown.d.ts +8 -0
- package/lib-esm/components/Input/Dropdown.d.ts.map +1 -1
- package/lib-esm/components/Input/Dropdown.js +54 -31
- package/lib-esm/components/Input/Dropdown.js.map +1 -1
- package/lib-esm/components/Input/Input.d.ts.map +1 -1
- package/lib-esm/components/Input/Input.js +27 -22
- package/lib-esm/components/Input/Input.js.map +1 -1
- package/lib-esm/components/Input/Radio.d.ts.map +1 -1
- package/lib-esm/components/Input/Radio.js +58 -42
- package/lib-esm/components/Input/Radio.js.map +1 -1
- package/lib-esm/components/Input/RadioButton.d.ts.map +1 -1
- package/lib-esm/components/Input/RadioButton.js +12 -12
- package/lib-esm/components/Input/RadioButton.js.map +1 -1
- package/lib-esm/components/Input/Select.d.ts.map +1 -1
- package/lib-esm/components/Input/Select.js +27 -22
- package/lib-esm/components/Input/Select.js.map +1 -1
- package/lib-esm/components/Input/TextArea.d.ts.map +1 -1
- package/lib-esm/components/Input/TextArea.js +27 -22
- package/lib-esm/components/Input/TextArea.js.map +1 -1
- package/lib-esm/components/Input/Toggle.d.ts.map +1 -1
- package/lib-esm/components/Input/Toggle.js +17 -14
- package/lib-esm/components/Input/Toggle.js.map +1 -1
- package/lib-esm/components/Menu/Menu.d.ts +13 -1
- package/lib-esm/components/Menu/Menu.d.ts.map +1 -1
- package/lib-esm/components/Menu/Menu.js +98 -3
- package/lib-esm/components/Menu/Menu.js.map +1 -1
- package/lib-esm/components/Menu/MenuItem.d.ts +6 -3
- package/lib-esm/components/Menu/MenuItem.d.ts.map +1 -1
- package/lib-esm/components/Menu/MenuItem.js +10 -10
- package/lib-esm/components/Menu/MenuItem.js.map +1 -1
- package/lib-esm/components/Modal/Modal.d.ts +70 -1
- package/lib-esm/components/Modal/Modal.d.ts.map +1 -1
- package/lib-esm/components/Modal/Modal.js +145 -11
- package/lib-esm/components/Modal/Modal.js.map +1 -1
- package/lib-esm/components/Notification/Notification.d.ts +11 -7
- package/lib-esm/components/Notification/Notification.d.ts.map +1 -1
- package/lib-esm/components/Notification/Notification.js +54 -25
- package/lib-esm/components/Notification/Notification.js.map +1 -1
- package/lib-esm/components/Notification/NotificationManager.d.ts +11 -1
- package/lib-esm/components/Notification/NotificationManager.d.ts.map +1 -1
- package/lib-esm/components/Notification/NotificationManager.js +43 -8
- package/lib-esm/components/Notification/NotificationManager.js.map +1 -1
- package/lib-esm/components/Notification/style.d.ts +4 -0
- package/lib-esm/components/Notification/style.d.ts.map +1 -1
- package/lib-esm/components/Notification/style.js +30 -15
- package/lib-esm/components/Notification/style.js.map +1 -1
- package/lib-esm/components/Notification/types.d.ts +2 -0
- package/lib-esm/components/Notification/types.d.ts.map +1 -1
- package/lib-esm/components/Notification/types.js.map +1 -1
- package/lib-esm/components/Popover/Popover.d.ts.map +1 -1
- package/lib-esm/components/Popover/Popover.js +17 -2
- package/lib-esm/components/Popover/Popover.js.map +1 -1
- package/lib-esm/components/Spinner/Spinner.d.ts +3 -0
- package/lib-esm/components/Spinner/Spinner.d.ts.map +1 -1
- package/lib-esm/components/Spinner/Spinner.js +19 -4
- package/lib-esm/components/Spinner/Spinner.js.map +1 -1
- package/lib-esm/components/Stepper/Stepper.d.ts.map +1 -1
- package/lib-esm/components/Stepper/Stepper.js +29 -10
- package/lib-esm/components/Stepper/Stepper.js.map +1 -1
- package/lib-esm/components/Tabs/Tabs.d.ts.map +1 -1
- package/lib-esm/components/Tabs/Tabs.js +45 -12
- package/lib-esm/components/Tabs/Tabs.js.map +1 -1
- package/lib-esm/components/Toast/Toast.d.ts +25 -4
- package/lib-esm/components/Toast/Toast.d.ts.map +1 -1
- package/lib-esm/components/Toast/Toast.js +114 -18
- package/lib-esm/components/Toast/Toast.js.map +1 -1
- package/lib-esm/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/lib-esm/components/Tooltip/Tooltip.js +16 -5
- package/lib-esm/components/Tooltip/Tooltip.js.map +1 -1
- package/lib-esm/shared/LayerManager.d.ts.map +1 -1
- package/lib-esm/shared/LayerManager.js +63 -1
- package/lib-esm/shared/LayerManager.js.map +1 -1
- package/lib-esm/shared/constants.d.ts +58 -27
- package/lib-esm/shared/constants.d.ts.map +1 -1
- package/lib-esm/shared/constants.js +88 -25
- package/lib-esm/shared/constants.js.map +1 -1
- package/lib-esm/shared/styles.d.ts +1 -1
- package/lib-esm/shared/styles.d.ts.map +1 -1
- package/lib-esm/shared/styles.js +5 -3
- package/lib-esm/shared/styles.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -74,42 +74,106 @@ function CheckCircle(props) {
|
|
|
74
74
|
return (jsxRuntime.jsxs("svg", Object.assign({ height: "24", viewBox: "0 0 24 24", width: "24", fill: "currentColor" }, props, { children: [jsxRuntime.jsx("path", { d: "M0 0h24v24H0V0z", fill: "none" }), jsxRuntime.jsx("path", { d: "M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" })] })));
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
var
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
77
|
+
var THEME_CONSTANTS;
|
|
78
|
+
(function (THEME_CONSTANTS) {
|
|
79
|
+
THEME_CONSTANTS["PRIMARY"] = "#1f7ac5";
|
|
80
|
+
THEME_CONSTANTS["PRIMARY_LIGHT"] = "#64baff";
|
|
81
|
+
THEME_CONSTANTS["PRIMARY_LIGHTER"] = "#cfe9ff";
|
|
82
|
+
THEME_CONSTANTS["BACKDROP_COLOR"] = "#2681da80";
|
|
83
|
+
THEME_CONSTANTS["INFO"] = "#1f7ac5ff";
|
|
84
|
+
THEME_CONSTANTS["INFO_LIGHT"] = "#64baffff";
|
|
85
|
+
THEME_CONSTANTS["SUCCESS"] = "#1a835f";
|
|
86
|
+
THEME_CONSTANTS["SUCCESS_LIGHT"] = "#80eac6";
|
|
87
|
+
THEME_CONSTANTS["WARNING"] = "#916b01";
|
|
88
|
+
THEME_CONSTANTS["WARNING_LIGHT"] = "#ffba00";
|
|
89
|
+
THEME_CONSTANTS["ERROR"] = "#bb2828";
|
|
90
|
+
THEME_CONSTANTS["ERROR_LIGHT"] = "#f1a5a5";
|
|
91
|
+
THEME_CONSTANTS["BORDER_COLOR"] = "#555555";
|
|
92
|
+
THEME_CONSTANTS["TOAST"] = "#5f5f5f";
|
|
93
|
+
THEME_CONSTANTS["TOOLTIP_COLOR"] = "rgba(0,0,0,0.6)";
|
|
94
|
+
THEME_CONSTANTS["BORDER_LIGHT_COLOR"] = "#eeeeee";
|
|
95
|
+
THEME_CONSTANTS["BACKGROUND"] = "#ffffff";
|
|
96
|
+
THEME_CONSTANTS["DISABLED_BACKGROUND"] = "#fafafa";
|
|
97
|
+
THEME_CONSTANTS["DISABLED_BORDER"] = "#aaa";
|
|
98
|
+
THEME_CONSTANTS["LIGHT_GREY"] = "#ccc";
|
|
99
|
+
THEME_CONSTANTS["DISABLED"] = "#737373";
|
|
100
|
+
THEME_CONSTANTS["TEXT_COLOR_LIGHT"] = "#fff";
|
|
101
|
+
THEME_CONSTANTS["TEXT_COLOR_DARK"] = "#000";
|
|
102
|
+
THEME_CONSTANTS["SHADOW"] = "0px 1px 3px 0px rgba(0,0,0,0.1), 0px 1px 2px 0px rgba(0,0,0,0.06)";
|
|
103
|
+
THEME_CONSTANTS["HOVER_SHADOW"] = "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)";
|
|
104
|
+
THEME_CONSTANTS["MODAL_SHADOW"] = "0px 8px 17px 2px rgba(0,0,0,0.14), 0px 3px 14px 2px rgba(0,0,0,0.12), 0px 5px 5px -3px rgba(0,0,0,0.2)";
|
|
105
|
+
})(THEME_CONSTANTS || (THEME_CONSTANTS = {}));
|
|
106
|
+
var THEME_NAME;
|
|
107
|
+
(function (THEME_NAME) {
|
|
108
|
+
THEME_NAME["PRIMARY"] = "--nfui-primary";
|
|
109
|
+
THEME_NAME["PRIMARY_LIGHT"] = "--nfui-primary-light";
|
|
110
|
+
THEME_NAME["PRIMARY_LIGHTER"] = "--nfui-primary-lighter";
|
|
111
|
+
THEME_NAME["INFO"] = "--nfui-info";
|
|
112
|
+
THEME_NAME["INFO_LIGHT"] = "--nfui-info-light";
|
|
113
|
+
THEME_NAME["SUCCESS"] = "--nfui-success";
|
|
114
|
+
THEME_NAME["SUCCESS_LIGHT"] = "--nfui-success-light";
|
|
115
|
+
THEME_NAME["WARNING"] = "--nfui-warning";
|
|
116
|
+
THEME_NAME["WARNING_LIGHT"] = "--nfui-warning-light";
|
|
117
|
+
THEME_NAME["ERROR"] = "--nfui-error";
|
|
118
|
+
THEME_NAME["ERROR_LIGHT"] = "--nfui-error-light";
|
|
119
|
+
THEME_NAME["BORDER_COLOR"] = "--nfui-border-color";
|
|
120
|
+
THEME_NAME["TOAST"] = "--nfui-toast";
|
|
121
|
+
THEME_NAME["TOOLTIP_COLOR"] = "--nfui-tooltip-color";
|
|
122
|
+
THEME_NAME["BORDER_LIGHT_COLOR"] = "--nfui-border-light-color";
|
|
123
|
+
THEME_NAME["BACKGROUND"] = "--nfui-background";
|
|
124
|
+
THEME_NAME["DISABLED_BACKGROUND"] = "--nfui-disabled-background";
|
|
125
|
+
THEME_NAME["DISABLED_BORDER"] = "--nfui-disabled-border";
|
|
126
|
+
THEME_NAME["LIGHT_GREY"] = "--nfui-light-grey";
|
|
127
|
+
THEME_NAME["DISABLED"] = "--nfui-disabled";
|
|
128
|
+
THEME_NAME["TEXT_COLOR_LIGHT"] = "--nfui-text-color-light";
|
|
129
|
+
THEME_NAME["TEXT_COLOR_DARK"] = "--nfui-text-color-dark";
|
|
130
|
+
THEME_NAME["SHADOW"] = "--nfui-shadow";
|
|
131
|
+
THEME_NAME["HOVER_SHADOW"] = "--nfui-hover-shadow";
|
|
132
|
+
THEME_NAME["MODAL_SHADOW"] = "--nfui-modal-shadow";
|
|
133
|
+
THEME_NAME["BACKDROP_COLOR"] = "--nfui-backdrop-color";
|
|
134
|
+
})(THEME_NAME || (THEME_NAME = {}));
|
|
135
|
+
const themeNameMap = {
|
|
136
|
+
[THEME_NAME.PRIMARY]: THEME_CONSTANTS.PRIMARY,
|
|
137
|
+
[THEME_NAME.PRIMARY_LIGHT]: THEME_CONSTANTS.PRIMARY_LIGHT,
|
|
138
|
+
[THEME_NAME.PRIMARY_LIGHTER]: THEME_CONSTANTS.PRIMARY_LIGHTER,
|
|
139
|
+
[THEME_NAME.INFO]: THEME_CONSTANTS.INFO,
|
|
140
|
+
[THEME_NAME.INFO_LIGHT]: THEME_CONSTANTS.INFO_LIGHT,
|
|
141
|
+
[THEME_NAME.SUCCESS]: THEME_CONSTANTS.SUCCESS,
|
|
142
|
+
[THEME_NAME.SUCCESS_LIGHT]: THEME_CONSTANTS.SUCCESS_LIGHT,
|
|
143
|
+
[THEME_NAME.WARNING]: THEME_CONSTANTS.WARNING,
|
|
144
|
+
[THEME_NAME.WARNING_LIGHT]: THEME_CONSTANTS.WARNING_LIGHT,
|
|
145
|
+
[THEME_NAME.ERROR]: THEME_CONSTANTS.ERROR,
|
|
146
|
+
[THEME_NAME.ERROR_LIGHT]: THEME_CONSTANTS.ERROR_LIGHT,
|
|
147
|
+
[THEME_NAME.BACKDROP_COLOR]: THEME_CONSTANTS.BACKDROP_COLOR,
|
|
148
|
+
[THEME_NAME.BORDER_COLOR]: THEME_CONSTANTS.BORDER_COLOR,
|
|
149
|
+
[THEME_NAME.TOAST]: THEME_CONSTANTS.TOAST,
|
|
150
|
+
[THEME_NAME.TOOLTIP_COLOR]: THEME_CONSTANTS.TOOLTIP_COLOR,
|
|
151
|
+
[THEME_NAME.BORDER_LIGHT_COLOR]: THEME_CONSTANTS.BORDER_LIGHT_COLOR,
|
|
152
|
+
[THEME_NAME.BACKGROUND]: THEME_CONSTANTS.BACKGROUND,
|
|
153
|
+
[THEME_NAME.DISABLED_BACKGROUND]: THEME_CONSTANTS.DISABLED_BACKGROUND,
|
|
154
|
+
[THEME_NAME.DISABLED_BORDER]: THEME_CONSTANTS.DISABLED_BORDER,
|
|
155
|
+
[THEME_NAME.LIGHT_GREY]: THEME_CONSTANTS.LIGHT_GREY,
|
|
156
|
+
[THEME_NAME.DISABLED]: THEME_CONSTANTS.DISABLED,
|
|
157
|
+
[THEME_NAME.TEXT_COLOR_LIGHT]: THEME_CONSTANTS.TEXT_COLOR_LIGHT,
|
|
158
|
+
[THEME_NAME.TEXT_COLOR_DARK]: THEME_CONSTANTS.TEXT_COLOR_DARK,
|
|
159
|
+
[THEME_NAME.SHADOW]: THEME_CONSTANTS.SHADOW,
|
|
160
|
+
[THEME_NAME.HOVER_SHADOW]: THEME_CONSTANTS.HOVER_SHADOW,
|
|
161
|
+
[THEME_NAME.MODAL_SHADOW]: THEME_CONSTANTS.MODAL_SHADOW,
|
|
162
|
+
};
|
|
163
|
+
const getThemeValue = (key) => {
|
|
164
|
+
return `var(${key}, ${themeNameMap[key]})`;
|
|
102
165
|
};
|
|
103
166
|
|
|
104
167
|
const Ellipsis = styled.span `
|
|
105
168
|
white-space: nowrap;
|
|
106
169
|
text-overflow: ellipsis;
|
|
107
170
|
overflow: hidden;
|
|
171
|
+
flex: 1;
|
|
108
172
|
`;
|
|
109
|
-
const Header$1 = styled.
|
|
173
|
+
const Header$1 = styled.h1 `
|
|
110
174
|
padding: 10px 15px;
|
|
111
175
|
line-height: 26px;
|
|
112
|
-
border-bottom: 1px solid
|
|
176
|
+
border-bottom: 1px solid ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};
|
|
113
177
|
font-size: 16px;
|
|
114
178
|
font-weight: bold;
|
|
115
179
|
`;
|
|
@@ -120,7 +184,7 @@ const Body$1 = styled.div `
|
|
|
120
184
|
`;
|
|
121
185
|
const Footer$1 = styled.div `
|
|
122
186
|
padding: 10px 15px;
|
|
123
|
-
border-top: 1px solid
|
|
187
|
+
border-top: 1px solid ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};
|
|
124
188
|
display: flex;
|
|
125
189
|
justify-content: flex-end;
|
|
126
190
|
`;
|
|
@@ -137,18 +201,18 @@ const BadgeSpan = styled.span `
|
|
|
137
201
|
background-color: ${(props) => {
|
|
138
202
|
switch (props.type) {
|
|
139
203
|
case exports.BADGE_TYPE.SUCCESS:
|
|
140
|
-
return
|
|
204
|
+
return getThemeValue(THEME_NAME.SUCCESS);
|
|
141
205
|
case exports.BADGE_TYPE.WARNING:
|
|
142
|
-
return
|
|
206
|
+
return getThemeValue(THEME_NAME.WARNING);
|
|
143
207
|
case exports.BADGE_TYPE.DANGER:
|
|
144
|
-
return
|
|
208
|
+
return getThemeValue(THEME_NAME.ERROR);
|
|
145
209
|
case exports.BADGE_TYPE.DISABLED:
|
|
146
|
-
return
|
|
210
|
+
return getThemeValue(THEME_NAME.DISABLED);
|
|
147
211
|
default:
|
|
148
|
-
return
|
|
212
|
+
return getThemeValue(THEME_NAME.PRIMARY);
|
|
149
213
|
}
|
|
150
214
|
}};
|
|
151
|
-
color:
|
|
215
|
+
color: ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};
|
|
152
216
|
border-radius: 10px;
|
|
153
217
|
padding: ${(props) => (props.children ? '3px 10px' : '4px')};
|
|
154
218
|
display: inline-block;
|
|
@@ -182,10 +246,10 @@ Badge.defaultProps = {
|
|
|
182
246
|
|
|
183
247
|
const Card = styled.div `
|
|
184
248
|
border-radius: 10px;
|
|
185
|
-
background-color:
|
|
249
|
+
background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
186
250
|
${(props) => props.elevated
|
|
187
|
-
? `box-shadow:
|
|
188
|
-
: `box-shadow:
|
|
251
|
+
? `box-shadow: ${getThemeValue(THEME_NAME.MODAL_SHADOW)};`
|
|
252
|
+
: `box-shadow: ${getThemeValue(THEME_NAME.SHADOW)};`}
|
|
189
253
|
margin: 5px;
|
|
190
254
|
overflow: auto;
|
|
191
255
|
position: relative;
|
|
@@ -193,37 +257,33 @@ const Card = styled.div `
|
|
|
193
257
|
|
|
194
258
|
const Step$1 = styled(Card) `
|
|
195
259
|
transition: all 0.6s ease;
|
|
260
|
+
overflow: visible;
|
|
196
261
|
|
|
197
|
-
${(props) => props.open &&
|
|
198
|
-
`
|
|
199
|
-
margin: 20px 5px;
|
|
200
|
-
`}
|
|
201
|
-
|
|
202
|
-
${(props) => props.focused && `box-shadow: 0 0 0 4px var(--primary-light, ${constants.PRIMARY_LIGHT});`}
|
|
262
|
+
${(props) => props.open && `margin: 20px 5px;`}
|
|
203
263
|
`;
|
|
204
|
-
const StepHeader = styled.
|
|
264
|
+
const StepHeader = styled.button `
|
|
205
265
|
padding: 20px 15px;
|
|
206
266
|
display: flex;
|
|
207
267
|
justify-content: space-between;
|
|
268
|
+
background: none;
|
|
269
|
+
border: none;
|
|
270
|
+
border-radius: 10px;
|
|
271
|
+
width: 100%;
|
|
272
|
+
font-size: inherit;
|
|
273
|
+
color: ${getThemeValue(THEME_NAME.TEXT_COLOR_DARK)};
|
|
274
|
+
|
|
275
|
+
&:focus-visible {
|
|
276
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
277
|
+
}
|
|
208
278
|
|
|
209
279
|
& input {
|
|
210
280
|
appearance: none;
|
|
211
281
|
margin: 0;
|
|
212
282
|
}
|
|
213
283
|
|
|
214
|
-
${(props) => props.open
|
|
215
|
-
? `
|
|
216
|
-
border-bottom: 1px solid var(--border-light-color, ${constants.BORDER_LIGHT_COLOR});
|
|
217
|
-
`
|
|
218
|
-
: ''}
|
|
284
|
+
${(props) => props.open && `border-bottom: 1px solid ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};`}
|
|
219
285
|
|
|
220
|
-
${(props) => props.disabled
|
|
221
|
-
? `
|
|
222
|
-
color: ${constants.LIGHT_GREY};
|
|
223
|
-
`
|
|
224
|
-
: `
|
|
225
|
-
cursor: pointer;
|
|
226
|
-
`}
|
|
286
|
+
${(props) => props.disabled && `color: ${getThemeValue(THEME_NAME.DISABLED)};`}
|
|
227
287
|
`;
|
|
228
288
|
const HeaderContainer = styled.div `
|
|
229
289
|
display: flex;
|
|
@@ -234,10 +294,10 @@ const HeaderContainer = styled.div `
|
|
|
234
294
|
vertical-align: top;
|
|
235
295
|
margin-right: 10px;
|
|
236
296
|
fill: ${(props) => props.open
|
|
237
|
-
?
|
|
297
|
+
? getThemeValue(THEME_NAME.PRIMARY)
|
|
238
298
|
: props.completed
|
|
239
|
-
?
|
|
240
|
-
:
|
|
299
|
+
? getThemeValue(THEME_NAME.SUCCESS)
|
|
300
|
+
: getThemeValue(THEME_NAME.LIGHT_GREY)};
|
|
241
301
|
transform: ${(props) => (props.open ? 'scale(0.8)' : 'scale(0.6)')};
|
|
242
302
|
transition: all 0.3s ease;
|
|
243
303
|
min-width: 24px;
|
|
@@ -254,13 +314,7 @@ const ExpandContainer = styled.div `
|
|
|
254
314
|
fill: currentColor;
|
|
255
315
|
}
|
|
256
316
|
|
|
257
|
-
${(props) => props.open
|
|
258
|
-
? `
|
|
259
|
-
& svg {
|
|
260
|
-
transform: rotate(180deg);
|
|
261
|
-
}
|
|
262
|
-
`
|
|
263
|
-
: ''}
|
|
317
|
+
${(props) => (props.open ? `& svg { transform: rotate(180deg); }` : '')}
|
|
264
318
|
`;
|
|
265
319
|
const StepBody = styled.div `
|
|
266
320
|
transition: all 0.6s ease;
|
|
@@ -274,19 +328,18 @@ const AccordionStepFooter = styled.div `
|
|
|
274
328
|
display: flex;
|
|
275
329
|
justify-content: flex-end;
|
|
276
330
|
padding: 10px 15px;
|
|
277
|
-
border-top: 1px solid
|
|
331
|
+
border-top: 1px solid ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};
|
|
278
332
|
`;
|
|
279
333
|
function AccordionStep(props) {
|
|
280
334
|
const [height, setHeight] = React.useState(0);
|
|
281
|
-
const [focused, setFocused] = React.useState(false);
|
|
282
335
|
const { open, disabled, header, errorText, completed, onStepClick } = props;
|
|
336
|
+
// Generate unique IDs for ARIA relationships
|
|
337
|
+
const headerId = React.useId();
|
|
338
|
+
const regionId = React.useId();
|
|
283
339
|
const ref = (el) => setHeight((el === null || el === void 0 ? void 0 : el.scrollHeight) || 0);
|
|
284
|
-
|
|
285
|
-
setFocused(!focused);
|
|
286
|
-
};
|
|
287
|
-
return (jsxRuntime.jsxs(Step$1, Object.assign({}, props, { focused: focused, elevated: props.open, children: [jsxRuntime.jsxs(StepHeader, { open: open, disabled: disabled, onClick: onStepClick, children: [jsxRuntime.jsxs(HeaderContainer, { open: open, completed: completed, children: [jsxRuntime.jsx("input", { type: "checkbox", checked: open, disabled: disabled, onFocus: toggleFocus, onBlur: toggleFocus }), jsxRuntime.jsx(FiberManualRecord, {}), jsxRuntime.jsx(Ellipsis, { children: header })] }), jsxRuntime.jsxs(ExpandContainer, { open: open, children: [errorText && (jsxRuntime.jsx(Badge, { css: react.css `
|
|
340
|
+
return (jsxRuntime.jsxs(Step$1, Object.assign({}, props, { elevated: props.open, children: [jsxRuntime.jsxs(StepHeader, { open: open, disabled: disabled, onClick: onStepClick, "aria-expanded": open ? 'true' : 'false', "aria-controls": regionId, id: headerId, children: [jsxRuntime.jsxs(HeaderContainer, { open: open, completed: completed, children: [jsxRuntime.jsx(FiberManualRecord, { "aria-hidden": "true" }), jsxRuntime.jsx(Ellipsis, { children: header })] }), jsxRuntime.jsxs(ExpandContainer, { open: open, children: [errorText && (jsxRuntime.jsx(Badge, { css: react.css `
|
|
288
341
|
margin-right: 15px;
|
|
289
|
-
`, inline: true, type: exports.BADGE_TYPE.DANGER, children: errorText })), jsxRuntime.jsx(ExpandMore, {})] })] }), jsxRuntime.jsx(StepBody, { ref: ref, height: open ? height : 0, children: open && props.children })] })));
|
|
342
|
+
`, inline: true, type: exports.BADGE_TYPE.DANGER, children: errorText })), jsxRuntime.jsx(ExpandMore, { "aria-hidden": "true" })] })] }), jsxRuntime.jsx(StepBody, { ref: ref, height: open ? height : 0, role: "region", id: regionId, "aria-labelledby": headerId, "aria-hidden": open ? 'false' : 'true', children: open && props.children })] })));
|
|
290
343
|
}
|
|
291
344
|
AccordionStep.propTypes = {
|
|
292
345
|
/** Header text for the step */
|
|
@@ -303,8 +356,8 @@ AccordionStep.defaultProps = {
|
|
|
303
356
|
disabled: false,
|
|
304
357
|
};
|
|
305
358
|
|
|
306
|
-
|
|
307
|
-
border: 1px solid
|
|
359
|
+
const StyledButton = styled.button `
|
|
360
|
+
border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};
|
|
308
361
|
border-radius: 5px;
|
|
309
362
|
height: 32px;
|
|
310
363
|
min-width: 100px;
|
|
@@ -312,12 +365,13 @@ var Button$2 = styled.button `
|
|
|
312
365
|
text-align: center;
|
|
313
366
|
padding: 0 12px;
|
|
314
367
|
cursor: pointer;
|
|
315
|
-
color:
|
|
316
|
-
background-color:
|
|
317
|
-
text-overflow: ellipsis;
|
|
318
|
-
white-space: nowrap;
|
|
368
|
+
color: ${getThemeValue(THEME_NAME.TEXT_COLOR_DARK)};
|
|
369
|
+
background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
319
370
|
margin: 5px;
|
|
320
371
|
position: relative;
|
|
372
|
+
display: inline-flex;
|
|
373
|
+
align-items: center;
|
|
374
|
+
justify-content: center;
|
|
321
375
|
|
|
322
376
|
& svg {
|
|
323
377
|
vertical-align: middle;
|
|
@@ -328,21 +382,24 @@ var Button$2 = styled.button `
|
|
|
328
382
|
}
|
|
329
383
|
|
|
330
384
|
&:enabled:hover {
|
|
331
|
-
border-color:
|
|
332
|
-
color:
|
|
385
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
386
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
333
387
|
}
|
|
334
388
|
|
|
335
389
|
&:focus {
|
|
336
|
-
border-color:
|
|
337
|
-
box-shadow: 0 0 0 4px
|
|
390
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
391
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
338
392
|
}
|
|
339
393
|
|
|
340
394
|
&:disabled {
|
|
341
|
-
background-color:
|
|
342
|
-
border-color:
|
|
343
|
-
color:
|
|
395
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};
|
|
396
|
+
border-color: ${getThemeValue(THEME_NAME.LIGHT_GREY)};
|
|
397
|
+
color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
344
398
|
}
|
|
345
399
|
`;
|
|
400
|
+
StyledButton.defaultProps = {
|
|
401
|
+
type: 'button',
|
|
402
|
+
};
|
|
346
403
|
|
|
347
404
|
var LinkButton = styled.button `
|
|
348
405
|
min-width: 100px;
|
|
@@ -352,12 +409,13 @@ var LinkButton = styled.button `
|
|
|
352
409
|
cursor: pointer;
|
|
353
410
|
background-color: transparent;
|
|
354
411
|
border: none;
|
|
355
|
-
color:
|
|
412
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
356
413
|
padding: 0 12px;
|
|
357
|
-
text-overflow: ellipsis;
|
|
358
|
-
white-space: nowrap;
|
|
359
414
|
margin: 5px;
|
|
360
415
|
position: relative;
|
|
416
|
+
display: inline-flex;
|
|
417
|
+
align-items: center;
|
|
418
|
+
justify-content: center;
|
|
361
419
|
|
|
362
420
|
& svg {
|
|
363
421
|
vertical-align: middle;
|
|
@@ -373,28 +431,29 @@ var LinkButton = styled.button `
|
|
|
373
431
|
}
|
|
374
432
|
|
|
375
433
|
&:disabled {
|
|
376
|
-
border-color: ${
|
|
377
|
-
color: ${
|
|
434
|
+
border-color: ${getThemeValue(THEME_NAME.BORDER_COLOR)};
|
|
435
|
+
color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
378
436
|
}
|
|
379
437
|
`;
|
|
380
438
|
|
|
381
439
|
var RaisedButton = styled.button `
|
|
382
|
-
border: 1px solid
|
|
440
|
+
border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};
|
|
383
441
|
border-radius: 5px;
|
|
384
442
|
height: 32px;
|
|
385
443
|
min-width: 100px;
|
|
386
444
|
font-size: 14px;
|
|
387
445
|
text-align: center;
|
|
388
446
|
padding: 0 12px;
|
|
389
|
-
cursor:
|
|
447
|
+
cursor: ${getThemeValue(THEME_NAME.TEXT_COLOR_DARK)};
|
|
390
448
|
color: inherit;
|
|
391
|
-
background-color:
|
|
449
|
+
background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
392
450
|
transform: translateY(-2px);
|
|
393
|
-
box-shadow:
|
|
394
|
-
text-overflow: ellipsis;
|
|
395
|
-
white-space: nowrap;
|
|
451
|
+
box-shadow: ${getThemeValue(THEME_NAME.HOVER_SHADOW)};
|
|
396
452
|
margin: 5px;
|
|
397
453
|
position: relative;
|
|
454
|
+
display: inline-flex;
|
|
455
|
+
align-items: center;
|
|
456
|
+
justify-content: center;
|
|
398
457
|
|
|
399
458
|
& svg {
|
|
400
459
|
vertical-align: middle;
|
|
@@ -405,30 +464,30 @@ var RaisedButton = styled.button `
|
|
|
405
464
|
}
|
|
406
465
|
|
|
407
466
|
&:enabled:hover {
|
|
408
|
-
border-color:
|
|
409
|
-
color:
|
|
467
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
468
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
410
469
|
}
|
|
411
470
|
|
|
412
471
|
&:focus {
|
|
413
|
-
border-color:
|
|
472
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
414
473
|
}
|
|
415
474
|
|
|
416
475
|
&:disabled {
|
|
417
|
-
background-color: ${
|
|
418
|
-
border-color: ${
|
|
419
|
-
color: ${
|
|
476
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};
|
|
477
|
+
border-color: ${getThemeValue(THEME_NAME.LIGHT_GREY)};
|
|
478
|
+
color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
420
479
|
}
|
|
421
480
|
|
|
422
481
|
&:active {
|
|
423
482
|
transform: translateY(0);
|
|
424
|
-
box-shadow:
|
|
483
|
+
box-shadow: ${getThemeValue(THEME_NAME.SHADOW)};
|
|
425
484
|
}
|
|
426
485
|
`;
|
|
427
486
|
|
|
428
487
|
var ActionButton = styled.button `
|
|
429
|
-
border: 1px solid
|
|
430
|
-
background-color:
|
|
431
|
-
color:
|
|
488
|
+
border: 1px solid ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
489
|
+
background-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
490
|
+
color: ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};
|
|
432
491
|
border-radius: 5px;
|
|
433
492
|
height: 32px;
|
|
434
493
|
min-width: 100px;
|
|
@@ -436,10 +495,11 @@ var ActionButton = styled.button `
|
|
|
436
495
|
text-align: center;
|
|
437
496
|
padding: 0 12px;
|
|
438
497
|
cursor: pointer;
|
|
439
|
-
text-overflow: ellipsis;
|
|
440
|
-
white-space: nowrap;
|
|
441
498
|
margin: 5px;
|
|
442
499
|
position: relative;
|
|
500
|
+
display: inline-flex;
|
|
501
|
+
align-items: center;
|
|
502
|
+
justify-content: center;
|
|
443
503
|
|
|
444
504
|
& svg {
|
|
445
505
|
vertical-align: middle;
|
|
@@ -450,34 +510,35 @@ var ActionButton = styled.button `
|
|
|
450
510
|
}
|
|
451
511
|
|
|
452
512
|
&:enabled:hover {
|
|
453
|
-
box-shadow:
|
|
513
|
+
box-shadow: ${getThemeValue(THEME_NAME.HOVER_SHADOW)};
|
|
454
514
|
}
|
|
455
515
|
|
|
456
516
|
&:focus {
|
|
457
|
-
box-shadow: 0 0 0 4px
|
|
517
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
458
518
|
}
|
|
459
519
|
|
|
460
520
|
&:disabled {
|
|
461
|
-
border: 1px solid ${
|
|
462
|
-
background-color:
|
|
463
|
-
color:
|
|
521
|
+
border: 1px solid ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};
|
|
522
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};
|
|
523
|
+
color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
464
524
|
}
|
|
465
525
|
`;
|
|
466
526
|
|
|
467
527
|
var IconButton = styled.button `
|
|
468
|
-
border: 1px solid
|
|
528
|
+
border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};
|
|
469
529
|
border-radius: 5px;
|
|
470
530
|
height: 32px;
|
|
471
531
|
font-size: 14px;
|
|
472
532
|
text-align: center;
|
|
473
533
|
padding: 0 3px;
|
|
474
534
|
cursor: pointer;
|
|
475
|
-
color:
|
|
476
|
-
background-color:
|
|
477
|
-
text-overflow: ellipsis;
|
|
478
|
-
white-space: nowrap;
|
|
535
|
+
color: ${getThemeValue(THEME_NAME.TEXT_COLOR_DARK)};
|
|
536
|
+
background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
479
537
|
margin: 5px;
|
|
480
538
|
position: relative;
|
|
539
|
+
display: inline-flex;
|
|
540
|
+
align-items: center;
|
|
541
|
+
justify-content: center;
|
|
481
542
|
|
|
482
543
|
& svg {
|
|
483
544
|
vertical-align: middle;
|
|
@@ -487,23 +548,23 @@ var IconButton = styled.button `
|
|
|
487
548
|
}
|
|
488
549
|
|
|
489
550
|
&:enabled:hover {
|
|
490
|
-
border-color:
|
|
491
|
-
color:
|
|
551
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
552
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
492
553
|
}
|
|
493
554
|
|
|
494
555
|
&:focus {
|
|
495
|
-
border-color:
|
|
496
|
-
box-shadow: 0 0 0 4px
|
|
556
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
557
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
497
558
|
}
|
|
498
559
|
|
|
499
560
|
&:disabled {
|
|
500
|
-
background-color: ${
|
|
501
|
-
border-color: ${
|
|
502
|
-
color: ${
|
|
561
|
+
background-color: ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};
|
|
562
|
+
border-color: ${getThemeValue(THEME_NAME.LIGHT_GREY)};
|
|
563
|
+
color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
503
564
|
}
|
|
504
565
|
|
|
505
566
|
&:disabled > svg {
|
|
506
|
-
fill: ${
|
|
567
|
+
fill: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
507
568
|
}
|
|
508
569
|
`;
|
|
509
570
|
|
|
@@ -536,42 +597,58 @@ function __rest(s, e) {
|
|
|
536
597
|
return t;
|
|
537
598
|
}
|
|
538
599
|
|
|
600
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
601
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
602
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
603
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
604
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
605
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
606
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
|
|
539
610
|
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
540
611
|
var e = new Error(message);
|
|
541
612
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
542
613
|
};
|
|
543
614
|
|
|
544
|
-
const Container$8 = styled.
|
|
615
|
+
const Container$8 = styled.span `
|
|
545
616
|
padding: 5px;
|
|
546
617
|
padding-left: 15px;
|
|
547
618
|
border-radius: 16px;
|
|
548
|
-
background-color:
|
|
619
|
+
background-color: ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};
|
|
549
620
|
display: inline-flex;
|
|
550
621
|
margin: 5px;
|
|
551
622
|
line-height: 20px;
|
|
552
623
|
align-items: center;
|
|
553
|
-
|
|
554
|
-
&:focus-within {
|
|
555
|
-
outline: 2px solid var(--primary-light, ${constants.PRIMARY_LIGHT});
|
|
556
|
-
}
|
|
557
624
|
`;
|
|
558
625
|
const Button$1 = styled.button `
|
|
559
|
-
color:
|
|
560
|
-
background-color:
|
|
626
|
+
color: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
627
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
561
628
|
border-radius: 50%;
|
|
562
629
|
border: none;
|
|
563
|
-
padding:
|
|
630
|
+
padding: 4px;
|
|
564
631
|
display: inline-flex;
|
|
565
632
|
margin-left: 5px;
|
|
633
|
+
|
|
634
|
+
&:focus-within {
|
|
635
|
+
outline: 4px solid ${getThemeValue(THEME_NAME.ERROR_LIGHT)};
|
|
636
|
+
}
|
|
566
637
|
`;
|
|
567
638
|
function Chip(props) {
|
|
568
|
-
const { label, onCloseClick } = props, rest = __rest(props, ["label", "onCloseClick"]);
|
|
639
|
+
const { label, onCloseClick, closeButtonAriaLabel } = props, rest = __rest(props, ["label", "onCloseClick", "closeButtonAriaLabel"]);
|
|
569
640
|
const keyUpHandler = (e) => {
|
|
570
|
-
if (e.
|
|
571
|
-
onCloseClick === null || onCloseClick === void 0 ? void 0 : onCloseClick();
|
|
641
|
+
if (e.key === 'Backspace' || e.key === 'Delete') {
|
|
642
|
+
onCloseClick === null || onCloseClick === void 0 ? void 0 : onCloseClick(e);
|
|
572
643
|
}
|
|
573
644
|
};
|
|
574
|
-
|
|
645
|
+
const buttonKeyDownHandler = (e) => {
|
|
646
|
+
// Stop propagation to prevent DragAndDrop from capturing Space/Enter
|
|
647
|
+
if (e.key === ' ' || e.key === 'Spacebar' || e.key === 'Enter') {
|
|
648
|
+
e.stopPropagation();
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
return (jsxRuntime.jsxs(Container$8, Object.assign({}, rest, { onKeyUp: keyUpHandler, children: [label, jsxRuntime.jsx(Button$1, { onClick: onCloseClick, onKeyDown: buttonKeyDownHandler, "aria-label": closeButtonAriaLabel !== null && closeButtonAriaLabel !== void 0 ? closeButtonAriaLabel : `Remove ${label}`, children: jsxRuntime.jsx(Close, { height: 16, width: 16 }) })] })));
|
|
575
652
|
}
|
|
576
653
|
|
|
577
654
|
exports.ORIENTATION = void 0;
|
|
@@ -586,30 +663,43 @@ const Item = styled.div `
|
|
|
586
663
|
cursor: ${(props) => (props.showIndicator ? 'default' : 'move')};
|
|
587
664
|
display: flex;
|
|
588
665
|
user-select: ${(props) => (props.showIndicator ? 'auto' : 'none')};
|
|
589
|
-
border-top: 2px
|
|
666
|
+
border-top: 2px dashed
|
|
590
667
|
${(props) => props.orientation === exports.ORIENTATION.VERTICAL && props.active > 0
|
|
591
|
-
?
|
|
668
|
+
? getThemeValue(THEME_NAME.PRIMARY)
|
|
592
669
|
: 'transparent'};
|
|
593
|
-
border-bottom: 2px
|
|
670
|
+
border-bottom: 2px dashed
|
|
594
671
|
${(props) => props.orientation === exports.ORIENTATION.VERTICAL && props.active < 0
|
|
595
|
-
?
|
|
672
|
+
? getThemeValue(THEME_NAME.PRIMARY)
|
|
596
673
|
: 'transparent'};
|
|
597
|
-
border-left: 2px
|
|
674
|
+
border-left: 2px dashed
|
|
598
675
|
${(props) => props.orientation === exports.ORIENTATION.HORIZONTAL && props.active > 0
|
|
599
|
-
?
|
|
676
|
+
? getThemeValue(THEME_NAME.PRIMARY)
|
|
600
677
|
: 'transparent'};
|
|
601
|
-
border-right: 2px
|
|
678
|
+
border-right: 2px dashed
|
|
602
679
|
${(props) => props.orientation === exports.ORIENTATION.HORIZONTAL && props.active < 0
|
|
603
|
-
?
|
|
680
|
+
? getThemeValue(THEME_NAME.PRIMARY)
|
|
604
681
|
: 'transparent'};
|
|
605
682
|
opacity: ${(props) => (props.dragging ? 0.5 : 1)};
|
|
683
|
+
border-radius: 10px;
|
|
684
|
+
|
|
685
|
+
&:focus {
|
|
686
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
&:focus:not(:focus-visible) {
|
|
690
|
+
box-shadow: none;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
&:focus-visible {
|
|
694
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
695
|
+
}
|
|
606
696
|
`;
|
|
607
697
|
/** Styled component for the drag handle indicator */
|
|
608
698
|
const DragKnob = styled.div `
|
|
609
699
|
padding-top: 8px;
|
|
610
700
|
cursor: move;
|
|
611
701
|
touch-action: none;
|
|
612
|
-
color:
|
|
702
|
+
color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
613
703
|
`;
|
|
614
704
|
/** Container for the children */
|
|
615
705
|
const Container$7 = styled.div `
|
|
@@ -648,7 +738,7 @@ const Container$7 = styled.div `
|
|
|
648
738
|
* @returns A draggable item with optional drag indicator and visual feedback
|
|
649
739
|
*/
|
|
650
740
|
function DragItem(props) {
|
|
651
|
-
const { index, orientation, children, showIndicator, dragOver } = props;
|
|
741
|
+
const { index, orientation, children, showIndicator, dragOver, totalItems, setAnnouncement } = props;
|
|
652
742
|
const [active, setActive] = React.useState(0);
|
|
653
743
|
const [touchTimer, setTouchTimer] = React.useState(null);
|
|
654
744
|
const context = React.useContext(DragContext);
|
|
@@ -750,6 +840,71 @@ function DragItem(props) {
|
|
|
750
840
|
document.body.style.overflow = 'auto';
|
|
751
841
|
}
|
|
752
842
|
};
|
|
843
|
+
/**
|
|
844
|
+
* Keyboard navigation handler for reordering items
|
|
845
|
+
* @param e Keyboard event
|
|
846
|
+
*/
|
|
847
|
+
const handleKeyDown = (e) => {
|
|
848
|
+
const isVertical = orientation === exports.ORIENTATION.VERTICAL;
|
|
849
|
+
const moveUp = isVertical ? 'ArrowUp' : 'ArrowLeft';
|
|
850
|
+
const moveDown = isVertical ? 'ArrowDown' : 'ArrowRight';
|
|
851
|
+
const isGrabbed = context.isDragging && context.startIndex === index;
|
|
852
|
+
// Space to grab/drop
|
|
853
|
+
if (e.key === ' ' || e.key === 'Spacebar') {
|
|
854
|
+
e.preventDefault();
|
|
855
|
+
if (isGrabbed) {
|
|
856
|
+
// Drop at current position
|
|
857
|
+
context.drop(index);
|
|
858
|
+
setAnnouncement(context.i18n.replacePlaceholders(context.i18n.droppedAnnouncementTemplate, {
|
|
859
|
+
position: index + 1,
|
|
860
|
+
}));
|
|
861
|
+
}
|
|
862
|
+
else {
|
|
863
|
+
// Grab item
|
|
864
|
+
context.startGrab(index);
|
|
865
|
+
setAnnouncement(context.i18n.replacePlaceholders(context.i18n.grabbedAnnouncementTemplate, {
|
|
866
|
+
position: index + 1,
|
|
867
|
+
}));
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
// Enter to drop
|
|
871
|
+
else if (e.key === 'Enter' && isGrabbed) {
|
|
872
|
+
e.preventDefault();
|
|
873
|
+
context.drop(index);
|
|
874
|
+
setAnnouncement(context.i18n.replacePlaceholders(context.i18n.droppedAnnouncementTemplate, {
|
|
875
|
+
position: index + 1,
|
|
876
|
+
}));
|
|
877
|
+
}
|
|
878
|
+
// Escape to cancel
|
|
879
|
+
else if (e.key === 'Escape' && isGrabbed) {
|
|
880
|
+
e.preventDefault();
|
|
881
|
+
context.cancel();
|
|
882
|
+
setAnnouncement(context.i18n.cancelledAnnouncementTemplate);
|
|
883
|
+
}
|
|
884
|
+
// Arrow keys to move while grabbed
|
|
885
|
+
else if (isGrabbed) {
|
|
886
|
+
if (e.key === moveUp && index > 0) {
|
|
887
|
+
e.preventDefault();
|
|
888
|
+
// Move without dropping - just reorder and update startIndex
|
|
889
|
+
const newIndex = index - 1;
|
|
890
|
+
context.onDrop(context.startIndex, newIndex);
|
|
891
|
+
context.setStartIndex(newIndex);
|
|
892
|
+
setAnnouncement(context.i18n.replacePlaceholders(context.i18n.movedAnnouncementTemplate, {
|
|
893
|
+
position: newIndex + 1,
|
|
894
|
+
}));
|
|
895
|
+
}
|
|
896
|
+
else if (e.key === moveDown && index < totalItems - 1) {
|
|
897
|
+
e.preventDefault();
|
|
898
|
+
// Move without dropping - just reorder and update startIndex
|
|
899
|
+
const newIndex = index + 1;
|
|
900
|
+
context.onDrop(context.startIndex, newIndex);
|
|
901
|
+
context.setStartIndex(newIndex);
|
|
902
|
+
setAnnouncement(context.i18n.replacePlaceholders(context.i18n.movedAnnouncementTemplate, {
|
|
903
|
+
position: newIndex + 1,
|
|
904
|
+
}));
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
};
|
|
753
908
|
/** Cleanup touch timer on unmount */
|
|
754
909
|
React.useEffect(() => {
|
|
755
910
|
return () => {
|
|
@@ -767,7 +922,9 @@ function DragItem(props) {
|
|
|
767
922
|
setActive(0);
|
|
768
923
|
}
|
|
769
924
|
}, [dragOver, context.startIndex, index, context.isDragging]);
|
|
770
|
-
return (jsxRuntime.jsxs(Item, { draggable: !showIndicator, showIndicator: showIndicator, active: active, dragging: context.isDragging && context.startIndex === index, orientation: orientation, "data-drag-index": index,
|
|
925
|
+
return (jsxRuntime.jsxs(Item, { draggable: !showIndicator, showIndicator: showIndicator, active: active, dragging: context.isDragging && context.startIndex === index, orientation: orientation, "data-drag-index": index, tabIndex: 0, role: "listitem", "aria-label": context.i18n.replacePlaceholders(context.i18n.itemAriaLabelTemplate, {
|
|
926
|
+
position: index + 1,
|
|
927
|
+
}), "aria-grabbed": context.isDragging && context.startIndex === index, onKeyDown: handleKeyDown, onDragStart: !showIndicator ? dragStartHandler : undefined, onDragOver: dragOverHandler, onDragLeave: dragExitHandler, onDrop: dropHandler, onTouchStart: !showIndicator ? touchStartHandler : undefined, onTouchMove: touchMoveHandler, onTouchEnd: touchEndHandler, onTouchCancel: touchEndHandler, children: [showIndicator && (jsxRuntime.jsx(DragKnob, { draggable: true, role: "button", "aria-label": context.i18n.dragHandleAriaLabel, onDragStart: dragStartHandler, onTouchStart: touchStartHandler, onKeyDown: handleKeyDown, tabIndex: -1, children: jsxRuntime.jsx(CheckCircle, {}) })), jsxRuntime.jsx(Container$7, { children: children })] }));
|
|
771
928
|
}
|
|
772
929
|
|
|
773
930
|
/** Container Component */
|
|
@@ -778,6 +935,18 @@ const Container$6 = styled.div `
|
|
|
778
935
|
flex-wrap: wrap;
|
|
779
936
|
flex-direction: ${(props) => (props.orientation === exports.ORIENTATION.HORIZONTAL ? 'row' : 'column')};
|
|
780
937
|
`;
|
|
938
|
+
/** Visually hidden but accessible to screen readers */
|
|
939
|
+
const VisuallyHidden$2 = styled.div `
|
|
940
|
+
position: absolute;
|
|
941
|
+
width: 1px;
|
|
942
|
+
height: 1px;
|
|
943
|
+
padding: 0;
|
|
944
|
+
margin: -1px;
|
|
945
|
+
overflow: hidden;
|
|
946
|
+
clip: rect(0, 0, 0, 0);
|
|
947
|
+
white-space: nowrap;
|
|
948
|
+
border-width: 0;
|
|
949
|
+
`;
|
|
781
950
|
/**
|
|
782
951
|
* A drag and drop container component that enables reordering of child elements.
|
|
783
952
|
*
|
|
@@ -804,10 +973,37 @@ const Container$6 = styled.div `
|
|
|
804
973
|
* @returns {JSX.Element} A draggable container with reorderable items
|
|
805
974
|
*/
|
|
806
975
|
function DragAndDrop(props) {
|
|
807
|
-
const { orientation, children, onDrop, showIndicator } = props;
|
|
976
|
+
const { orientation, children, onDrop, showIndicator, itemAriaLabelTemplate, dragHandleAriaLabel, grabbedAnnouncementTemplate, movedAnnouncementTemplate, droppedAnnouncementTemplate, cancelledAnnouncementTemplate, } = props;
|
|
808
977
|
const [startIndex, setStartIndex] = React.useState(null);
|
|
978
|
+
const [originalIndex, setOriginalIndex] = React.useState(null);
|
|
809
979
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
810
980
|
const [dragOver, setDragOver] = React.useState(null);
|
|
981
|
+
const [announcement, setAnnouncement] = React.useState('');
|
|
982
|
+
const childrenArray = React.Children.toArray(children);
|
|
983
|
+
const totalItems = childrenArray.length;
|
|
984
|
+
/**
|
|
985
|
+
* Replace placeholders in i18n templates
|
|
986
|
+
*/
|
|
987
|
+
const replacePlaceholders = (template, data) => {
|
|
988
|
+
var _a, _b, _c, _d, _e, _f;
|
|
989
|
+
return template
|
|
990
|
+
.replace(/\{:position\}/g, String((_a = data.position) !== null && _a !== void 0 ? _a : ''))
|
|
991
|
+
.replace(/\{:grabKey\}/g, (_b = data.grabKey) !== null && _b !== void 0 ? _b : 'Space')
|
|
992
|
+
.replace(/\{:dropKey\}/g, (_c = data.dropKey) !== null && _c !== void 0 ? _c : 'Space')
|
|
993
|
+
.replace(/\{:altDropKey\}/g, (_d = data.altDropKey) !== null && _d !== void 0 ? _d : 'Enter')
|
|
994
|
+
.replace(/\{:cancelKey\}/g, (_e = data.cancelKey) !== null && _e !== void 0 ? _e : 'Escape')
|
|
995
|
+
.replace(/\{:moveKeys\}/g, (_f = data.moveKeys) !== null && _f !== void 0 ? _f : (orientation === exports.ORIENTATION.VERTICAL ? 'Arrow Up/Down' : 'Arrow Left/Right'));
|
|
996
|
+
};
|
|
997
|
+
// i18n configuration object
|
|
998
|
+
const i18n = {
|
|
999
|
+
itemAriaLabelTemplate: itemAriaLabelTemplate,
|
|
1000
|
+
dragHandleAriaLabel: dragHandleAriaLabel,
|
|
1001
|
+
grabbedAnnouncementTemplate: grabbedAnnouncementTemplate,
|
|
1002
|
+
movedAnnouncementTemplate: movedAnnouncementTemplate,
|
|
1003
|
+
droppedAnnouncementTemplate: droppedAnnouncementTemplate,
|
|
1004
|
+
cancelledAnnouncementTemplate: cancelledAnnouncementTemplate,
|
|
1005
|
+
replacePlaceholders,
|
|
1006
|
+
};
|
|
811
1007
|
/**
|
|
812
1008
|
* Drop handler invoked when a draggable item is released.
|
|
813
1009
|
* @param index
|
|
@@ -817,15 +1013,58 @@ function DragAndDrop(props) {
|
|
|
817
1013
|
onDrop === null || onDrop === void 0 ? void 0 : onDrop(startIndex, index);
|
|
818
1014
|
}
|
|
819
1015
|
setStartIndex(null);
|
|
1016
|
+
setOriginalIndex(null);
|
|
1017
|
+
setIsDragging(false);
|
|
1018
|
+
};
|
|
1019
|
+
/**
|
|
1020
|
+
* Cancel handler to restore item to original position
|
|
1021
|
+
*/
|
|
1022
|
+
const cancel = () => {
|
|
1023
|
+
if (originalIndex !== null && startIndex !== null && startIndex !== originalIndex) {
|
|
1024
|
+
onDrop === null || onDrop === void 0 ? void 0 : onDrop(startIndex, originalIndex);
|
|
1025
|
+
}
|
|
1026
|
+
setStartIndex(null);
|
|
1027
|
+
setOriginalIndex(null);
|
|
820
1028
|
setIsDragging(false);
|
|
821
1029
|
};
|
|
822
|
-
|
|
1030
|
+
/**
|
|
1031
|
+
* Start grab handler to track original position
|
|
1032
|
+
*/
|
|
1033
|
+
const startGrab = (index) => {
|
|
1034
|
+
setStartIndex(index);
|
|
1035
|
+
setOriginalIndex(index);
|
|
1036
|
+
setIsDragging(true);
|
|
1037
|
+
};
|
|
1038
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(DragContext.Provider, { value: {
|
|
1039
|
+
startIndex,
|
|
1040
|
+
setStartIndex,
|
|
1041
|
+
drop,
|
|
1042
|
+
onDrop,
|
|
1043
|
+
cancel,
|
|
1044
|
+
startGrab,
|
|
1045
|
+
isDragging,
|
|
1046
|
+
setIsDragging,
|
|
1047
|
+
setDragOver,
|
|
1048
|
+
i18n,
|
|
1049
|
+
}, children: jsxRuntime.jsx(Container$6, { orientation: orientation, role: "list", children: React.Children.map(childrenArray, (child, index) => (jsxRuntime.jsx(DragItem, { index: index, orientation: orientation, showIndicator: showIndicator, dragOver: dragOver, totalItems: totalItems, setAnnouncement: setAnnouncement, children: child }))) }) }), jsxRuntime.jsx(VisuallyHidden$2, { role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement })] }));
|
|
823
1050
|
}
|
|
824
1051
|
DragAndDrop.defaultProps = {
|
|
825
1052
|
/** Orientation of the list layout */
|
|
826
1053
|
orientation: exports.ORIENTATION.VERTICAL,
|
|
827
1054
|
/** Whether to display drag indicators for each list item */
|
|
828
1055
|
showIndicator: false,
|
|
1056
|
+
/** Default item aria-label template */
|
|
1057
|
+
itemAriaLabelTemplate: 'Item {:position}. Press {:grabKey} to grab, {:moveKeys} to move, {:dropKey} or {:altDropKey} to drop',
|
|
1058
|
+
/** Default drag handle aria-label */
|
|
1059
|
+
dragHandleAriaLabel: 'Drag to reorder',
|
|
1060
|
+
/** Default grabbed announcement template */
|
|
1061
|
+
grabbedAnnouncementTemplate: 'Item {:position} grabbed. Use {:moveKeys} to move, {:dropKey} or {:altDropKey} to drop, {:cancelKey} to cancel',
|
|
1062
|
+
/** Default moved announcement template */
|
|
1063
|
+
movedAnnouncementTemplate: 'Item moved to position {:position}',
|
|
1064
|
+
/** Default dropped announcement template */
|
|
1065
|
+
droppedAnnouncementTemplate: 'Item dropped at position {:position}',
|
|
1066
|
+
/** Default cancelled announcement template */
|
|
1067
|
+
cancelledAnnouncementTemplate: 'Drag cancelled, item restored to original position',
|
|
829
1068
|
};
|
|
830
1069
|
|
|
831
1070
|
// Label component for the ChipInput
|
|
@@ -839,45 +1078,45 @@ const Label$6 = styled.label `
|
|
|
839
1078
|
padding: 0 8px;
|
|
840
1079
|
width: 250px;
|
|
841
1080
|
border-radius: 3px;
|
|
842
|
-
border: 1px solid
|
|
843
|
-
background-color:
|
|
1081
|
+
border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};
|
|
1082
|
+
background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
844
1083
|
|
|
845
1084
|
/** Focused */
|
|
846
1085
|
&:has(:focus),
|
|
847
1086
|
&:has(:active) {
|
|
848
|
-
border-color:
|
|
849
|
-
box-shadow: 0 0 0 4px
|
|
1087
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
1088
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
850
1089
|
}
|
|
851
1090
|
|
|
852
1091
|
&:has(:focus) > span,
|
|
853
1092
|
&:has(:active) > span {
|
|
854
|
-
color:
|
|
1093
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
855
1094
|
}
|
|
856
1095
|
|
|
857
1096
|
/** Disabled */
|
|
858
1097
|
&:has(:disabled) {
|
|
859
|
-
border-color:
|
|
860
|
-
background-color:
|
|
1098
|
+
border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
1099
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};
|
|
861
1100
|
}
|
|
862
1101
|
|
|
863
1102
|
&:has(:disabled) > span {
|
|
864
|
-
color:
|
|
1103
|
+
color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
865
1104
|
}
|
|
866
1105
|
|
|
867
1106
|
/** Invalid */
|
|
868
1107
|
&:has(:focus:invalid) {
|
|
869
|
-
border-color:
|
|
870
|
-
box-shadow: 0 0 0 4px
|
|
1108
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1109
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.ERROR_LIGHT)};
|
|
871
1110
|
}
|
|
872
1111
|
|
|
873
1112
|
${(props) => props.touched
|
|
874
1113
|
? `
|
|
875
1114
|
&:has(:invalid) {
|
|
876
|
-
border-color:
|
|
1115
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
877
1116
|
}
|
|
878
1117
|
|
|
879
1118
|
&:has(:invalid) > span {
|
|
880
|
-
color:
|
|
1119
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
881
1120
|
}
|
|
882
1121
|
`
|
|
883
1122
|
: ''}
|
|
@@ -885,10 +1124,10 @@ const Label$6 = styled.label `
|
|
|
885
1124
|
/** Error */
|
|
886
1125
|
${(props) => props.errorText
|
|
887
1126
|
? `
|
|
888
|
-
border-color:
|
|
1127
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
889
1128
|
|
|
890
1129
|
& > span {
|
|
891
|
-
color:
|
|
1130
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
892
1131
|
}
|
|
893
1132
|
`
|
|
894
1133
|
: ''}
|
|
@@ -897,15 +1136,15 @@ const Label$6 = styled.label `
|
|
|
897
1136
|
&:has(:required) > span:after {
|
|
898
1137
|
content: '*';
|
|
899
1138
|
margin-left: 2px;
|
|
900
|
-
color:
|
|
1139
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
901
1140
|
}
|
|
902
1141
|
|
|
903
1142
|
& > input {
|
|
904
1143
|
border: none;
|
|
905
1144
|
outline: none;
|
|
906
|
-
width: 100%;
|
|
907
1145
|
line-height: 30px;
|
|
908
1146
|
min-height: 30px;
|
|
1147
|
+
max-width: 95%;
|
|
909
1148
|
}
|
|
910
1149
|
|
|
911
1150
|
/** Label Animation */
|
|
@@ -922,7 +1161,7 @@ const Label$6 = styled.label `
|
|
|
922
1161
|
&:has(:focus) > span,
|
|
923
1162
|
&:has(:placeholder-shown) > span {
|
|
924
1163
|
top: -8px;
|
|
925
|
-
background:
|
|
1164
|
+
background: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
926
1165
|
font-size: 12px;
|
|
927
1166
|
line-height: 14px;
|
|
928
1167
|
}
|
|
@@ -931,7 +1170,7 @@ const Label$6 = styled.label `
|
|
|
931
1170
|
? `
|
|
932
1171
|
& > span {
|
|
933
1172
|
top: -8px;
|
|
934
|
-
background:
|
|
1173
|
+
background: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
935
1174
|
font-size: 12px;
|
|
936
1175
|
line-height: 14px;
|
|
937
1176
|
}
|
|
@@ -940,12 +1179,28 @@ const Label$6 = styled.label `
|
|
|
940
1179
|
`;
|
|
941
1180
|
// Error message container
|
|
942
1181
|
const ErrorContainer$4 = styled.div `
|
|
943
|
-
color:
|
|
1182
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
944
1183
|
padding-top: 3px;
|
|
945
1184
|
font-size: 12px;
|
|
946
1185
|
line-height: 14px;
|
|
947
1186
|
margin-left: 3px;
|
|
948
1187
|
`;
|
|
1188
|
+
// Visually hidden but accessible to screen readers
|
|
1189
|
+
const VisuallyHidden$1 = styled.ul `
|
|
1190
|
+
position: absolute;
|
|
1191
|
+
width: 1px;
|
|
1192
|
+
height: 1px;
|
|
1193
|
+
padding: 0;
|
|
1194
|
+
margin: -1px;
|
|
1195
|
+
overflow: hidden;
|
|
1196
|
+
clip: rect(0, 0, 0, 0);
|
|
1197
|
+
white-space: nowrap;
|
|
1198
|
+
border-width: 0;
|
|
1199
|
+
|
|
1200
|
+
& li {
|
|
1201
|
+
list-style: none;
|
|
1202
|
+
}
|
|
1203
|
+
`;
|
|
949
1204
|
/**
|
|
950
1205
|
* A chip input component that allows users to add and remove chips (tags) by typing and pressing Enter.
|
|
951
1206
|
* @component
|
|
@@ -964,9 +1219,21 @@ function ChipInput(props) {
|
|
|
964
1219
|
const [touched, setTouched] = React.useState(false);
|
|
965
1220
|
const [value, setValue] = React.useState(props.value);
|
|
966
1221
|
const InputRef = React.useRef(null);
|
|
1222
|
+
const [announcement, setAnnouncement] = React.useState('');
|
|
1223
|
+
const errorId = React.useId();
|
|
1224
|
+
/**
|
|
1225
|
+
* Replace {:label} placeholder in template string
|
|
1226
|
+
*/
|
|
1227
|
+
const replacePlaceholder = (template, label) => {
|
|
1228
|
+
if (!template)
|
|
1229
|
+
return undefined;
|
|
1230
|
+
return template.replace(/\{:label\}/g, label);
|
|
1231
|
+
};
|
|
967
1232
|
// Sync internal value with props.value
|
|
968
1233
|
React.useEffect(() => {
|
|
969
|
-
|
|
1234
|
+
if (Array.isArray(props.value)) {
|
|
1235
|
+
setValue(props.value);
|
|
1236
|
+
}
|
|
970
1237
|
}, [props.value]);
|
|
971
1238
|
/**
|
|
972
1239
|
* Update the chip values and notify changes.
|
|
@@ -1004,6 +1271,7 @@ function ChipInput(props) {
|
|
|
1004
1271
|
const newValue = [...value, text.trim()];
|
|
1005
1272
|
updateValue(newValue);
|
|
1006
1273
|
setText('');
|
|
1274
|
+
setAnnouncement(replacePlaceholder(props.addedAnnouncementTemplate, text.trim()));
|
|
1007
1275
|
}
|
|
1008
1276
|
};
|
|
1009
1277
|
/**
|
|
@@ -1013,6 +1281,7 @@ function ChipInput(props) {
|
|
|
1013
1281
|
const removeChip = (chipToRemove) => {
|
|
1014
1282
|
const newValue = value.filter((chip) => chip !== chipToRemove);
|
|
1015
1283
|
updateValue(newValue);
|
|
1284
|
+
setAnnouncement(replacePlaceholder(props.removedAnnouncementTemplate, chipToRemove));
|
|
1016
1285
|
};
|
|
1017
1286
|
/**
|
|
1018
1287
|
* Moves a chip from one position to another.
|
|
@@ -1030,7 +1299,7 @@ function ChipInput(props) {
|
|
|
1030
1299
|
updateValue(newItems);
|
|
1031
1300
|
};
|
|
1032
1301
|
// Render the component
|
|
1033
|
-
return (jsxRuntime.jsxs(Label$6, { text: text, touched: touched, errorText: props.errorText, children: [jsxRuntime.jsx("input", Object.assign({}, props, { ref: InputRef,
|
|
1302
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs(Label$6, { text: text, touched: touched, errorText: props.errorText, children: [jsxRuntime.jsx("input", Object.assign({}, props, { ref: InputRef, value: text, onChange: handleChange, onFocus: handleFocus, onKeyUp: handleKeyUp, required: props.required && value.length === 0, "aria-required": props.required, "aria-invalid": !!props.errorText, "aria-describedby": props.errorText ? errorId : undefined })), jsxRuntime.jsx("div", { children: (value === null || value === void 0 ? void 0 : value.length) > 0 && (jsxRuntime.jsx(DragAndDrop, { orientation: exports.ORIENTATION.HORIZONTAL, onDrop: onDrop, children: value.map((chip) => (jsxRuntime.jsx(Chip, { label: chip, onCloseClick: () => removeChip(chip), closeButtonAriaLabel: replacePlaceholder(props.closeButtonAriaLabel, chip) }, chip))) })) }), jsxRuntime.jsx("span", { children: props.label }), props.errorText && jsxRuntime.jsx(ErrorContainer$4, { id: errorId, children: props.errorText })] }), jsxRuntime.jsx(VisuallyHidden$1, { "aria-live": "polite", "aria-atomic": "true", children: announcement })] }));
|
|
1034
1303
|
}
|
|
1035
1304
|
ChipInput.propTypes = {
|
|
1036
1305
|
/** Label for the field */
|
|
@@ -1041,9 +1310,18 @@ ChipInput.propTypes = {
|
|
|
1041
1310
|
value: PropTypes.arrayOf(PropTypes.string),
|
|
1042
1311
|
/** Callback when chips change */
|
|
1043
1312
|
onChange: PropTypes.func,
|
|
1313
|
+
/** Aria label for the close button on chip. Defaults to "Remove {label}" */
|
|
1314
|
+
closeButtonAriaLabel: PropTypes.string,
|
|
1315
|
+
/** Announcement text when a chip is added. Defaults to "{label} was added" */
|
|
1316
|
+
addedAnnouncementTemplate: PropTypes.string,
|
|
1317
|
+
/** Announcement text when a chip is removed. Defaults to "{label} was removed" */
|
|
1318
|
+
removedAnnouncementTemplate: PropTypes.string,
|
|
1044
1319
|
};
|
|
1045
1320
|
ChipInput.defaultProps = {
|
|
1046
1321
|
value: [],
|
|
1322
|
+
closeButtonAriaLabel: 'Remove {:label}',
|
|
1323
|
+
addedAnnouncementTemplate: '{:label} was added',
|
|
1324
|
+
removedAnnouncementTemplate: '{:label} was removed',
|
|
1047
1325
|
};
|
|
1048
1326
|
|
|
1049
1327
|
/** Enums for layer position on screen. */
|
|
@@ -1088,7 +1366,7 @@ const Container$5 = styled.div `
|
|
|
1088
1366
|
`
|
|
1089
1367
|
width: 100%;
|
|
1090
1368
|
height: 100vh;
|
|
1091
|
-
background-color:
|
|
1369
|
+
background-color: ${getThemeValue(THEME_NAME.BACKDROP_COLOR)};
|
|
1092
1370
|
backdrop-filter: blur(0px);
|
|
1093
1371
|
pointer-events: all;
|
|
1094
1372
|
`}
|
|
@@ -1188,6 +1466,7 @@ class LayerManager {
|
|
|
1188
1466
|
const layerConfig = Object.assign(Object.assign({}, defaultConfig), config);
|
|
1189
1467
|
// Get the z-index for the new layer
|
|
1190
1468
|
const currentIndex = layerConfig.alwaysOnTop ? 2147483647 : this.nextIndex++;
|
|
1469
|
+
const className = layerConfig.alwaysOnTop ? 'nf-layer-manager-top' : 'nf-layer-manager';
|
|
1191
1470
|
// Create a unique ID for tracking this layer
|
|
1192
1471
|
const layerId = `nf-layer-manager-${currentIndex}`;
|
|
1193
1472
|
const overlayClickHandler = () => {
|
|
@@ -1209,6 +1488,7 @@ class LayerManager {
|
|
|
1209
1488
|
React.useEffect(() => {
|
|
1210
1489
|
// Create the div element only once when component mounts
|
|
1211
1490
|
const div = document.createElement('div');
|
|
1491
|
+
div.setAttribute('class', className);
|
|
1212
1492
|
div.setAttribute('id', layerId);
|
|
1213
1493
|
document.body.appendChild(div);
|
|
1214
1494
|
// Add layer to stack
|
|
@@ -1223,8 +1503,67 @@ class LayerManager {
|
|
|
1223
1503
|
setTimeout(() => {
|
|
1224
1504
|
div.setAttribute('class', 'nf-layer-enter');
|
|
1225
1505
|
}, 10);
|
|
1506
|
+
// Track elements modified for accessibility
|
|
1507
|
+
const modifiedElements = [];
|
|
1508
|
+
let originalBodyOverflow = null;
|
|
1509
|
+
let originalBodyPosition = null;
|
|
1510
|
+
let originalBodyWidth = null;
|
|
1511
|
+
let originalBodyTop = null;
|
|
1512
|
+
let scrollY = 0;
|
|
1513
|
+
// Apply aria-hidden to siblings and body scroll lock for overlay modals
|
|
1514
|
+
if (layerConfig.overlay) {
|
|
1515
|
+
// Hide all body children except this layer portal, scripts, and styles
|
|
1516
|
+
const bodyChildren = Array.from(document.body.children);
|
|
1517
|
+
bodyChildren.forEach((child) => {
|
|
1518
|
+
if (child !== div &&
|
|
1519
|
+
child.className !== 'nf-layer-manager-top' &&
|
|
1520
|
+
child.tagName !== 'SCRIPT' &&
|
|
1521
|
+
child.tagName !== 'STYLE') {
|
|
1522
|
+
const hadAriaHidden = child.hasAttribute('aria-hidden');
|
|
1523
|
+
const previousValue = child.getAttribute('aria-hidden');
|
|
1524
|
+
// Only set aria-hidden if not already hidden
|
|
1525
|
+
if (previousValue !== 'true') {
|
|
1526
|
+
child.setAttribute('aria-hidden', 'true');
|
|
1527
|
+
modifiedElements.push({
|
|
1528
|
+
element: child,
|
|
1529
|
+
hadAriaHidden,
|
|
1530
|
+
previousValue,
|
|
1531
|
+
});
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
});
|
|
1535
|
+
// Prevent body scroll on iOS
|
|
1536
|
+
scrollY = window.scrollY;
|
|
1537
|
+
originalBodyOverflow = document.body.style.overflow;
|
|
1538
|
+
originalBodyPosition = document.body.style.position;
|
|
1539
|
+
originalBodyWidth = document.body.style.width;
|
|
1540
|
+
originalBodyTop = document.body.style.top;
|
|
1541
|
+
document.body.style.overflow = 'hidden';
|
|
1542
|
+
document.body.style.position = 'fixed';
|
|
1543
|
+
document.body.style.width = '100%';
|
|
1544
|
+
document.body.style.top = `-${scrollY}px`;
|
|
1545
|
+
}
|
|
1226
1546
|
// Cleanup function - remove div when component unmounts
|
|
1227
1547
|
return () => {
|
|
1548
|
+
// Restore aria-hidden attributes
|
|
1549
|
+
modifiedElements.forEach(({ element, hadAriaHidden, previousValue }) => {
|
|
1550
|
+
if (document.body.contains(element)) {
|
|
1551
|
+
if (hadAriaHidden && previousValue !== null) {
|
|
1552
|
+
element.setAttribute('aria-hidden', previousValue);
|
|
1553
|
+
}
|
|
1554
|
+
else {
|
|
1555
|
+
element.removeAttribute('aria-hidden');
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
});
|
|
1559
|
+
// Restore body scroll
|
|
1560
|
+
if (layerConfig.overlay) {
|
|
1561
|
+
document.body.style.overflow = originalBodyOverflow || '';
|
|
1562
|
+
document.body.style.position = originalBodyPosition || '';
|
|
1563
|
+
document.body.style.width = originalBodyWidth || '';
|
|
1564
|
+
document.body.style.top = originalBodyTop || '';
|
|
1565
|
+
window.scrollTo(0, scrollY);
|
|
1566
|
+
}
|
|
1228
1567
|
if (document.body.contains(div)) {
|
|
1229
1568
|
document.body.removeChild(div);
|
|
1230
1569
|
}
|
|
@@ -1278,12 +1617,94 @@ const DialogContainer = styled(Card) `
|
|
|
1278
1617
|
class Dialog extends React.Component {
|
|
1279
1618
|
constructor() {
|
|
1280
1619
|
super(...arguments);
|
|
1620
|
+
this.lastFocusedElement = null;
|
|
1621
|
+
this.dialogRef = React.createRef();
|
|
1281
1622
|
this.state = {
|
|
1282
1623
|
show: false,
|
|
1283
1624
|
LayerComponent: undefined,
|
|
1284
1625
|
};
|
|
1626
|
+
/**
|
|
1627
|
+
* Retrieves all focusable elements within the dialog.
|
|
1628
|
+
*/
|
|
1629
|
+
this.getFocusableElements = () => {
|
|
1630
|
+
if (!this.dialogRef.current)
|
|
1631
|
+
return [];
|
|
1632
|
+
return Array.from(this.dialogRef.current.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'));
|
|
1633
|
+
};
|
|
1634
|
+
/**
|
|
1635
|
+
* Handles keydown events to implement the focus trap.
|
|
1636
|
+
* Traps Tab and Shift+Tab within the dialog.
|
|
1637
|
+
*/
|
|
1638
|
+
this.handleKeyDown = (e) => {
|
|
1639
|
+
if (e.key === 'Tab') {
|
|
1640
|
+
const focusableElements = this.getFocusableElements();
|
|
1641
|
+
if (focusableElements.length === 0)
|
|
1642
|
+
return;
|
|
1643
|
+
const firstElement = focusableElements[0];
|
|
1644
|
+
const lastElement = focusableElements[focusableElements.length - 1];
|
|
1645
|
+
if (e.shiftKey) {
|
|
1646
|
+
if (document.activeElement === firstElement) {
|
|
1647
|
+
lastElement.focus();
|
|
1648
|
+
e.preventDefault();
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
else {
|
|
1652
|
+
if (document.activeElement === lastElement) {
|
|
1653
|
+
firstElement.focus();
|
|
1654
|
+
e.preventDefault();
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
};
|
|
1659
|
+
/**
|
|
1660
|
+
* Restores focus to the element that was focused before the dialog opened.
|
|
1661
|
+
*/
|
|
1662
|
+
this.restoreFocus = () => {
|
|
1663
|
+
if (this.lastFocusedElement) {
|
|
1664
|
+
const elementToBeFocused = this.lastFocusedElement;
|
|
1665
|
+
this.lastFocusedElement = null;
|
|
1666
|
+
setTimeout(() => {
|
|
1667
|
+
if (document.body.contains(elementToBeFocused)) {
|
|
1668
|
+
elementToBeFocused.focus();
|
|
1669
|
+
}
|
|
1670
|
+
}, 100);
|
|
1671
|
+
}
|
|
1672
|
+
};
|
|
1673
|
+
/**
|
|
1674
|
+
* Callback ref to capture the Dialog DOM element.
|
|
1675
|
+
* Triggers initial focus setting when the element mounts.
|
|
1676
|
+
*/
|
|
1677
|
+
this.setDialogRef = (node) => {
|
|
1678
|
+
this.dialogRef.current = node;
|
|
1679
|
+
if (node) {
|
|
1680
|
+
this.setInitialFocus(node);
|
|
1681
|
+
}
|
|
1682
|
+
};
|
|
1683
|
+
/**
|
|
1684
|
+
* Sets initial focus within the dialog.
|
|
1685
|
+
* Tries to focus the header first, then the first interactive element, or falls back to the container.
|
|
1686
|
+
*/
|
|
1687
|
+
this.setInitialFocus = (root) => {
|
|
1688
|
+
const firstChild = root.firstElementChild;
|
|
1689
|
+
if (firstChild) {
|
|
1690
|
+
if (firstChild.getAttribute('tabindex') === null) {
|
|
1691
|
+
firstChild.setAttribute('tabindex', '-1');
|
|
1692
|
+
}
|
|
1693
|
+
firstChild.focus();
|
|
1694
|
+
return;
|
|
1695
|
+
}
|
|
1696
|
+
const focusableElements = this.getFocusableElements();
|
|
1697
|
+
if (focusableElements.length > 0) {
|
|
1698
|
+
focusableElements[0].focus();
|
|
1699
|
+
}
|
|
1700
|
+
else {
|
|
1701
|
+
root.focus();
|
|
1702
|
+
}
|
|
1703
|
+
};
|
|
1285
1704
|
this.open = (closeCallback) => {
|
|
1286
1705
|
const _a = this.props, { closeOnEsc, closeOnOverlayClick, children } = _a, rest = __rest(_a, ["closeOnEsc", "closeOnOverlayClick", "children"]);
|
|
1706
|
+
// Save current focus
|
|
1707
|
+
this.lastFocusedElement = document.activeElement;
|
|
1287
1708
|
const [Component, closeFn] = LayerManager$1.renderLayer({
|
|
1288
1709
|
exitDelay: 300,
|
|
1289
1710
|
overlay: true,
|
|
@@ -1291,7 +1712,7 @@ class Dialog extends React.Component {
|
|
|
1291
1712
|
closeCallback: this.closeCallback,
|
|
1292
1713
|
closeOnOverlayClick,
|
|
1293
1714
|
position: LAYER_POSITION.DIALOG,
|
|
1294
|
-
component: (jsxRuntime.jsx(DialogContainer, Object.assign({}, rest, { onClick: (e) => e.stopPropagation(), elevated: true, children: children }))),
|
|
1715
|
+
component: (jsxRuntime.jsx(DialogContainer, Object.assign({}, rest, { ref: this.setDialogRef, role: "dialog", "aria-modal": "true", tabIndex: -1, onKeyDown: this.handleKeyDown, onClick: (e) => e.stopPropagation(), elevated: true, children: children }))),
|
|
1295
1716
|
});
|
|
1296
1717
|
this.closeDialog = closeFn;
|
|
1297
1718
|
this.setState({
|
|
@@ -1306,6 +1727,7 @@ class Dialog extends React.Component {
|
|
|
1306
1727
|
};
|
|
1307
1728
|
this.closeCallback = (resp) => {
|
|
1308
1729
|
var _a;
|
|
1730
|
+
this.restoreFocus();
|
|
1309
1731
|
this.setState({
|
|
1310
1732
|
show: false,
|
|
1311
1733
|
LayerComponent: undefined,
|
|
@@ -1337,6 +1759,7 @@ Dialog.defaultProps = {
|
|
|
1337
1759
|
closeOnOverlayClick: true,
|
|
1338
1760
|
};
|
|
1339
1761
|
|
|
1762
|
+
let dialogCounter = 0;
|
|
1340
1763
|
class AlertDialog extends React.Component {
|
|
1341
1764
|
constructor() {
|
|
1342
1765
|
super(...arguments);
|
|
@@ -1350,7 +1773,9 @@ class AlertDialog extends React.Component {
|
|
|
1350
1773
|
this.close = () => this.dialog.current.close();
|
|
1351
1774
|
}
|
|
1352
1775
|
render() {
|
|
1353
|
-
|
|
1776
|
+
const titleId = `nfui-alert-dialog-${dialogCounter++}-title`;
|
|
1777
|
+
const descriptionId = `nfui-alert-dialog-${dialogCounter++}-description`;
|
|
1778
|
+
return (jsxRuntime.jsxs(Dialog, Object.assign({}, this.props.dialogProps, { role: "alertdialog", "aria-labelledby": titleId, "aria-describedby": descriptionId, ref: this.dialog, closeOnEsc: false, closeOnOverlayClick: false, children: [this.props.header && jsxRuntime.jsx(Header$1, { id: titleId, children: this.props.header }), jsxRuntime.jsx(Body$1, { id: descriptionId, children: this.props.body }), jsxRuntime.jsx(Footer$1, { children: jsxRuntime.jsx(StyledButton, { onClick: this.close, children: this.props.buttonText }) })] })));
|
|
1354
1779
|
}
|
|
1355
1780
|
}
|
|
1356
1781
|
AlertDialog.propTypes = {
|
|
@@ -1389,7 +1814,7 @@ class ConfirmDialog extends React.Component {
|
|
|
1389
1814
|
}
|
|
1390
1815
|
render() {
|
|
1391
1816
|
const { header, body, yesText, noText, dialogProps } = this.props;
|
|
1392
|
-
return (jsxRuntime.jsxs(Dialog, Object.assign({}, dialogProps, { ref: this.dialog, closeOnEsc: false, closeOnOverlayClick: false, children: [header && jsxRuntime.jsx(Header$1, { children: header }), jsxRuntime.jsx(Body$1, { children: body }), jsxRuntime.jsxs(Footer$1, { children: [jsxRuntime.jsx(
|
|
1817
|
+
return (jsxRuntime.jsxs(Dialog, Object.assign({}, dialogProps, { ref: this.dialog, closeOnEsc: false, closeOnOverlayClick: false, children: [header && jsxRuntime.jsx(Header$1, { children: header }), jsxRuntime.jsx(Body$1, { children: body }), jsxRuntime.jsxs(Footer$1, { children: [jsxRuntime.jsx(StyledButton, { onClick: this.cancel, children: noText }), jsxRuntime.jsx(ActionButton, { onClick: this.confirm, children: yesText })] })] })));
|
|
1393
1818
|
}
|
|
1394
1819
|
}
|
|
1395
1820
|
ConfirmDialog.propTypes = {
|
|
@@ -1412,7 +1837,6 @@ ConfirmDialog.defaultProps = {
|
|
|
1412
1837
|
const Label$5 = styled.label `
|
|
1413
1838
|
display: inline-flex;
|
|
1414
1839
|
flex-direction: column;
|
|
1415
|
-
flex: 1;
|
|
1416
1840
|
position: relative;
|
|
1417
1841
|
margin: 10px 5px;
|
|
1418
1842
|
`;
|
|
@@ -1424,46 +1848,46 @@ const TextField$1 = styled.input `
|
|
|
1424
1848
|
min-height: 30px;
|
|
1425
1849
|
width: 250px;
|
|
1426
1850
|
border-radius: 3px;
|
|
1427
|
-
border: 1px solid
|
|
1851
|
+
border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};
|
|
1428
1852
|
display: inline-block;
|
|
1429
|
-
background-color:
|
|
1853
|
+
background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
1430
1854
|
|
|
1431
1855
|
/** Focused */
|
|
1432
1856
|
&:focus,
|
|
1433
1857
|
&:active {
|
|
1434
|
-
border-color:
|
|
1435
|
-
box-shadow: 0 0 0 4px
|
|
1858
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
1859
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
1436
1860
|
}
|
|
1437
1861
|
|
|
1438
1862
|
&:focus + span,
|
|
1439
1863
|
&:active + span {
|
|
1440
|
-
color:
|
|
1864
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
1441
1865
|
}
|
|
1442
1866
|
|
|
1443
1867
|
/** Disabled */
|
|
1444
1868
|
&:disabled {
|
|
1445
|
-
border-color:
|
|
1446
|
-
background-color:
|
|
1869
|
+
border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
1870
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};
|
|
1447
1871
|
}
|
|
1448
1872
|
|
|
1449
1873
|
&:disabled + span {
|
|
1450
|
-
color:
|
|
1874
|
+
color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
1451
1875
|
}
|
|
1452
1876
|
|
|
1453
1877
|
/** Invalid */
|
|
1454
1878
|
&:focus:invalid {
|
|
1455
|
-
border-color:
|
|
1456
|
-
box-shadow: 0 0 0 4px
|
|
1879
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1880
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.ERROR_LIGHT)};
|
|
1457
1881
|
}
|
|
1458
1882
|
|
|
1459
1883
|
${(props) => props.touched
|
|
1460
1884
|
? `
|
|
1461
1885
|
&:invalid {
|
|
1462
|
-
border-color:
|
|
1886
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1463
1887
|
}
|
|
1464
1888
|
|
|
1465
1889
|
&:invalid + span {
|
|
1466
|
-
color:
|
|
1890
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1467
1891
|
}
|
|
1468
1892
|
`
|
|
1469
1893
|
: ''}
|
|
@@ -1471,10 +1895,10 @@ const TextField$1 = styled.input `
|
|
|
1471
1895
|
/** Error */
|
|
1472
1896
|
${(props) => props.errorText
|
|
1473
1897
|
? `
|
|
1474
|
-
border-color:
|
|
1898
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1475
1899
|
|
|
1476
1900
|
& + span {
|
|
1477
|
-
color:
|
|
1901
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1478
1902
|
}
|
|
1479
1903
|
`
|
|
1480
1904
|
: ''}
|
|
@@ -1483,7 +1907,7 @@ const TextField$1 = styled.input `
|
|
|
1483
1907
|
&:required + span:after {
|
|
1484
1908
|
content: '*';
|
|
1485
1909
|
margin-left: 2px;
|
|
1486
|
-
color:
|
|
1910
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1487
1911
|
}
|
|
1488
1912
|
|
|
1489
1913
|
/** Label Animation */
|
|
@@ -1501,7 +1925,7 @@ const TextField$1 = styled.input `
|
|
|
1501
1925
|
? `
|
|
1502
1926
|
& + span {
|
|
1503
1927
|
top: -8px;
|
|
1504
|
-
background:
|
|
1928
|
+
background: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
1505
1929
|
font-size: 12px;
|
|
1506
1930
|
line-height: 14px;
|
|
1507
1931
|
}
|
|
@@ -1510,21 +1934,27 @@ const TextField$1 = styled.input `
|
|
|
1510
1934
|
|
|
1511
1935
|
&:focus + span, &:placeholder-shown + span {
|
|
1512
1936
|
top: -8px;
|
|
1513
|
-
background:
|
|
1937
|
+
background: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
1514
1938
|
font-size: 12px;
|
|
1515
1939
|
line-height: 14px;
|
|
1516
1940
|
}
|
|
1517
1941
|
`;
|
|
1518
1942
|
const ErrorContainer$3 = styled.div `
|
|
1519
|
-
color:
|
|
1943
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1520
1944
|
padding-top: 3px;
|
|
1521
1945
|
font-size: 12px;
|
|
1522
1946
|
line-height: 14px;
|
|
1523
1947
|
margin-left: 3px;
|
|
1524
1948
|
`;
|
|
1525
|
-
const Input$
|
|
1949
|
+
const Input$2 = React.forwardRef((props, ref) => {
|
|
1526
1950
|
const [touched, setTouched] = React.useState(false);
|
|
1527
1951
|
const [value, setValue] = React.useState(props.value || '');
|
|
1952
|
+
const errorId = React.useId();
|
|
1953
|
+
React.useEffect(() => {
|
|
1954
|
+
if (props.value !== undefined) {
|
|
1955
|
+
setValue(props.value);
|
|
1956
|
+
}
|
|
1957
|
+
}, [props.value]);
|
|
1528
1958
|
const handleFocus = (e) => {
|
|
1529
1959
|
setTouched(true);
|
|
1530
1960
|
if (props.onFocus) {
|
|
@@ -1540,10 +1970,10 @@ const Input$4 = React.forwardRef((props, ref) => {
|
|
|
1540
1970
|
setValue(e.target.value);
|
|
1541
1971
|
}
|
|
1542
1972
|
};
|
|
1543
|
-
return (jsxRuntime.jsxs(Label$5, { children: [jsxRuntime.jsx(TextField$1, Object.assign({}, props, { ref: ref, value: value, onChange: onChangeHandler, onFocus: handleFocus, touched: touched })), jsxRuntime.jsx("span", { children: props.label }), props.errorText && jsxRuntime.jsx(ErrorContainer$3, { children: props.errorText })] }));
|
|
1973
|
+
return (jsxRuntime.jsxs(Label$5, { children: [jsxRuntime.jsx(TextField$1, Object.assign({}, props, { ref: ref, value: value, onChange: onChangeHandler, onFocus: handleFocus, touched: touched, "aria-invalid": !!props.errorText, "aria-required": props.required, "aria-describedby": props.errorText ? errorId : undefined })), jsxRuntime.jsx("span", { children: props.label }), props.errorText && jsxRuntime.jsx(ErrorContainer$3, { id: errorId, children: props.errorText })] }));
|
|
1544
1974
|
});
|
|
1545
|
-
Input$
|
|
1546
|
-
Input$
|
|
1975
|
+
Input$2.displayName = 'Input';
|
|
1976
|
+
Input$2.propTypes = {
|
|
1547
1977
|
/** Label for the field */
|
|
1548
1978
|
label: PropTypes.string,
|
|
1549
1979
|
/** Error text to be shown below the field */
|
|
@@ -1553,7 +1983,6 @@ Input$4.propTypes = {
|
|
|
1553
1983
|
const Label$4 = styled.label `
|
|
1554
1984
|
display: inline-flex;
|
|
1555
1985
|
flex-direction: column;
|
|
1556
|
-
flex: 1;
|
|
1557
1986
|
position: relative;
|
|
1558
1987
|
margin: 10px 5px;
|
|
1559
1988
|
`;
|
|
@@ -1564,46 +1993,46 @@ const TextField = styled.textarea `
|
|
|
1564
1993
|
min-height: 150px;
|
|
1565
1994
|
min-width: 250px;
|
|
1566
1995
|
border-radius: 3px;
|
|
1567
|
-
border: 1px solid
|
|
1996
|
+
border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};
|
|
1568
1997
|
display: inline-block;
|
|
1569
|
-
background-color:
|
|
1998
|
+
background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
1570
1999
|
|
|
1571
2000
|
/** Focused */
|
|
1572
2001
|
&:focus,
|
|
1573
2002
|
&:active {
|
|
1574
|
-
border-color:
|
|
1575
|
-
box-shadow: 0 0 0 4px
|
|
2003
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2004
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
1576
2005
|
}
|
|
1577
2006
|
|
|
1578
2007
|
&:focus + span,
|
|
1579
2008
|
&:active + span {
|
|
1580
|
-
color:
|
|
2009
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
1581
2010
|
}
|
|
1582
2011
|
|
|
1583
2012
|
/** Disabled */
|
|
1584
2013
|
&:disabled {
|
|
1585
|
-
border-color:
|
|
1586
|
-
background-color:
|
|
2014
|
+
border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
2015
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};
|
|
1587
2016
|
}
|
|
1588
2017
|
|
|
1589
2018
|
&:disabled + span {
|
|
1590
|
-
color:
|
|
2019
|
+
color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
1591
2020
|
}
|
|
1592
2021
|
|
|
1593
2022
|
/** Invalid */
|
|
1594
2023
|
&:focus:invalid {
|
|
1595
|
-
border-color:
|
|
1596
|
-
box-shadow: 0 0 0 4px
|
|
2024
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
2025
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.ERROR_LIGHT)};
|
|
1597
2026
|
}
|
|
1598
2027
|
|
|
1599
2028
|
${(props) => props.touched
|
|
1600
2029
|
? `
|
|
1601
2030
|
&:invalid {
|
|
1602
|
-
border-color:
|
|
2031
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1603
2032
|
}
|
|
1604
2033
|
|
|
1605
2034
|
&:invalid + span {
|
|
1606
|
-
color:
|
|
2035
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1607
2036
|
}
|
|
1608
2037
|
`
|
|
1609
2038
|
: ''}
|
|
@@ -1611,10 +2040,10 @@ const TextField = styled.textarea `
|
|
|
1611
2040
|
/** Error */
|
|
1612
2041
|
${(props) => props.errorText
|
|
1613
2042
|
? `
|
|
1614
|
-
border-color:
|
|
2043
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1615
2044
|
|
|
1616
2045
|
& + span {
|
|
1617
|
-
color:
|
|
2046
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1618
2047
|
}
|
|
1619
2048
|
`
|
|
1620
2049
|
: ''}
|
|
@@ -1623,7 +2052,7 @@ const TextField = styled.textarea `
|
|
|
1623
2052
|
&:required + span:after {
|
|
1624
2053
|
content: '*';
|
|
1625
2054
|
margin-left: 2px;
|
|
1626
|
-
color:
|
|
2055
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1627
2056
|
}
|
|
1628
2057
|
|
|
1629
2058
|
/** Label Animation */
|
|
@@ -1641,7 +2070,7 @@ const TextField = styled.textarea `
|
|
|
1641
2070
|
? `
|
|
1642
2071
|
& + span {
|
|
1643
2072
|
top: -8px;
|
|
1644
|
-
background:
|
|
2073
|
+
background: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
1645
2074
|
font-size: 12px;
|
|
1646
2075
|
line-height: 14px;
|
|
1647
2076
|
}
|
|
@@ -1650,13 +2079,13 @@ const TextField = styled.textarea `
|
|
|
1650
2079
|
|
|
1651
2080
|
&:focus + span, &:placeholder-shown + span {
|
|
1652
2081
|
top: -8px;
|
|
1653
|
-
background:
|
|
2082
|
+
background: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
1654
2083
|
font-size: 12px;
|
|
1655
2084
|
line-height: 14px;
|
|
1656
2085
|
}
|
|
1657
2086
|
`;
|
|
1658
2087
|
const ErrorContainer$2 = styled.div `
|
|
1659
|
-
color:
|
|
2088
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1660
2089
|
padding-top: 3px;
|
|
1661
2090
|
font-size: 12px;
|
|
1662
2091
|
line-height: 14px;
|
|
@@ -1665,6 +2094,12 @@ const ErrorContainer$2 = styled.div `
|
|
|
1665
2094
|
function TextArea(props) {
|
|
1666
2095
|
const [touched, setTouched] = React.useState(false);
|
|
1667
2096
|
const [value, setValue] = React.useState(props.value || '');
|
|
2097
|
+
const errorId = React.useId();
|
|
2098
|
+
React.useEffect(() => {
|
|
2099
|
+
if (props.value !== undefined) {
|
|
2100
|
+
setValue(props.value);
|
|
2101
|
+
}
|
|
2102
|
+
}, [props.value]);
|
|
1668
2103
|
const handleFocus = (e) => {
|
|
1669
2104
|
setTouched(true);
|
|
1670
2105
|
if (props.onFocus) {
|
|
@@ -1680,7 +2115,7 @@ function TextArea(props) {
|
|
|
1680
2115
|
setValue(e.target.value);
|
|
1681
2116
|
}
|
|
1682
2117
|
};
|
|
1683
|
-
return (jsxRuntime.jsxs(Label$4, { children: [jsxRuntime.jsx(TextField, Object.assign({}, props, { value: value, onChange: onChangeHandler, onFocus: handleFocus, touched: touched })), jsxRuntime.jsx("span", { children: props.label }), props.errorText && jsxRuntime.jsx(ErrorContainer$2, { children: props.errorText })] }));
|
|
2118
|
+
return (jsxRuntime.jsxs(Label$4, { children: [jsxRuntime.jsx(TextField, Object.assign({}, props, { value: value, onChange: onChangeHandler, onFocus: handleFocus, touched: touched, "aria-invalid": !!props.errorText, "aria-required": props.required, "aria-describedby": props.errorText ? errorId : undefined })), jsxRuntime.jsx("span", { children: props.label }), props.errorText && jsxRuntime.jsx(ErrorContainer$2, { id: errorId, children: props.errorText })] }));
|
|
1684
2119
|
}
|
|
1685
2120
|
TextArea.propTypes = {
|
|
1686
2121
|
/** Label for the field */
|
|
@@ -1692,7 +2127,6 @@ TextArea.propTypes = {
|
|
|
1692
2127
|
const Label$3 = styled.label `
|
|
1693
2128
|
display: inline-flex;
|
|
1694
2129
|
flex-direction: column;
|
|
1695
|
-
flex: 1;
|
|
1696
2130
|
position: relative;
|
|
1697
2131
|
margin: 10px 5px;
|
|
1698
2132
|
pointer-events: none;
|
|
@@ -1710,48 +2144,48 @@ const SelectField = styled.select `
|
|
|
1710
2144
|
min-height: 32px;
|
|
1711
2145
|
width: 268px;
|
|
1712
2146
|
border-radius: 3px;
|
|
1713
|
-
border: 1px solid
|
|
2147
|
+
border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};
|
|
1714
2148
|
display: inline-block;
|
|
1715
|
-
background-color:
|
|
2149
|
+
background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
1716
2150
|
pointer-events: auto;
|
|
1717
2151
|
appearance: none;
|
|
1718
2152
|
|
|
1719
2153
|
/** Focused */
|
|
1720
2154
|
&:focus,
|
|
1721
2155
|
&:active {
|
|
1722
|
-
border-color:
|
|
1723
|
-
box-shadow: 0 0 0 4px
|
|
2156
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2157
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
1724
2158
|
}
|
|
1725
2159
|
|
|
1726
2160
|
&:focus ~ span,
|
|
1727
2161
|
&:active ~ span {
|
|
1728
|
-
color:
|
|
2162
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
1729
2163
|
}
|
|
1730
2164
|
|
|
1731
2165
|
/** Disabled */
|
|
1732
2166
|
&:disabled {
|
|
1733
|
-
border-color:
|
|
1734
|
-
background-color:
|
|
2167
|
+
border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
2168
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};
|
|
1735
2169
|
}
|
|
1736
2170
|
|
|
1737
2171
|
&:disabled ~ span {
|
|
1738
|
-
color:
|
|
2172
|
+
color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
1739
2173
|
}
|
|
1740
2174
|
|
|
1741
2175
|
/** Invalid */
|
|
1742
2176
|
&:focus:invalid {
|
|
1743
|
-
border-color:
|
|
1744
|
-
box-shadow: 0 0 0 4px
|
|
2177
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
2178
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.ERROR_LIGHT)};
|
|
1745
2179
|
}
|
|
1746
2180
|
|
|
1747
2181
|
${(props) => props.touched
|
|
1748
2182
|
? `
|
|
1749
2183
|
&:invalid {
|
|
1750
|
-
border-color:
|
|
2184
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1751
2185
|
}
|
|
1752
2186
|
|
|
1753
2187
|
&:invalid ~ span {
|
|
1754
|
-
color:
|
|
2188
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1755
2189
|
}
|
|
1756
2190
|
`
|
|
1757
2191
|
: ''}
|
|
@@ -1759,10 +2193,10 @@ const SelectField = styled.select `
|
|
|
1759
2193
|
/** Error */
|
|
1760
2194
|
${(props) => props.errorText
|
|
1761
2195
|
? `
|
|
1762
|
-
border-color:
|
|
2196
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1763
2197
|
|
|
1764
2198
|
& ~ span {
|
|
1765
|
-
color:
|
|
2199
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1766
2200
|
}
|
|
1767
2201
|
`
|
|
1768
2202
|
: ''}
|
|
@@ -1771,7 +2205,7 @@ const SelectField = styled.select `
|
|
|
1771
2205
|
&:required + span:after {
|
|
1772
2206
|
content: '*';
|
|
1773
2207
|
margin-left: 2px;
|
|
1774
|
-
color:
|
|
2208
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1775
2209
|
}
|
|
1776
2210
|
|
|
1777
2211
|
/** Label Animation */
|
|
@@ -1789,7 +2223,7 @@ const SelectField = styled.select `
|
|
|
1789
2223
|
? `
|
|
1790
2224
|
& + span {
|
|
1791
2225
|
top: -8px;
|
|
1792
|
-
background:
|
|
2226
|
+
background: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
1793
2227
|
font-size: 12px;
|
|
1794
2228
|
line-height: 14px;
|
|
1795
2229
|
}
|
|
@@ -1798,13 +2232,13 @@ const SelectField = styled.select `
|
|
|
1798
2232
|
|
|
1799
2233
|
&:focus + span, &:placeholder-shown + span {
|
|
1800
2234
|
top: -8px;
|
|
1801
|
-
background:
|
|
2235
|
+
background: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
1802
2236
|
font-size: 12px;
|
|
1803
2237
|
line-height: 14px;
|
|
1804
2238
|
}
|
|
1805
2239
|
`;
|
|
1806
2240
|
const ErrorContainer$1 = styled.div `
|
|
1807
|
-
color:
|
|
2241
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
1808
2242
|
padding-top: 3px;
|
|
1809
2243
|
font-size: 12px;
|
|
1810
2244
|
line-height: 14px;
|
|
@@ -1818,6 +2252,12 @@ const ArrowContainer$1 = styled.span `
|
|
|
1818
2252
|
function Select(props) {
|
|
1819
2253
|
const [touched, setTouched] = React.useState(false);
|
|
1820
2254
|
const [value, setValue] = React.useState(props.value || '');
|
|
2255
|
+
const errorId = React.useId();
|
|
2256
|
+
React.useEffect(() => {
|
|
2257
|
+
if (props.value !== undefined) {
|
|
2258
|
+
setValue(props.value);
|
|
2259
|
+
}
|
|
2260
|
+
}, [props.value]);
|
|
1821
2261
|
const handleFocus = (e) => {
|
|
1822
2262
|
setTouched(true);
|
|
1823
2263
|
if (props.onFocus) {
|
|
@@ -1833,7 +2273,7 @@ function Select(props) {
|
|
|
1833
2273
|
setValue(e.target.value);
|
|
1834
2274
|
}
|
|
1835
2275
|
};
|
|
1836
|
-
return (jsxRuntime.jsxs(Label$3, { children: [jsxRuntime.jsxs(SelectField, Object.assign({}, props, { multiple: false, value: value, onChange: onChangeHandler, onFocus: handleFocus, touched: touched, children: [jsxRuntime.jsx("option", {}), props.children] })), jsxRuntime.jsx("span", { children: props.label }), jsxRuntime.jsx(ArrowContainer$1, { children: jsxRuntime.jsx(ExpandMore, {}) }), props.errorText && jsxRuntime.jsx(ErrorContainer$1, { children: props.errorText })] }));
|
|
2276
|
+
return (jsxRuntime.jsxs(Label$3, { children: [jsxRuntime.jsxs(SelectField, Object.assign({}, props, { multiple: false, value: value, onChange: onChangeHandler, onFocus: handleFocus, touched: touched, "aria-invalid": !!props.errorText, "aria-required": props.required, "aria-describedby": props.errorText ? errorId : undefined, children: [jsxRuntime.jsx("option", {}), props.children] })), jsxRuntime.jsx("span", { children: props.label }), jsxRuntime.jsx(ArrowContainer$1, { "aria-hidden": "true", children: jsxRuntime.jsx(ExpandMore, {}) }), props.errorText && jsxRuntime.jsx(ErrorContainer$1, { id: errorId, children: props.errorText })] }));
|
|
1837
2277
|
}
|
|
1838
2278
|
Select.propTypes = {
|
|
1839
2279
|
/** Label for the field */
|
|
@@ -1845,99 +2285,104 @@ Select.propTypes = {
|
|
|
1845
2285
|
const Label$2 = styled.label `
|
|
1846
2286
|
margin: 5px 0;
|
|
1847
2287
|
position: relative;
|
|
2288
|
+
display: inline-flex;
|
|
2289
|
+
align-items: center;
|
|
2290
|
+
cursor: pointer;
|
|
1848
2291
|
`;
|
|
1849
|
-
const
|
|
1850
|
-
|
|
2292
|
+
const StyledCheckmark = styled.span `
|
|
2293
|
+
width: 16px;
|
|
2294
|
+
height: 16px;
|
|
2295
|
+
border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};
|
|
2296
|
+
display: inline-block;
|
|
2297
|
+
border-radius: 3px;
|
|
2298
|
+
margin-right: 5px;
|
|
2299
|
+
background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
2300
|
+
transition: all 0.3s ease;
|
|
1851
2301
|
position: relative;
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
&::before {
|
|
1855
|
-
content: '';
|
|
1856
|
-
width: 16px;
|
|
1857
|
-
height: 16px;
|
|
1858
|
-
border: 1px solid var(--border-color, ${constants.BORDER_COLOR});
|
|
1859
|
-
display: inline-block;
|
|
1860
|
-
border-radius: 3px;
|
|
1861
|
-
vertical-align: bottom;
|
|
1862
|
-
margin: 0 5px;
|
|
1863
|
-
text-align: center;
|
|
1864
|
-
line-height: 16px;
|
|
1865
|
-
background-color: var(--background, ${constants.BACKGROUND});
|
|
1866
|
-
transition: background-color 0.3s ease;
|
|
1867
|
-
}
|
|
2302
|
+
flex-shrink: 0;
|
|
1868
2303
|
|
|
1869
2304
|
&::after {
|
|
1870
2305
|
content: '';
|
|
1871
2306
|
width: 3px;
|
|
1872
2307
|
height: 10px;
|
|
1873
|
-
border-right: 2px solid
|
|
1874
|
-
border-bottom: 2px solid
|
|
1875
|
-
transform: translate(-16px, 1px);
|
|
1876
|
-
opacity: 0;
|
|
1877
|
-
transition: transform 0.3s ease;
|
|
2308
|
+
border-right: 2px solid ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};
|
|
2309
|
+
border-bottom: 2px solid ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};
|
|
1878
2310
|
position: absolute;
|
|
2311
|
+
top: 1px;
|
|
2312
|
+
left: 6px;
|
|
2313
|
+
opacity: 0;
|
|
2314
|
+
transform: rotate(45deg) scale(0);
|
|
2315
|
+
transition: all 0.2s ease;
|
|
1879
2316
|
}
|
|
2317
|
+
`;
|
|
2318
|
+
const HiddenInput$1 = styled.input `
|
|
2319
|
+
opacity: 0;
|
|
2320
|
+
width: 0;
|
|
2321
|
+
height: 0;
|
|
2322
|
+
position: absolute;
|
|
2323
|
+
margin: 0;
|
|
1880
2324
|
|
|
1881
2325
|
/** checked */
|
|
1882
|
-
&:checked
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
border-color: var(--primary, ${constants.PRIMARY});
|
|
1886
|
-
color: #fff;
|
|
2326
|
+
&:checked + ${StyledCheckmark} {
|
|
2327
|
+
background-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2328
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
1887
2329
|
}
|
|
1888
2330
|
|
|
1889
|
-
&:checked::after {
|
|
2331
|
+
&:checked + ${StyledCheckmark}::after {
|
|
1890
2332
|
opacity: 1;
|
|
1891
|
-
transform:
|
|
2333
|
+
transform: rotate(45deg) scale(1);
|
|
1892
2334
|
}
|
|
1893
2335
|
|
|
1894
2336
|
/** indeterminate */
|
|
1895
|
-
&:indeterminate
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
border-color: var(--primary, ${constants});
|
|
1899
|
-
color: #fff;
|
|
2337
|
+
&:indeterminate + ${StyledCheckmark} {
|
|
2338
|
+
background-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2339
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
1900
2340
|
}
|
|
1901
2341
|
|
|
1902
|
-
&:indeterminate::after {
|
|
1903
|
-
width: 0;
|
|
2342
|
+
&:indeterminate + ${StyledCheckmark}::after {
|
|
1904
2343
|
opacity: 1;
|
|
1905
|
-
|
|
2344
|
+
height: 0;
|
|
2345
|
+
width: 8px;
|
|
2346
|
+
border-right: none;
|
|
2347
|
+
border-bottom: 2px solid ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};
|
|
2348
|
+
transform: rotate(0deg) scale(1);
|
|
2349
|
+
top: 7px;
|
|
2350
|
+
left: 4px;
|
|
1906
2351
|
}
|
|
1907
2352
|
|
|
1908
2353
|
/** active and focus */
|
|
1909
|
-
&:enabled:active
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
box-shadow: 0 0 0 3px var(--primary, ${constants.PRIMARY_LIGHT});
|
|
2354
|
+
&:enabled:active + ${StyledCheckmark}, &:focus + ${StyledCheckmark} {
|
|
2355
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2356
|
+
box-shadow: 0 0 0 3px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
1913
2357
|
}
|
|
1914
2358
|
|
|
1915
|
-
&:enabled:active
|
|
1916
|
-
&:focus
|
|
1917
|
-
color:
|
|
2359
|
+
&:enabled:active ~ span,
|
|
2360
|
+
&:focus ~ span {
|
|
2361
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
1918
2362
|
}
|
|
1919
2363
|
|
|
1920
2364
|
/** hover */
|
|
1921
|
-
&:enabled:hover
|
|
1922
|
-
border-color:
|
|
2365
|
+
&:enabled:hover + ${StyledCheckmark} {
|
|
2366
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
1923
2367
|
}
|
|
1924
2368
|
|
|
1925
|
-
&:enabled:hover
|
|
1926
|
-
color:
|
|
2369
|
+
&:enabled:hover ~ span {
|
|
2370
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
1927
2371
|
}
|
|
1928
2372
|
|
|
1929
2373
|
/** disabled */
|
|
1930
|
-
&:disabled
|
|
1931
|
-
border-color:
|
|
2374
|
+
&:disabled + ${StyledCheckmark} {
|
|
2375
|
+
border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
2376
|
+
cursor: not-allowed;
|
|
1932
2377
|
}
|
|
1933
2378
|
|
|
1934
|
-
&:disabled
|
|
1935
|
-
color:
|
|
2379
|
+
&:disabled ~ span {
|
|
2380
|
+
color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
2381
|
+
cursor: not-allowed;
|
|
1936
2382
|
}
|
|
1937
2383
|
|
|
1938
|
-
&:checked:disabled
|
|
1939
|
-
|
|
1940
|
-
background-color: #aaa;
|
|
2384
|
+
&:checked:disabled + ${StyledCheckmark}, &:indeterminate:disabled + ${StyledCheckmark} {
|
|
2385
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
1941
2386
|
}
|
|
1942
2387
|
`;
|
|
1943
2388
|
function Checkbox(props) {
|
|
@@ -1948,7 +2393,7 @@ function Checkbox(props) {
|
|
|
1948
2393
|
}
|
|
1949
2394
|
}
|
|
1950
2395
|
}, [props.indeterminate]);
|
|
1951
|
-
return (jsxRuntime.jsxs(Label$2, { children: [jsxRuntime.jsx(
|
|
2396
|
+
return (jsxRuntime.jsxs(Label$2, { children: [jsxRuntime.jsx(HiddenInput$1, Object.assign({}, props, { ref: ref, type: "checkbox", "aria-checked": props.indeterminate ? 'mixed' : props.checked })), jsxRuntime.jsx(StyledCheckmark, {}), jsxRuntime.jsx("span", { children: props.label })] }));
|
|
1952
2397
|
}
|
|
1953
2398
|
Checkbox.propTypes = {
|
|
1954
2399
|
/** Label for the field */
|
|
@@ -1966,7 +2411,10 @@ const Switch = styled.label `
|
|
|
1966
2411
|
display: inline-flex;
|
|
1967
2412
|
margin: 5px 0;
|
|
1968
2413
|
`;
|
|
1969
|
-
const Input$
|
|
2414
|
+
const Input$1 = styled.input `
|
|
2415
|
+
position: absolute;
|
|
2416
|
+
width: 0;
|
|
2417
|
+
height: 0;
|
|
1970
2418
|
appearance: none;
|
|
1971
2419
|
margin: 0;
|
|
1972
2420
|
|
|
@@ -1975,7 +2423,7 @@ const Input$2 = styled.input `
|
|
|
1975
2423
|
cursor: pointer;
|
|
1976
2424
|
width: 30px;
|
|
1977
2425
|
height: 18px;
|
|
1978
|
-
background-color: ${
|
|
2426
|
+
background-color: ${getThemeValue(THEME_NAME.LIGHT_GREY)};
|
|
1979
2427
|
transition: 0.4s;
|
|
1980
2428
|
border-radius: 10px;
|
|
1981
2429
|
padding: 0 3px;
|
|
@@ -1988,51 +2436,51 @@ const Input$2 = styled.input `
|
|
|
1988
2436
|
width: 14px;
|
|
1989
2437
|
left: 1px;
|
|
1990
2438
|
top: 1px;
|
|
1991
|
-
border: 1px solid
|
|
2439
|
+
border: 1px solid ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
1992
2440
|
border-radius: 50%;
|
|
1993
|
-
background-color:
|
|
2441
|
+
background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
1994
2442
|
transition: 0.4s;
|
|
1995
2443
|
}
|
|
1996
2444
|
|
|
1997
2445
|
/* checked */
|
|
1998
2446
|
&:checked + span {
|
|
1999
|
-
background-color:
|
|
2447
|
+
background-color: ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
2000
2448
|
}
|
|
2001
2449
|
|
|
2002
2450
|
&:checked + span:before {
|
|
2003
2451
|
transform: translateX(18px);
|
|
2004
|
-
border-color:
|
|
2452
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2005
2453
|
}
|
|
2006
2454
|
|
|
2007
2455
|
/* focus */
|
|
2008
2456
|
&:enabled:focus + span:before {
|
|
2009
|
-
box-shadow: 0 0 0 3px
|
|
2010
|
-
border-color:
|
|
2457
|
+
box-shadow: 0 0 0 3px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
2458
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2011
2459
|
}
|
|
2012
2460
|
|
|
2013
2461
|
/* hover */
|
|
2014
2462
|
&:enabled:hover ~ span {
|
|
2015
2463
|
cursor: pointer;
|
|
2016
|
-
color:
|
|
2464
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2017
2465
|
}
|
|
2018
2466
|
|
|
2019
2467
|
/* disabled */
|
|
2020
2468
|
&:disabled ~ span {
|
|
2021
|
-
color:
|
|
2469
|
+
color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
2022
2470
|
}
|
|
2023
2471
|
|
|
2024
2472
|
&:disabled + span {
|
|
2025
|
-
background-color: ${
|
|
2473
|
+
background-color: ${getThemeValue(THEME_NAME.LIGHT_GREY)};
|
|
2026
2474
|
cursor: not-allowed;
|
|
2027
2475
|
}
|
|
2028
2476
|
|
|
2029
2477
|
&:disabled + span:before {
|
|
2030
|
-
background-color:
|
|
2031
|
-
border-color:
|
|
2478
|
+
background-color: ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};
|
|
2479
|
+
border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
2032
2480
|
}
|
|
2033
2481
|
`;
|
|
2034
2482
|
function Toggle(props) {
|
|
2035
|
-
return (jsxRuntime.jsxs(Switch, { children: [jsxRuntime.jsx(Input$
|
|
2483
|
+
return (jsxRuntime.jsxs(Switch, { children: [jsxRuntime.jsx(Input$1, Object.assign({}, props, { type: "checkbox", role: "switch", "aria-checked": props.checked })), jsxRuntime.jsx("span", {}), jsxRuntime.jsx("span", { children: props.label })] }));
|
|
2036
2484
|
}
|
|
2037
2485
|
Toggle.propTypes = {
|
|
2038
2486
|
/** Label for the field */
|
|
@@ -2043,73 +2491,89 @@ const Label$1 = styled.label `
|
|
|
2043
2491
|
display: inline-flex;
|
|
2044
2492
|
align-items: center;
|
|
2045
2493
|
margin: 5px 0;
|
|
2494
|
+
cursor: pointer;
|
|
2495
|
+
position: relative;
|
|
2046
2496
|
`;
|
|
2047
|
-
const
|
|
2048
|
-
|
|
2049
|
-
|
|
2497
|
+
const StyledRadio = styled.span `
|
|
2498
|
+
width: 16px;
|
|
2499
|
+
height: 16px;
|
|
2500
|
+
margin-right: 5px;
|
|
2501
|
+
border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};
|
|
2502
|
+
border-radius: 50%;
|
|
2503
|
+
display: block;
|
|
2504
|
+
transition: background-color 0.3s ease;
|
|
2505
|
+
position: relative;
|
|
2506
|
+
flex-shrink: 0;
|
|
2050
2507
|
|
|
2051
|
-
&::
|
|
2052
|
-
content: '
|
|
2053
|
-
width:
|
|
2054
|
-
height:
|
|
2055
|
-
margin: 0 5px;
|
|
2056
|
-
border: 1px solid var(--border-color, ${constants.BORDER_COLOR});
|
|
2508
|
+
&::after {
|
|
2509
|
+
content: '';
|
|
2510
|
+
width: 100%;
|
|
2511
|
+
height: 100%;
|
|
2057
2512
|
border-radius: 50%;
|
|
2058
|
-
|
|
2059
|
-
|
|
2513
|
+
position: absolute;
|
|
2514
|
+
top: 0;
|
|
2515
|
+
left: 0;
|
|
2516
|
+
box-shadow: inset 0 0 0 3px ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
2517
|
+
opacity: 0;
|
|
2518
|
+
transition: opacity 0.2s ease;
|
|
2060
2519
|
}
|
|
2520
|
+
`;
|
|
2521
|
+
const HiddenInput = styled.input `
|
|
2522
|
+
opacity: 0;
|
|
2523
|
+
width: 0;
|
|
2524
|
+
height: 0;
|
|
2525
|
+
position: absolute;
|
|
2526
|
+
margin: 0;
|
|
2061
2527
|
|
|
2062
2528
|
/* checked */
|
|
2063
|
-
&:checked
|
|
2064
|
-
border:
|
|
2065
|
-
background-color:
|
|
2066
|
-
|
|
2529
|
+
&:checked + ${StyledRadio} {
|
|
2530
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2531
|
+
background-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
&:checked + ${StyledRadio}::after {
|
|
2535
|
+
opacity: 1;
|
|
2067
2536
|
}
|
|
2068
2537
|
|
|
2069
2538
|
/* focus */
|
|
2070
|
-
&:enabled:focus
|
|
2071
|
-
border:
|
|
2072
|
-
box-shadow: 0 0 0 3px
|
|
2073
|
-
cursor: pointer;
|
|
2539
|
+
&:enabled:focus + ${StyledRadio} {
|
|
2540
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2541
|
+
box-shadow: 0 0 0 3px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
2074
2542
|
}
|
|
2075
2543
|
|
|
2076
|
-
&:enabled:checked:focus
|
|
2077
|
-
border:
|
|
2078
|
-
box-shadow:
|
|
2079
|
-
0 0 0 3px var(--primary, ${constants.PRIMARY_LIGHT}),
|
|
2080
|
-
inset 0 0 0 3px var(--background, ${constants.BACKGROUND});
|
|
2081
|
-
cursor: pointer;
|
|
2544
|
+
&:enabled:checked:focus + ${StyledRadio} {
|
|
2545
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2546
|
+
box-shadow: 0 0 0 3px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
2082
2547
|
}
|
|
2083
2548
|
|
|
2084
2549
|
/* hover */
|
|
2085
|
-
&:enabled:hover
|
|
2086
|
-
border:
|
|
2087
|
-
cursor: pointer;
|
|
2550
|
+
&:enabled:hover + ${StyledRadio} {
|
|
2551
|
+
border-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2088
2552
|
}
|
|
2089
2553
|
|
|
2090
|
-
&:enabled:hover
|
|
2091
|
-
color:
|
|
2092
|
-
cursor: pointer;
|
|
2554
|
+
&:enabled:hover ~ span {
|
|
2555
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2093
2556
|
}
|
|
2094
2557
|
|
|
2095
2558
|
/* disabled */
|
|
2096
|
-
&:disabled
|
|
2097
|
-
border:
|
|
2098
|
-
background-color:
|
|
2559
|
+
&:disabled + ${StyledRadio} {
|
|
2560
|
+
border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
2561
|
+
background-color: ${getThemeValue(THEME_NAME.LIGHT_GREY)};
|
|
2562
|
+
cursor: not-allowed;
|
|
2099
2563
|
}
|
|
2100
2564
|
|
|
2101
|
-
&:disabled:checked
|
|
2102
|
-
border:
|
|
2103
|
-
background-color:
|
|
2104
|
-
box-shadow: inset 0 0 0 3px var(--background, ${constants.BACKGROUND});
|
|
2565
|
+
&:disabled:checked + ${StyledRadio} {
|
|
2566
|
+
border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
2567
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
2105
2568
|
}
|
|
2106
2569
|
|
|
2107
|
-
&:disabled
|
|
2108
|
-
color:
|
|
2570
|
+
&:disabled ~ span {
|
|
2571
|
+
color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
2572
|
+
cursor: not-allowed;
|
|
2109
2573
|
}
|
|
2110
2574
|
`;
|
|
2111
2575
|
function Radio(props) {
|
|
2112
|
-
return (jsxRuntime.jsxs(Label$1, { children: [jsxRuntime.jsx(
|
|
2576
|
+
return (jsxRuntime.jsxs(Label$1, { children: [jsxRuntime.jsx(HiddenInput, Object.assign({}, props, { type: "radio" })), jsxRuntime.jsx(StyledRadio, {}), jsxRuntime.jsx("span", { children: props.label })] }));
|
|
2113
2577
|
}
|
|
2114
2578
|
Radio.propTypes = {
|
|
2115
2579
|
/** Label for the field */
|
|
@@ -2122,37 +2586,37 @@ const Input = styled.input `
|
|
|
2122
2586
|
width: 0;
|
|
2123
2587
|
|
|
2124
2588
|
& + span {
|
|
2125
|
-
color:
|
|
2589
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2126
2590
|
padding: 6px 12px;
|
|
2127
2591
|
border: none;
|
|
2128
|
-
border: 1px solid
|
|
2592
|
+
border: 1px solid ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2129
2593
|
cursor: pointer;
|
|
2130
2594
|
margin-right: -1px;
|
|
2131
2595
|
line-height: 18px;
|
|
2132
2596
|
}
|
|
2133
2597
|
|
|
2134
2598
|
&:enabled:focus + span {
|
|
2135
|
-
box-shadow: 0 0 0 4px
|
|
2599
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
2136
2600
|
}
|
|
2137
2601
|
|
|
2138
2602
|
&:enabled:hover + span {
|
|
2139
|
-
background-color:
|
|
2140
|
-
color:
|
|
2603
|
+
background-color: ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
2604
|
+
color: ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};
|
|
2141
2605
|
}
|
|
2142
2606
|
|
|
2143
2607
|
&:enabled:checked + span {
|
|
2144
|
-
background-color:
|
|
2145
|
-
color:
|
|
2608
|
+
background-color: ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
2609
|
+
color: ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};
|
|
2146
2610
|
}
|
|
2147
2611
|
|
|
2148
2612
|
&:disabled + span {
|
|
2149
|
-
background-color:
|
|
2150
|
-
color:
|
|
2613
|
+
background-color: ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};
|
|
2614
|
+
color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
2151
2615
|
}
|
|
2152
2616
|
|
|
2153
2617
|
&:disabled:checked + span {
|
|
2154
|
-
background-color:
|
|
2155
|
-
color:
|
|
2618
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
2619
|
+
color: ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};
|
|
2156
2620
|
}
|
|
2157
2621
|
`;
|
|
2158
2622
|
const Label = styled.label `
|
|
@@ -2194,10 +2658,28 @@ const MenuContainer = styled.div `
|
|
|
2194
2658
|
& div:last-child {
|
|
2195
2659
|
border-bottom: none;
|
|
2196
2660
|
}
|
|
2661
|
+
|
|
2662
|
+
&:focus-within {
|
|
2663
|
+
box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
2664
|
+
}
|
|
2197
2665
|
`;
|
|
2666
|
+
/**
|
|
2667
|
+
* Menu component that allows selection of items from a list.
|
|
2668
|
+
* Supports single and multi-select modes and keyboard navigation.
|
|
2669
|
+
*
|
|
2670
|
+
* @template T - The type of value(s) in the menu.
|
|
2671
|
+
* @param {MenuProps<T> & Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'>} props - The menu properties.
|
|
2672
|
+
* @param {ForwardedRef<HTMLDivElement>} ref - The ref forwarded to the menu container.
|
|
2673
|
+
*/
|
|
2198
2674
|
const Menu = React.forwardRef(function (props, ref) {
|
|
2199
|
-
const { multiSelect, onChange } = props;
|
|
2200
|
-
const [value, setValue] = React.useState(
|
|
2675
|
+
const { multiSelect, onChange, value: propValue } = props, rest = __rest(props, ["multiSelect", "onChange", "value"]);
|
|
2676
|
+
const [value, setValue] = React.useState(propValue || (multiSelect ? [] : ''));
|
|
2677
|
+
/**
|
|
2678
|
+
* Updates the selected value(s).
|
|
2679
|
+
* Handles both single and multi-select logic.
|
|
2680
|
+
*
|
|
2681
|
+
* @param {T} val - The value to select or deselect.
|
|
2682
|
+
*/
|
|
2201
2683
|
const updateValue = (val) => {
|
|
2202
2684
|
let newVal;
|
|
2203
2685
|
if (multiSelect) {
|
|
@@ -2216,11 +2698,74 @@ const Menu = React.forwardRef(function (props, ref) {
|
|
|
2216
2698
|
setValue(newVal);
|
|
2217
2699
|
onChange === null || onChange === void 0 ? void 0 : onChange(newVal);
|
|
2218
2700
|
};
|
|
2701
|
+
/**
|
|
2702
|
+
* Handles keyboard navigation within the menu.
|
|
2703
|
+
* Supports Arrow keys for navigation, and Enter/Space for selection.
|
|
2704
|
+
*
|
|
2705
|
+
* @param {React.KeyboardEvent} e - The keyboard event.
|
|
2706
|
+
*/
|
|
2707
|
+
const handleKeyDown = (e) => {
|
|
2708
|
+
var _a, _b, _c, _d;
|
|
2709
|
+
const target = e.target;
|
|
2710
|
+
const container = e.currentTarget;
|
|
2711
|
+
const items = Array.from(container.querySelectorAll('[role="option"]'));
|
|
2712
|
+
const currentIndex = items.indexOf(target);
|
|
2713
|
+
let nextIndex;
|
|
2714
|
+
switch (e.key) {
|
|
2715
|
+
case 'ArrowDown':
|
|
2716
|
+
e.preventDefault();
|
|
2717
|
+
nextIndex = currentIndex + 1;
|
|
2718
|
+
if (nextIndex >= items.length)
|
|
2719
|
+
nextIndex = 0;
|
|
2720
|
+
(_a = items[nextIndex]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
2721
|
+
break;
|
|
2722
|
+
case 'ArrowUp':
|
|
2723
|
+
e.preventDefault();
|
|
2724
|
+
nextIndex = currentIndex - 1;
|
|
2725
|
+
if (nextIndex < 0)
|
|
2726
|
+
nextIndex = items.length - 1;
|
|
2727
|
+
(_b = items[nextIndex]) === null || _b === void 0 ? void 0 : _b.focus();
|
|
2728
|
+
break;
|
|
2729
|
+
case 'Home':
|
|
2730
|
+
e.preventDefault();
|
|
2731
|
+
(_c = items[0]) === null || _c === void 0 ? void 0 : _c.focus();
|
|
2732
|
+
break;
|
|
2733
|
+
case 'End':
|
|
2734
|
+
e.preventDefault();
|
|
2735
|
+
(_d = items[items.length - 1]) === null || _d === void 0 ? void 0 : _d.focus();
|
|
2736
|
+
break;
|
|
2737
|
+
case 'Enter':
|
|
2738
|
+
case ' ': // Space
|
|
2739
|
+
e.preventDefault();
|
|
2740
|
+
target.click();
|
|
2741
|
+
break;
|
|
2742
|
+
}
|
|
2743
|
+
};
|
|
2744
|
+
/**
|
|
2745
|
+
* Handles focus events on the menu container.
|
|
2746
|
+
* Delegates focus to the first item if the container itself receives focus.
|
|
2747
|
+
*
|
|
2748
|
+
* @param {React.FocusEvent} e - The focus event.
|
|
2749
|
+
*/
|
|
2750
|
+
const focusHandler = (e) => {
|
|
2751
|
+
// Prevent trap: If focus came from inside (Shift+Tab), do NOT auto-focus again.
|
|
2752
|
+
// This allows focus to land on the container, and the next Shift+Tab will exit.
|
|
2753
|
+
if (e.currentTarget.contains(e.relatedTarget)) {
|
|
2754
|
+
return;
|
|
2755
|
+
}
|
|
2756
|
+
// Only if focus is actually on the container (e.g. tabbing into it)
|
|
2757
|
+
// and not bubbling up from a child
|
|
2758
|
+
if (e.target === e.currentTarget) {
|
|
2759
|
+
// Prevent the container from holding focus; delegate to first item
|
|
2760
|
+
const firstItem = e.currentTarget.querySelector('[role="option"]');
|
|
2761
|
+
firstItem === null || firstItem === void 0 ? void 0 : firstItem.focus();
|
|
2762
|
+
}
|
|
2763
|
+
};
|
|
2219
2764
|
return (jsxRuntime.jsx(MenuContext.Provider, { value: {
|
|
2220
2765
|
value,
|
|
2221
2766
|
multiSelect,
|
|
2222
2767
|
updateValue,
|
|
2223
|
-
}, children: jsxRuntime.jsx(MenuContainer, { ref: ref, children: props.children }) }));
|
|
2768
|
+
}, children: jsxRuntime.jsx(MenuContainer, Object.assign({}, rest, { ref: ref, role: "listbox", "aria-multiselectable": multiSelect, tabIndex: 0, onKeyDown: handleKeyDown, onFocus: focusHandler, children: props.children })) }));
|
|
2224
2769
|
});
|
|
2225
2770
|
Menu.displayName = 'Menu';
|
|
2226
2771
|
Menu.defaultProps = {
|
|
@@ -2233,39 +2778,38 @@ const Container$4 = styled.button `
|
|
|
2233
2778
|
border: none;
|
|
2234
2779
|
background-color: transparent;
|
|
2235
2780
|
font-size: 16px;
|
|
2236
|
-
border-bottom: 1px solid
|
|
2781
|
+
border-bottom: 1px solid ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};
|
|
2237
2782
|
min-height: 41px;
|
|
2238
2783
|
display: flex;
|
|
2239
2784
|
align-items: center;
|
|
2240
2785
|
cursor: pointer;
|
|
2241
2786
|
position: relative;
|
|
2787
|
+
color: ${getThemeValue(THEME_NAME.TEXT_COLOR_DARK)};
|
|
2242
2788
|
|
|
2243
2789
|
&:hover,
|
|
2244
2790
|
&:focus,
|
|
2245
2791
|
&:focus-within {
|
|
2246
|
-
background-color:
|
|
2792
|
+
background-color: ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};
|
|
2247
2793
|
}
|
|
2248
2794
|
|
|
2249
2795
|
& > label {
|
|
2250
2796
|
margin: 0 4px 0 0;
|
|
2251
2797
|
}
|
|
2252
2798
|
`;
|
|
2253
|
-
|
|
2799
|
+
const MenuItemInner = (props, ref) => {
|
|
2254
2800
|
var _a, _b;
|
|
2255
2801
|
const context = React.useContext(MenuContext);
|
|
2256
2802
|
const { value, children } = props, rest = __rest(props, ["value", "children"]);
|
|
2257
2803
|
const clickHandler = (e) => {
|
|
2258
2804
|
e.stopPropagation();
|
|
2259
|
-
if (context.multiSelect) {
|
|
2260
|
-
e.nativeEvent.stopImmediatePropagation();
|
|
2261
|
-
}
|
|
2262
2805
|
context.updateValue(value);
|
|
2263
2806
|
};
|
|
2264
2807
|
const selected = context.multiSelect
|
|
2265
2808
|
? (_b = (_a = context.value) === null || _a === void 0 ? void 0 : _a.includes) === null || _b === void 0 ? void 0 : _b.call(_a, value)
|
|
2266
2809
|
: context.value === value;
|
|
2267
|
-
return (jsxRuntime.jsxs(Container$4, Object.assign({}, rest, { type: "button",
|
|
2268
|
-
}
|
|
2810
|
+
return (jsxRuntime.jsxs(Container$4, Object.assign({}, rest, { ref: ref, type: "button", role: "option", "aria-selected": selected, selected: selected, onClick: clickHandler, children: [context.multiSelect && (jsxRuntime.jsx(Checkbox, { checked: selected, readOnly: true, tabIndex: -1, onClick: (e) => e.stopPropagation() })), children] })));
|
|
2811
|
+
};
|
|
2812
|
+
const MenuItem = React.forwardRef(MenuItemInner);
|
|
2269
2813
|
|
|
2270
2814
|
exports.POPOVER_POSITION = void 0;
|
|
2271
2815
|
(function (POPOVER_POSITION) {
|
|
@@ -2349,6 +2893,9 @@ function Popover(props) {
|
|
|
2349
2893
|
const [translate, setTranslate] = React.useState({ x: 0, y: 0 });
|
|
2350
2894
|
const popperRef = React.useRef();
|
|
2351
2895
|
const containerRef = React.useRef();
|
|
2896
|
+
const triggerRef = React.useRef(null);
|
|
2897
|
+
const popperId = React.useId();
|
|
2898
|
+
const triggerId = React.useId();
|
|
2352
2899
|
const close = React.useCallback(() => {
|
|
2353
2900
|
setClosing(true);
|
|
2354
2901
|
setTimeout(() => {
|
|
@@ -2358,6 +2905,12 @@ function Popover(props) {
|
|
|
2358
2905
|
props.onClose();
|
|
2359
2906
|
}
|
|
2360
2907
|
setClosing(false);
|
|
2908
|
+
// Restore focus to the trigger element after animation completes
|
|
2909
|
+
setTimeout(() => {
|
|
2910
|
+
if (triggerRef.current) {
|
|
2911
|
+
triggerRef.current.focus();
|
|
2912
|
+
}
|
|
2913
|
+
}, 50);
|
|
2361
2914
|
}, 280);
|
|
2362
2915
|
}, [props]);
|
|
2363
2916
|
const keyupEventHandler = React.useCallback((e) => {
|
|
@@ -2446,7 +2999,13 @@ function Popover(props) {
|
|
|
2446
2999
|
popperRef.current.focus();
|
|
2447
3000
|
}
|
|
2448
3001
|
}, [open, props.position]);
|
|
2449
|
-
return (jsxRuntime.jsxs(PopoverDiv, { ref: containerRef, children: [
|
|
3002
|
+
return (jsxRuntime.jsxs(PopoverDiv, { ref: containerRef, children: [React.createElement(props.element, {
|
|
3003
|
+
ref: triggerRef,
|
|
3004
|
+
id: triggerId,
|
|
3005
|
+
'aria-expanded': open,
|
|
3006
|
+
'aria-haspopup': 'dialog',
|
|
3007
|
+
'aria-controls': popperId,
|
|
3008
|
+
}), open && (jsxRuntime.jsx(Popper, { elevated: true, tabIndex: 0, role: "dialog", "aria-labelledby": triggerId, id: popperId, position: props.position, translateX: translate.x, translateY: translate.y, className: closing && 'closing', ref: popperRef, onClick: (e) => {
|
|
2450
3009
|
e.stopPropagation();
|
|
2451
3010
|
e.nativeEvent.stopImmediatePropagation();
|
|
2452
3011
|
}, children: props.children }))] }));
|
|
@@ -2479,54 +3038,77 @@ const ArrowContainer = styled.span `
|
|
|
2479
3038
|
top: 16px;
|
|
2480
3039
|
pointer-events: none;
|
|
2481
3040
|
`;
|
|
3041
|
+
/**
|
|
3042
|
+
* Dropdown component that allows selection from a list of options.
|
|
3043
|
+
* Supports single and multi-select modes.
|
|
3044
|
+
*
|
|
3045
|
+
* @template T - The type of the value(s) in the dropdown.
|
|
3046
|
+
* @param {DropdownProps<T>} props - The properties for the Dropdown component.
|
|
3047
|
+
* @returns {JSX.Element} The rendered Dropdown component.
|
|
3048
|
+
*/
|
|
2482
3049
|
function Dropdown(props) {
|
|
2483
3050
|
const { multiSelect, onChange } = props;
|
|
2484
3051
|
const [open, setOpen] = React.useState(false);
|
|
2485
3052
|
const [value, setValue] = React.useState(props.value);
|
|
3053
|
+
const id = React.useId();
|
|
3054
|
+
const menuId = `${id}-menu`;
|
|
3055
|
+
const menuRef = React.useRef(null);
|
|
3056
|
+
const triggerRef = React.useRef(null);
|
|
3057
|
+
// Focus menu when opened
|
|
2486
3058
|
React.useEffect(() => {
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
}
|
|
2496
|
-
else {
|
|
2497
|
-
const currentBtn = current.closest('button');
|
|
2498
|
-
if (e.keyCode === 38) {
|
|
2499
|
-
const prev = (_a = currentBtn === null || currentBtn === void 0 ? void 0 : currentBtn.previousElementSibling) === null || _a === void 0 ? void 0 : _a.closest('button');
|
|
2500
|
-
prev === null || prev === void 0 ? void 0 : prev.focus();
|
|
2501
|
-
}
|
|
2502
|
-
else {
|
|
2503
|
-
const next = (_b = currentBtn === null || currentBtn === void 0 ? void 0 : currentBtn.nextElementSibling) === null || _b === void 0 ? void 0 : _b.closest('button');
|
|
2504
|
-
next === null || next === void 0 ? void 0 : next.focus();
|
|
2505
|
-
}
|
|
3059
|
+
if (open) {
|
|
3060
|
+
// Wait for Popover to fully open and focus itself first
|
|
3061
|
+
// Then move focus to the first menu item
|
|
3062
|
+
const timer = setTimeout(() => {
|
|
3063
|
+
var _a;
|
|
3064
|
+
const firstItem = (_a = menuRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('[role="option"]');
|
|
3065
|
+
if (firstItem) {
|
|
3066
|
+
firstItem.focus();
|
|
2506
3067
|
}
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
}
|
|
2510
|
-
document.addEventListener('keydown', focusHandler);
|
|
2511
|
-
return () => {
|
|
2512
|
-
document.removeEventListener('keydown', focusHandler);
|
|
2513
|
-
};
|
|
3068
|
+
}, 100); // Wait after Popover has set initial focus
|
|
3069
|
+
return () => clearTimeout(timer);
|
|
3070
|
+
}
|
|
2514
3071
|
}, [open]);
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
3072
|
+
/**
|
|
3073
|
+
* Handles keydown events on the input trigger.
|
|
3074
|
+
* Opens the menu on 'Enter', 'Space', 'ArrowDown', or 'ArrowUp'.
|
|
3075
|
+
*
|
|
3076
|
+
* @param {React.KeyboardEvent<HTMLInputElement>} e - The keyboard event.
|
|
3077
|
+
*/
|
|
3078
|
+
const onKeyDown = (e) => {
|
|
3079
|
+
if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(e.key)) {
|
|
3080
|
+
e.preventDefault();
|
|
2518
3081
|
setOpen(true);
|
|
2519
3082
|
}
|
|
2520
3083
|
};
|
|
3084
|
+
/**
|
|
3085
|
+
* Handles changes to the dropdown value.
|
|
3086
|
+
* Updates local state and calls the external onChange handler.
|
|
3087
|
+
* Closes the dropdown if not in multi-select mode.
|
|
3088
|
+
*
|
|
3089
|
+
* @param {T | T[]} val - The new value(s).
|
|
3090
|
+
*/
|
|
2521
3091
|
const changeHandler = (val) => {
|
|
3092
|
+
var _a;
|
|
2522
3093
|
setValue(val);
|
|
2523
3094
|
onChange === null || onChange === void 0 ? void 0 : onChange(val);
|
|
2524
3095
|
// Close dropdown after selection if not multiSelect
|
|
2525
3096
|
if (!multiSelect) {
|
|
2526
3097
|
setOpen(false);
|
|
3098
|
+
(_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
2527
3099
|
}
|
|
2528
3100
|
};
|
|
2529
|
-
|
|
3101
|
+
/**
|
|
3102
|
+
* Toggles the dropdown open state on click.
|
|
3103
|
+
*/
|
|
3104
|
+
const clickHandler = () => setOpen(true);
|
|
3105
|
+
const TriggerElement = React.forwardRef((passedProps, ref) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Input$2, Object.assign({}, passedProps, { ref: ref, type: "text", value: value && String(value), label: props.label, errorText: props.errorText, onClick: clickHandler, onKeyDown: onKeyDown, required: props.required, disabled: props.disabled, readOnly: true, role: "combobox", "aria-haspopup": "listbox", "aria-expanded": open, "aria-controls": menuId })), jsxRuntime.jsx(ArrowContainer, { "aria-hidden": "true", children: jsxRuntime.jsx(ExpandMore, {}) })] })));
|
|
3106
|
+
TriggerElement.displayName = 'DropdownTrigger';
|
|
3107
|
+
return (jsxRuntime.jsx(Popover, { position: exports.POPOVER_POSITION.BOTTOM_LEFT, open: open, element: TriggerElement, onClose: () => {
|
|
3108
|
+
var _a;
|
|
3109
|
+
setOpen(false);
|
|
3110
|
+
(_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
3111
|
+
}, children: jsxRuntime.jsx(Menu, { ref: menuRef, id: menuId, value: value, multiSelect: multiSelect, onChange: changeHandler, children: props.children }) }));
|
|
2530
3112
|
}
|
|
2531
3113
|
Dropdown.defaultProps = {
|
|
2532
3114
|
multiSelect: false,
|
|
@@ -2571,7 +3153,7 @@ class PromptDialog extends React.Component {
|
|
|
2571
3153
|
}
|
|
2572
3154
|
render() {
|
|
2573
3155
|
const { header, body, inputProps, submitText, cancelText, dialogProps } = this.props;
|
|
2574
|
-
return (jsxRuntime.jsx(Dialog, Object.assign({}, dialogProps, { ref: this.dialog, closeOnEsc: false, closeOnOverlayClick: false, children: jsxRuntime.jsxs("form", { onSubmit: this.submit, children: [header && jsxRuntime.jsx(Header$1, { children: header }), jsxRuntime.jsxs(Body$1, { children: [jsxRuntime.jsx(BodyText, { children: body }), jsxRuntime.jsx("div", { style: { display: 'flex' }, children: jsxRuntime.jsx(Input$
|
|
3156
|
+
return (jsxRuntime.jsx(Dialog, Object.assign({}, dialogProps, { ref: this.dialog, closeOnEsc: false, closeOnOverlayClick: false, children: jsxRuntime.jsxs("form", { onSubmit: this.submit, children: [header && jsxRuntime.jsx(Header$1, { children: header }), jsxRuntime.jsxs(Body$1, { children: [jsxRuntime.jsx(BodyText, { children: body }), jsxRuntime.jsx("div", { style: { display: 'flex' }, children: jsxRuntime.jsx(Input$2, Object.assign({ style: { width: 'auto', flex: '1' }, value: this.state.value, onChange: this.valueChange }, inputProps)) })] }), jsxRuntime.jsxs(Footer$1, { children: [jsxRuntime.jsx(StyledButton, { type: "button", onClick: this.cancel, children: cancelText }), jsxRuntime.jsx(ActionButton, { children: submitText })] })] }) })));
|
|
2575
3157
|
}
|
|
2576
3158
|
}
|
|
2577
3159
|
PromptDialog.propTypes = {
|
|
@@ -2626,9 +3208,9 @@ const positionStyle$1 = (size) => ({
|
|
|
2626
3208
|
const DrawerDiv = styled.div `
|
|
2627
3209
|
display: flex;
|
|
2628
3210
|
flex-direction: column;
|
|
2629
|
-
background-color:
|
|
3211
|
+
background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};
|
|
2630
3212
|
transition: transform 0.3s ease;
|
|
2631
|
-
box-shadow:
|
|
3213
|
+
box-shadow: ${getThemeValue(THEME_NAME.MODAL_SHADOW)};
|
|
2632
3214
|
${(props) => positionStyle$1(props.size)[props.position].before}
|
|
2633
3215
|
|
|
2634
3216
|
.nf-layer-enter & {
|
|
@@ -2636,19 +3218,56 @@ const DrawerDiv = styled.div `
|
|
|
2636
3218
|
${(props) => positionStyle$1(props.size)[props.position].after}
|
|
2637
3219
|
}
|
|
2638
3220
|
`;
|
|
3221
|
+
const drawerPropTypes = {
|
|
3222
|
+
/** Opens the drawer */
|
|
3223
|
+
open: PropTypes.bool.isRequired,
|
|
3224
|
+
/** position of the drawer */
|
|
3225
|
+
position: PropTypes.oneOf([
|
|
3226
|
+
exports.DRAWER_POSITION.LEFT,
|
|
3227
|
+
exports.DRAWER_POSITION.RIGHT,
|
|
3228
|
+
exports.DRAWER_POSITION.BOTTOM,
|
|
3229
|
+
]),
|
|
3230
|
+
/** size of the drawer */
|
|
3231
|
+
size: PropTypes.string,
|
|
3232
|
+
/** Shows an overlay behind the drawer. */
|
|
3233
|
+
overlay: PropTypes.bool,
|
|
3234
|
+
/** Closes the drawer on esc */
|
|
3235
|
+
closeOnEsc: PropTypes.bool,
|
|
3236
|
+
/** Closes the drawer on overlay click */
|
|
3237
|
+
closeOnOverlayClick: PropTypes.bool,
|
|
3238
|
+
/** Call back function called when the drawer closes. */
|
|
3239
|
+
onClose: PropTypes.func,
|
|
3240
|
+
};
|
|
2639
3241
|
const positionMap$1 = {
|
|
2640
3242
|
[exports.DRAWER_POSITION.LEFT]: LAYER_POSITION.TOP_LEFT,
|
|
2641
3243
|
[exports.DRAWER_POSITION.RIGHT]: LAYER_POSITION.TOP_RIGHT,
|
|
2642
3244
|
[exports.DRAWER_POSITION.BOTTOM]: LAYER_POSITION.BOTTOM_LEFT,
|
|
2643
3245
|
};
|
|
3246
|
+
/**
|
|
3247
|
+
* Drawer component
|
|
3248
|
+
*
|
|
3249
|
+
* A panel that slides in from the edge of the screen.
|
|
3250
|
+
* It sits on top of the application content and is often used for navigation or details.
|
|
3251
|
+
*
|
|
3252
|
+
* Accessibility:
|
|
3253
|
+
* - Implements ARIA `role="dialog"` and `aria-modal="true"`.
|
|
3254
|
+
* - Traps focus effectively within the drawer while open.
|
|
3255
|
+
* - Restores focus to the triggering element upon closure.
|
|
3256
|
+
* - Supports closing via ESC key and overlay click.
|
|
3257
|
+
*/
|
|
2644
3258
|
class Drawer extends React.Component {
|
|
2645
3259
|
constructor() {
|
|
2646
3260
|
super(...arguments);
|
|
2647
3261
|
this.state = {
|
|
2648
3262
|
open: false,
|
|
2649
3263
|
};
|
|
3264
|
+
/**
|
|
3265
|
+
* Internal close handler.
|
|
3266
|
+
* Restores focus and calls the external onClose callback.
|
|
3267
|
+
*/
|
|
2650
3268
|
this.onClose = () => {
|
|
2651
3269
|
var _a, _b;
|
|
3270
|
+
this.restoreFocus();
|
|
2652
3271
|
this.setState({
|
|
2653
3272
|
open: false,
|
|
2654
3273
|
});
|
|
@@ -2656,7 +3275,97 @@ class Drawer extends React.Component {
|
|
|
2656
3275
|
this.closeCallback = null;
|
|
2657
3276
|
this.layer = null;
|
|
2658
3277
|
};
|
|
3278
|
+
this.lastFocusedElement = null;
|
|
3279
|
+
this.drawerRef = React.createRef();
|
|
3280
|
+
/**
|
|
3281
|
+
* Retrieves all focusable elements within the drawer.
|
|
3282
|
+
*/
|
|
3283
|
+
this.getFocusableElements = () => {
|
|
3284
|
+
if (!this.drawerRef.current)
|
|
3285
|
+
return [];
|
|
3286
|
+
return Array.from(this.drawerRef.current.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'));
|
|
3287
|
+
};
|
|
3288
|
+
/**
|
|
3289
|
+
* Handles keydown events to implement the focus trap.
|
|
3290
|
+
* Traps Tab and Shift+Tab within the drawer.
|
|
3291
|
+
*/
|
|
3292
|
+
this.handleKeyDown = (e) => {
|
|
3293
|
+
if (e.key === 'Tab') {
|
|
3294
|
+
const focusableElements = this.getFocusableElements();
|
|
3295
|
+
if (focusableElements.length === 0)
|
|
3296
|
+
return;
|
|
3297
|
+
const firstElement = focusableElements[0];
|
|
3298
|
+
const lastElement = focusableElements[focusableElements.length - 1];
|
|
3299
|
+
if (e.shiftKey) {
|
|
3300
|
+
if (document.activeElement === firstElement) {
|
|
3301
|
+
lastElement.focus();
|
|
3302
|
+
e.preventDefault();
|
|
3303
|
+
}
|
|
3304
|
+
}
|
|
3305
|
+
else {
|
|
3306
|
+
if (document.activeElement === lastElement) {
|
|
3307
|
+
firstElement.focus();
|
|
3308
|
+
e.preventDefault();
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
}
|
|
3312
|
+
};
|
|
3313
|
+
/**
|
|
3314
|
+
* Restores focus to the element that was focused before the drawer opened.
|
|
3315
|
+
*/
|
|
3316
|
+
this.restoreFocus = () => {
|
|
3317
|
+
if (this.lastFocusedElement) {
|
|
3318
|
+
// Check if the element is still in the document
|
|
3319
|
+
const elementToBeFocused = this.lastFocusedElement;
|
|
3320
|
+
this.lastFocusedElement = null;
|
|
3321
|
+
setTimeout(() => {
|
|
3322
|
+
if (document.body.contains(elementToBeFocused)) {
|
|
3323
|
+
elementToBeFocused.focus();
|
|
3324
|
+
}
|
|
3325
|
+
}, 100);
|
|
3326
|
+
}
|
|
3327
|
+
};
|
|
3328
|
+
/**
|
|
3329
|
+
* Callback ref to capture the Drawer DOM element.
|
|
3330
|
+
* Triggers initial focus setting when the element mounts.
|
|
3331
|
+
*/
|
|
3332
|
+
this.setDrawerRef = (node) => {
|
|
3333
|
+
// Update ref
|
|
3334
|
+
this.drawerRef.current = node;
|
|
3335
|
+
if (node) {
|
|
3336
|
+
// Set initial focus when the node is mounted
|
|
3337
|
+
this.setInitialFocus(node);
|
|
3338
|
+
}
|
|
3339
|
+
};
|
|
3340
|
+
/**
|
|
3341
|
+
* Sets initial focus within the drawer.
|
|
3342
|
+
* Tries to focus the header first, then the first interactive element, or falls back to the container.
|
|
3343
|
+
*/
|
|
3344
|
+
this.setInitialFocus = (root) => {
|
|
3345
|
+
// Try to find the header (assumed to be the first child)
|
|
3346
|
+
const firstChild = root.firstElementChild;
|
|
3347
|
+
if (firstChild) {
|
|
3348
|
+
// Ensure it's focusable
|
|
3349
|
+
if (firstChild.getAttribute('tabindex') === null) {
|
|
3350
|
+
firstChild.setAttribute('tabindex', '-1');
|
|
3351
|
+
}
|
|
3352
|
+
firstChild.focus();
|
|
3353
|
+
return;
|
|
3354
|
+
}
|
|
3355
|
+
// Fallback to focusable elements
|
|
3356
|
+
const focusableElements = this.getFocusableElements();
|
|
3357
|
+
if (focusableElements.length > 0) {
|
|
3358
|
+
focusableElements[0].focus();
|
|
3359
|
+
}
|
|
3360
|
+
else {
|
|
3361
|
+
// Fallback to container
|
|
3362
|
+
root.focus();
|
|
3363
|
+
}
|
|
3364
|
+
};
|
|
2659
3365
|
}
|
|
3366
|
+
/**
|
|
3367
|
+
* Syncs state with props.
|
|
3368
|
+
*/
|
|
2660
3369
|
static getDerivedStateFromProps(props) {
|
|
2661
3370
|
if (props.open) {
|
|
2662
3371
|
return {
|
|
@@ -2665,13 +3374,36 @@ class Drawer extends React.Component {
|
|
|
2665
3374
|
}
|
|
2666
3375
|
return null;
|
|
2667
3376
|
}
|
|
3377
|
+
/**
|
|
3378
|
+
* Lifecycle method to save the currently focused element when the drawer mounts while open.
|
|
3379
|
+
*/
|
|
3380
|
+
componentDidMount() {
|
|
3381
|
+
if (this.props.open) {
|
|
3382
|
+
this.lastFocusedElement = document.activeElement;
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
/**
|
|
3386
|
+
* Lifecycle method to restore focus when the drawer unmounts.
|
|
3387
|
+
*/
|
|
3388
|
+
componentWillUnmount() {
|
|
3389
|
+
if (this.props.open) {
|
|
3390
|
+
this.restoreFocus();
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
/**
|
|
3394
|
+
* Lifecycle method to handle Drawer updates.
|
|
3395
|
+
* Manages opening/closing logic via LayerManager and focus preservation.
|
|
3396
|
+
*/
|
|
2668
3397
|
getSnapshotBeforeUpdate(prevProps) {
|
|
2669
3398
|
var _a;
|
|
2670
3399
|
const _b = this.props, { open, closeOnEsc, closeOnOverlayClick, overlay, position, children, size } = _b, rest = __rest(_b, ["open", "closeOnEsc", "closeOnOverlayClick", "overlay", "position", "children", "size"]);
|
|
2671
3400
|
if (prevProps.open && !open) {
|
|
2672
3401
|
(_a = this.closeCallback) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
3402
|
+
this.restoreFocus();
|
|
2673
3403
|
}
|
|
2674
3404
|
if (!prevProps.open && open) {
|
|
3405
|
+
// Save current focus
|
|
3406
|
+
this.lastFocusedElement = document.activeElement;
|
|
2675
3407
|
this.layer = LayerManager$1.renderLayer({
|
|
2676
3408
|
overlay,
|
|
2677
3409
|
exitDelay: 300,
|
|
@@ -2679,12 +3411,15 @@ class Drawer extends React.Component {
|
|
|
2679
3411
|
closeCallback: this.onClose,
|
|
2680
3412
|
closeOnEsc,
|
|
2681
3413
|
closeOnOverlayClick,
|
|
2682
|
-
component: (jsxRuntime.jsx(DrawerDiv, Object.assign({}, rest, { position: position, size: size, onClick: (e) => e.stopPropagation(), children: children }))),
|
|
3414
|
+
component: (jsxRuntime.jsx(DrawerDiv, Object.assign({}, rest, { ref: this.setDrawerRef, role: "dialog", "aria-modal": "true", tabIndex: -1, onKeyDown: this.handleKeyDown, position: position, size: size, onClick: (e) => e.stopPropagation(), children: children }))),
|
|
2683
3415
|
});
|
|
2684
3416
|
this.closeCallback = this.layer[1];
|
|
2685
3417
|
this.forceUpdate();
|
|
2686
3418
|
}
|
|
2687
3419
|
}
|
|
3420
|
+
/**
|
|
3421
|
+
* Renders the Drawer component via the LayerManager portal.
|
|
3422
|
+
*/
|
|
2688
3423
|
render() {
|
|
2689
3424
|
if (this.state.open && this.layer) {
|
|
2690
3425
|
const [Component] = this.layer;
|
|
@@ -2693,26 +3428,7 @@ class Drawer extends React.Component {
|
|
|
2693
3428
|
return null;
|
|
2694
3429
|
}
|
|
2695
3430
|
}
|
|
2696
|
-
Drawer.propTypes =
|
|
2697
|
-
/** Opens the drawer */
|
|
2698
|
-
open: PropTypes.bool.isRequired,
|
|
2699
|
-
/** position of the drawer */
|
|
2700
|
-
position: PropTypes.oneOf([
|
|
2701
|
-
exports.DRAWER_POSITION.LEFT,
|
|
2702
|
-
exports.DRAWER_POSITION.RIGHT,
|
|
2703
|
-
exports.DRAWER_POSITION.BOTTOM,
|
|
2704
|
-
]),
|
|
2705
|
-
/** size of the drawer */
|
|
2706
|
-
size: PropTypes.string,
|
|
2707
|
-
/** Shows an overlay behind the drawer. */
|
|
2708
|
-
overlay: PropTypes.bool,
|
|
2709
|
-
/** Closes the drawer on esc */
|
|
2710
|
-
closeOnEsc: PropTypes.bool,
|
|
2711
|
-
/** Closes the drawer on overlay click */
|
|
2712
|
-
closeOnOverlayClick: PropTypes.bool,
|
|
2713
|
-
/** Call back function called when the drawer closes. */
|
|
2714
|
-
onClose: PropTypes.func,
|
|
2715
|
-
};
|
|
3431
|
+
Drawer.propTypes = drawerPropTypes;
|
|
2716
3432
|
Drawer.defaultProps = {
|
|
2717
3433
|
overlay: true,
|
|
2718
3434
|
position: exports.DRAWER_POSITION.LEFT,
|
|
@@ -2722,7 +3438,7 @@ Drawer.defaultProps = {
|
|
|
2722
3438
|
|
|
2723
3439
|
const Container$3 = styled.div `
|
|
2724
3440
|
display: inline-flex;
|
|
2725
|
-
border: 1px solid
|
|
3441
|
+
border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};
|
|
2726
3442
|
border-radius: 3px;
|
|
2727
3443
|
margin: 5px;
|
|
2728
3444
|
|
|
@@ -2732,7 +3448,7 @@ const Container$3 = styled.div `
|
|
|
2732
3448
|
margin: 0;
|
|
2733
3449
|
border: none;
|
|
2734
3450
|
border-radius: 0;
|
|
2735
|
-
border-left: 1px solid
|
|
3451
|
+
border-left: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};
|
|
2736
3452
|
box-shadow: none;
|
|
2737
3453
|
height: 32px;
|
|
2738
3454
|
}
|
|
@@ -2787,26 +3503,27 @@ const Container$3 = styled.div `
|
|
|
2787
3503
|
|
|
2788
3504
|
&:focus-within,
|
|
2789
3505
|
&:hover {
|
|
2790
|
-
box-shadow:
|
|
3506
|
+
box-shadow: ${getThemeValue(THEME_NAME.HOVER_SHADOW)};
|
|
2791
3507
|
}
|
|
2792
3508
|
|
|
2793
3509
|
${(props) => props.errorText
|
|
2794
3510
|
? `
|
|
2795
|
-
border-color:
|
|
3511
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
2796
3512
|
|
|
2797
3513
|
& > button, & > label {
|
|
2798
|
-
border-color:
|
|
3514
|
+
border-color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
2799
3515
|
}
|
|
2800
3516
|
`
|
|
2801
3517
|
: ''}
|
|
2802
3518
|
`;
|
|
2803
3519
|
const ErrorContainer = styled.div `
|
|
2804
|
-
color:
|
|
3520
|
+
color: ${getThemeValue(THEME_NAME.ERROR)};
|
|
2805
3521
|
margin-left: 8px;
|
|
2806
3522
|
font-size: 12px;
|
|
2807
3523
|
`;
|
|
2808
3524
|
function Group(props) {
|
|
2809
|
-
|
|
3525
|
+
const errorId = React.useId();
|
|
3526
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Container$3, Object.assign({}, props, { "aria-describedby": props.errorText ? errorId : undefined, children: props.children })), props.errorText && jsxRuntime.jsx(ErrorContainer, { id: errorId, children: props.errorText })] }));
|
|
2810
3527
|
}
|
|
2811
3528
|
Group.propTypes = {
|
|
2812
3529
|
/** Error Message for the group */
|
|
@@ -2815,12 +3532,12 @@ Group.propTypes = {
|
|
|
2815
3532
|
|
|
2816
3533
|
var GroupLabel = styled.label `
|
|
2817
3534
|
height: 32px;
|
|
2818
|
-
background-color: ${
|
|
3535
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};
|
|
2819
3536
|
padding: 0 4px;
|
|
2820
3537
|
line-height: 32px;
|
|
2821
3538
|
min-width: 24px;
|
|
2822
3539
|
text-align: center;
|
|
2823
|
-
color: ${
|
|
3540
|
+
color: ${getThemeValue(THEME_NAME.BORDER_COLOR)};
|
|
2824
3541
|
|
|
2825
3542
|
& > svg {
|
|
2826
3543
|
height: 24px;
|
|
@@ -2830,14 +3547,41 @@ var GroupLabel = styled.label `
|
|
|
2830
3547
|
}
|
|
2831
3548
|
`;
|
|
2832
3549
|
|
|
3550
|
+
const modalPropTypes = {
|
|
3551
|
+
/** Opens the modal */
|
|
3552
|
+
open: PropTypes.bool.isRequired,
|
|
3553
|
+
/** Closes the modal on esc */
|
|
3554
|
+
closeOnEsc: PropTypes.bool,
|
|
3555
|
+
/** Closes the modal on overlay click */
|
|
3556
|
+
closeOnOverlayClick: PropTypes.bool,
|
|
3557
|
+
/** Call back function called when the modal closes. */
|
|
3558
|
+
onClose: PropTypes.func,
|
|
3559
|
+
};
|
|
3560
|
+
/**
|
|
3561
|
+
* Modal component
|
|
3562
|
+
*
|
|
3563
|
+
* A dialog window that sits on top of the main application content.
|
|
3564
|
+
* It disrupts the user's workflow to demand attention for a critical task or decision.
|
|
3565
|
+
*
|
|
3566
|
+
* Accessibility:
|
|
3567
|
+
* - Implements ARIA `role="dialog"` and `aria-modal="true"`.
|
|
3568
|
+
* - Traps focus effectively within the modal while open.
|
|
3569
|
+
* - Restores focus to the triggering element upon closure.
|
|
3570
|
+
* - Supports closing via ESC key and overlay click.
|
|
3571
|
+
*/
|
|
2833
3572
|
class Modal extends React.Component {
|
|
2834
3573
|
constructor() {
|
|
2835
3574
|
super(...arguments);
|
|
2836
3575
|
this.state = {
|
|
2837
3576
|
open: false,
|
|
2838
3577
|
};
|
|
3578
|
+
/**
|
|
3579
|
+
* Internal close handler.
|
|
3580
|
+
* Restores focus and calls the external onClose callback.
|
|
3581
|
+
*/
|
|
2839
3582
|
this.onClose = () => {
|
|
2840
3583
|
var _a, _b;
|
|
3584
|
+
this.restoreFocus();
|
|
2841
3585
|
this.setState({
|
|
2842
3586
|
open: false,
|
|
2843
3587
|
});
|
|
@@ -2845,7 +3589,97 @@ class Modal extends React.Component {
|
|
|
2845
3589
|
this.closeCallback = null;
|
|
2846
3590
|
this.layer = null;
|
|
2847
3591
|
};
|
|
3592
|
+
this.lastFocusedElement = null;
|
|
3593
|
+
this.modalRef = React.createRef();
|
|
3594
|
+
/**
|
|
3595
|
+
* Retrieves all focusable elements within the modal.
|
|
3596
|
+
*/
|
|
3597
|
+
this.getFocusableElements = () => {
|
|
3598
|
+
if (!this.modalRef.current)
|
|
3599
|
+
return [];
|
|
3600
|
+
return Array.from(this.modalRef.current.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'));
|
|
3601
|
+
};
|
|
3602
|
+
/**
|
|
3603
|
+
* Handles keydown events to implement the focus trap.
|
|
3604
|
+
* Traps Tab and Shift+Tab within the modal.
|
|
3605
|
+
*/
|
|
3606
|
+
this.handleKeyDown = (e) => {
|
|
3607
|
+
if (e.key === 'Tab') {
|
|
3608
|
+
const focusableElements = this.getFocusableElements();
|
|
3609
|
+
if (focusableElements.length === 0)
|
|
3610
|
+
return;
|
|
3611
|
+
const firstElement = focusableElements[0];
|
|
3612
|
+
const lastElement = focusableElements[focusableElements.length - 1];
|
|
3613
|
+
if (e.shiftKey) {
|
|
3614
|
+
if (document.activeElement === firstElement) {
|
|
3615
|
+
lastElement.focus();
|
|
3616
|
+
e.preventDefault();
|
|
3617
|
+
}
|
|
3618
|
+
}
|
|
3619
|
+
else {
|
|
3620
|
+
if (document.activeElement === lastElement) {
|
|
3621
|
+
firstElement.focus();
|
|
3622
|
+
e.preventDefault();
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3626
|
+
};
|
|
3627
|
+
/**
|
|
3628
|
+
* Restores focus to the element that was focused before the modal opened.
|
|
3629
|
+
*/
|
|
3630
|
+
this.restoreFocus = () => {
|
|
3631
|
+
if (this.lastFocusedElement) {
|
|
3632
|
+
// Check if the element is still in the document
|
|
3633
|
+
const elementToBeFocused = this.lastFocusedElement;
|
|
3634
|
+
this.lastFocusedElement = null;
|
|
3635
|
+
setTimeout(() => {
|
|
3636
|
+
if (document.body.contains(elementToBeFocused)) {
|
|
3637
|
+
elementToBeFocused.focus();
|
|
3638
|
+
}
|
|
3639
|
+
}, 100);
|
|
3640
|
+
}
|
|
3641
|
+
};
|
|
3642
|
+
/**
|
|
3643
|
+
* Callback ref to capture the Modal DOM element.
|
|
3644
|
+
* Triggers initial focus setting when the element mounts.
|
|
3645
|
+
*/
|
|
3646
|
+
this.setModalRef = (node) => {
|
|
3647
|
+
// Update ref
|
|
3648
|
+
this.modalRef.current = node;
|
|
3649
|
+
if (node) {
|
|
3650
|
+
// Set initial focus when the node is mounted
|
|
3651
|
+
this.setInitialFocus(node);
|
|
3652
|
+
}
|
|
3653
|
+
};
|
|
3654
|
+
/**
|
|
3655
|
+
* Sets initial focus within the modal.
|
|
3656
|
+
* Tries to focus the header (first child) first, then the first interactive element, or falls back to the container.
|
|
3657
|
+
*/
|
|
3658
|
+
this.setInitialFocus = (root) => {
|
|
3659
|
+
// Try to find the header (assumed to be the first child)
|
|
3660
|
+
const firstChild = root.firstElementChild;
|
|
3661
|
+
if (firstChild) {
|
|
3662
|
+
// Ensure it's focusable
|
|
3663
|
+
if (firstChild.getAttribute('tabindex') === null) {
|
|
3664
|
+
firstChild.setAttribute('tabindex', '-1');
|
|
3665
|
+
}
|
|
3666
|
+
firstChild.focus();
|
|
3667
|
+
return;
|
|
3668
|
+
}
|
|
3669
|
+
// Fallback to focusable elements
|
|
3670
|
+
const focusableElements = this.getFocusableElements();
|
|
3671
|
+
if (focusableElements.length > 0) {
|
|
3672
|
+
focusableElements[0].focus();
|
|
3673
|
+
}
|
|
3674
|
+
else {
|
|
3675
|
+
// Fallback to container
|
|
3676
|
+
root.focus();
|
|
3677
|
+
}
|
|
3678
|
+
};
|
|
2848
3679
|
}
|
|
3680
|
+
/**
|
|
3681
|
+
* Syncs state with props.
|
|
3682
|
+
*/
|
|
2849
3683
|
static getDerivedStateFromProps(props) {
|
|
2850
3684
|
if (props.open) {
|
|
2851
3685
|
return {
|
|
@@ -2854,13 +3688,36 @@ class Modal extends React.Component {
|
|
|
2854
3688
|
}
|
|
2855
3689
|
return null;
|
|
2856
3690
|
}
|
|
3691
|
+
/**
|
|
3692
|
+
* Lifecycle method to save the currently focused element when the modal mounts while open.
|
|
3693
|
+
*/
|
|
3694
|
+
componentDidMount() {
|
|
3695
|
+
if (this.props.open) {
|
|
3696
|
+
this.lastFocusedElement = document.activeElement;
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3699
|
+
/**
|
|
3700
|
+
* Lifecycle method to restore focus when the modal unmounts.
|
|
3701
|
+
*/
|
|
3702
|
+
componentWillUnmount() {
|
|
3703
|
+
if (this.props.open) {
|
|
3704
|
+
this.restoreFocus();
|
|
3705
|
+
}
|
|
3706
|
+
}
|
|
3707
|
+
/**
|
|
3708
|
+
* Lifecycle method to handle Modal updates.
|
|
3709
|
+
* Manages opening/closing logic via LayerManager and focus preservation.
|
|
3710
|
+
*/
|
|
2857
3711
|
getSnapshotBeforeUpdate(prevProps) {
|
|
2858
3712
|
var _a;
|
|
2859
3713
|
const _b = this.props, { open, closeOnEsc, closeOnOverlayClick, children } = _b, rest = __rest(_b, ["open", "closeOnEsc", "closeOnOverlayClick", "children"]);
|
|
2860
3714
|
if (prevProps.open && !open) {
|
|
2861
3715
|
(_a = this.closeCallback) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
3716
|
+
this.restoreFocus();
|
|
2862
3717
|
}
|
|
2863
3718
|
if (!prevProps.open && open) {
|
|
3719
|
+
// Save current focus
|
|
3720
|
+
this.lastFocusedElement = document.activeElement;
|
|
2864
3721
|
this.layer = LayerManager$1.renderLayer({
|
|
2865
3722
|
overlay: true,
|
|
2866
3723
|
exitDelay: 300,
|
|
@@ -2868,12 +3725,15 @@ class Modal extends React.Component {
|
|
|
2868
3725
|
closeCallback: this.onClose,
|
|
2869
3726
|
closeOnEsc: closeOnEsc,
|
|
2870
3727
|
closeOnOverlayClick: closeOnOverlayClick,
|
|
2871
|
-
component: (jsxRuntime.jsx(DialogContainer, Object.assign({}, rest, { onClick: (e) => e.stopPropagation(), elevated: true, children: children }))),
|
|
3728
|
+
component: (jsxRuntime.jsx(DialogContainer, Object.assign({}, rest, { ref: this.setModalRef, role: "dialog", "aria-modal": "true", tabIndex: -1, onKeyDown: this.handleKeyDown, onClick: (e) => e.stopPropagation(), elevated: true, children: children }))),
|
|
2872
3729
|
});
|
|
2873
3730
|
this.closeCallback = this.layer[1];
|
|
2874
3731
|
this.forceUpdate();
|
|
2875
3732
|
}
|
|
2876
3733
|
}
|
|
3734
|
+
/**
|
|
3735
|
+
* Renders the Modal component via the LayerManager portal.
|
|
3736
|
+
*/
|
|
2877
3737
|
render() {
|
|
2878
3738
|
if (this.state.open && this.layer) {
|
|
2879
3739
|
const [Component] = this.layer;
|
|
@@ -2882,16 +3742,7 @@ class Modal extends React.Component {
|
|
|
2882
3742
|
return null;
|
|
2883
3743
|
}
|
|
2884
3744
|
}
|
|
2885
|
-
Modal.propTypes =
|
|
2886
|
-
/** Opens the modal */
|
|
2887
|
-
open: PropTypes.bool.isRequired,
|
|
2888
|
-
/** Closes the modal on esc */
|
|
2889
|
-
closeOnEsc: PropTypes.bool,
|
|
2890
|
-
/** Closes the modal on overlay click */
|
|
2891
|
-
closeOnOverlayClick: PropTypes.bool,
|
|
2892
|
-
/** Call back function called when the modal closes. */
|
|
2893
|
-
onClose: PropTypes.func,
|
|
2894
|
-
};
|
|
3745
|
+
Modal.propTypes = modalPropTypes;
|
|
2895
3746
|
Modal.defaultProps = {
|
|
2896
3747
|
closeOnEsc: true,
|
|
2897
3748
|
closeOnOverlayClick: true,
|
|
@@ -2935,37 +3786,37 @@ const getExitAnimation = (position) => {
|
|
|
2935
3786
|
const getBorderColor = (type) => {
|
|
2936
3787
|
switch (type) {
|
|
2937
3788
|
case exports.NOTIFICATION_TYPE.SUCCESS:
|
|
2938
|
-
return
|
|
3789
|
+
return getThemeValue(THEME_NAME.SUCCESS_LIGHT);
|
|
2939
3790
|
case exports.NOTIFICATION_TYPE.DANGER:
|
|
2940
|
-
return
|
|
3791
|
+
return getThemeValue(THEME_NAME.ERROR_LIGHT);
|
|
2941
3792
|
case exports.NOTIFICATION_TYPE.WARNING:
|
|
2942
|
-
return
|
|
3793
|
+
return getThemeValue(THEME_NAME.WARNING_LIGHT);
|
|
2943
3794
|
default:
|
|
2944
|
-
return
|
|
3795
|
+
return getThemeValue(THEME_NAME.INFO_LIGHT);
|
|
2945
3796
|
}
|
|
2946
3797
|
};
|
|
2947
3798
|
const getTitleColor = (type) => {
|
|
2948
3799
|
switch (type) {
|
|
2949
3800
|
case exports.NOTIFICATION_TYPE.SUCCESS:
|
|
2950
|
-
return
|
|
3801
|
+
return getThemeValue(THEME_NAME.SUCCESS);
|
|
2951
3802
|
case exports.NOTIFICATION_TYPE.DANGER:
|
|
2952
|
-
return
|
|
3803
|
+
return getThemeValue(THEME_NAME.ERROR);
|
|
2953
3804
|
case exports.NOTIFICATION_TYPE.WARNING:
|
|
2954
|
-
return
|
|
3805
|
+
return getThemeValue(THEME_NAME.WARNING);
|
|
2955
3806
|
case exports.NOTIFICATION_TYPE.INFO:
|
|
2956
|
-
return
|
|
3807
|
+
return getThemeValue(THEME_NAME.INFO);
|
|
2957
3808
|
}
|
|
2958
3809
|
};
|
|
2959
3810
|
const getTypeStyle = (type) => {
|
|
2960
3811
|
switch (type) {
|
|
2961
3812
|
case exports.NOTIFICATION_TYPE.INFO:
|
|
2962
|
-
return `color:
|
|
3813
|
+
return `color: ${getThemeValue(THEME_NAME.INFO)}`;
|
|
2963
3814
|
case exports.NOTIFICATION_TYPE.SUCCESS:
|
|
2964
|
-
return `color:
|
|
3815
|
+
return `color: ${getThemeValue(THEME_NAME.SUCCESS)}`;
|
|
2965
3816
|
case exports.NOTIFICATION_TYPE.DANGER:
|
|
2966
|
-
return `color:
|
|
3817
|
+
return `color: ${getThemeValue(THEME_NAME.ERROR)}`;
|
|
2967
3818
|
case exports.NOTIFICATION_TYPE.WARNING:
|
|
2968
|
-
return `color:
|
|
3819
|
+
return `color: ${getThemeValue(THEME_NAME.WARNING)}`;
|
|
2969
3820
|
}
|
|
2970
3821
|
};
|
|
2971
3822
|
const Container$2 = styled.div `
|
|
@@ -2976,6 +3827,7 @@ const Container$2 = styled.div `
|
|
|
2976
3827
|
: 'column-reverse'};
|
|
2977
3828
|
`;
|
|
2978
3829
|
const Notice = styled(Card) `
|
|
3830
|
+
position: relative;
|
|
2979
3831
|
border-radius: 3px;
|
|
2980
3832
|
border-left: 4px solid ${(props) => getBorderColor(props.type)};
|
|
2981
3833
|
width: 300px;
|
|
@@ -3062,13 +3914,16 @@ const FillParent = styled.div `
|
|
|
3062
3914
|
flex: 1;
|
|
3063
3915
|
`;
|
|
3064
3916
|
const CloseButton = styled.button `
|
|
3917
|
+
position: absolute;
|
|
3065
3918
|
background-color: transparent;
|
|
3066
3919
|
border: none;
|
|
3067
|
-
padding:
|
|
3920
|
+
padding: 0;
|
|
3921
|
+
top: 4px;
|
|
3922
|
+
right: 4px;
|
|
3068
3923
|
cursor: pointer;
|
|
3069
3924
|
|
|
3070
3925
|
&:focus {
|
|
3071
|
-
box-shadow: 0 0 0 3px
|
|
3926
|
+
box-shadow: 0 0 0 3px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
3072
3927
|
border-radius: 3px;
|
|
3073
3928
|
}
|
|
3074
3929
|
`;
|
|
@@ -3085,6 +3940,17 @@ const Footer = styled.div `
|
|
|
3085
3940
|
justify-content: flex-end;
|
|
3086
3941
|
padding: 0 5px;
|
|
3087
3942
|
`;
|
|
3943
|
+
const VisuallyHidden = styled.span `
|
|
3944
|
+
position: absolute;
|
|
3945
|
+
width: 1px;
|
|
3946
|
+
height: 1px;
|
|
3947
|
+
padding: 0;
|
|
3948
|
+
margin: -1px;
|
|
3949
|
+
overflow: hidden;
|
|
3950
|
+
clip: rect(0, 0, 0, 0);
|
|
3951
|
+
white-space: nowrap;
|
|
3952
|
+
border: 0;
|
|
3953
|
+
`;
|
|
3088
3954
|
|
|
3089
3955
|
const DEFAULT_DURATION$1 = 5000;
|
|
3090
3956
|
/**
|
|
@@ -3100,6 +3966,9 @@ class NotificationManager extends React.Component {
|
|
|
3100
3966
|
this.timeouts = {};
|
|
3101
3967
|
// Set of notification ids
|
|
3102
3968
|
this.set = new Set();
|
|
3969
|
+
// Refs for live regions to ensure they exist before updates
|
|
3970
|
+
this.politeRegionRef = React.createRef();
|
|
3971
|
+
this.assertiveRegionRef = React.createRef();
|
|
3103
3972
|
/**
|
|
3104
3973
|
* Removes a notification from stack if the notification with the given id is found.
|
|
3105
3974
|
*
|
|
@@ -3142,17 +4011,23 @@ class NotificationManager extends React.Component {
|
|
|
3142
4011
|
*
|
|
3143
4012
|
* @param notice
|
|
3144
4013
|
*/
|
|
3145
|
-
this.add = (notice) => {
|
|
4014
|
+
this.add = (notice) => __awaiter(this, void 0, void 0, function* () {
|
|
3146
4015
|
// Generate unique id if not provided.
|
|
3147
4016
|
const id = notice.id || (Math.random() * Math.pow(10, 7)).toFixed(0);
|
|
3148
4017
|
// De-dupe on id
|
|
3149
4018
|
if (!this.set.has(id)) {
|
|
4019
|
+
const type = notice.type || exports.NOTIFICATION_TYPE.INFO;
|
|
4020
|
+
const isUrgent = type === exports.NOTIFICATION_TYPE.WARNING || type === exports.NOTIFICATION_TYPE.DANGER;
|
|
3150
4021
|
// Add notice to the top of stack.
|
|
3151
4022
|
this.setState({
|
|
3152
4023
|
notices: [
|
|
3153
4024
|
Object.assign(Object.assign({}, notice), { id }),
|
|
3154
4025
|
...this.state.notices,
|
|
3155
4026
|
],
|
|
4027
|
+
}, () => {
|
|
4028
|
+
// Update live region after state update
|
|
4029
|
+
const announcement = `${notice.title} ${notice.description}`;
|
|
4030
|
+
this.updateLiveRegion(announcement, isUrgent);
|
|
3156
4031
|
});
|
|
3157
4032
|
// set timeout for closing the notification.
|
|
3158
4033
|
if (!notice.sticky) {
|
|
@@ -3162,6 +4037,23 @@ class NotificationManager extends React.Component {
|
|
|
3162
4037
|
this.set.add(id);
|
|
3163
4038
|
}
|
|
3164
4039
|
return id;
|
|
4040
|
+
});
|
|
4041
|
+
/**
|
|
4042
|
+
* Update live region content with clear-then-set pattern for reliable VoiceOver announcements.
|
|
4043
|
+
*
|
|
4044
|
+
* @param content - The text content to announce
|
|
4045
|
+
* @param isAssertive - Whether to use assertive (alert) or polite (log) live region
|
|
4046
|
+
*/
|
|
4047
|
+
this.updateLiveRegion = (content, isAssertive) => {
|
|
4048
|
+
const region = isAssertive ? this.assertiveRegionRef.current : this.politeRegionRef.current;
|
|
4049
|
+
if (region) {
|
|
4050
|
+
// Add content after delay
|
|
4051
|
+
setTimeout(() => {
|
|
4052
|
+
if (region) {
|
|
4053
|
+
region.textContent = content;
|
|
4054
|
+
}
|
|
4055
|
+
}, 150);
|
|
4056
|
+
}
|
|
3165
4057
|
};
|
|
3166
4058
|
/**
|
|
3167
4059
|
* Handler for close button click.
|
|
@@ -3192,12 +4084,12 @@ class NotificationManager extends React.Component {
|
|
|
3192
4084
|
};
|
|
3193
4085
|
}
|
|
3194
4086
|
render() {
|
|
3195
|
-
return (jsxRuntime.
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
4087
|
+
return (jsxRuntime.jsxs(Container$2, { position: this.props.position, children: [jsxRuntime.jsx(VisuallyHidden, { ref: this.politeRegionRef, role: "log", "aria-live": "polite", "aria-atomic": "false", "aria-relevant": "additions text" }), jsxRuntime.jsx(VisuallyHidden, { ref: this.assertiveRegionRef, role: "alert", "aria-live": "assertive", "aria-atomic": "true" }), jsxRuntime.jsx("div", { role: "list", "aria-label": this.props.ariaLabel, children: this.state.notices.map((notice) => {
|
|
4088
|
+
const { id, title, description, leaving, type = exports.NOTIFICATION_TYPE.INFO, buttonText, buttonClick, closeButtonAriaLabel, } = notice;
|
|
4089
|
+
return (jsxRuntime.jsxs(Notice, Object.assign({}, notice, { position: this.props.position, className: leaving ? 'leave' : '', onMouseEnter: this.pause(id), onMouseLeave: this.resume(id), role: "listitem", children: [jsxRuntime.jsxs(IconContainer, { type: type, "aria-hidden": "true", children: [type === exports.NOTIFICATION_TYPE.INFO && jsxRuntime.jsx(CheckCircle$3, {}), type === exports.NOTIFICATION_TYPE.SUCCESS && jsxRuntime.jsx(CheckCircle$4, {}), type === exports.NOTIFICATION_TYPE.WARNING && jsxRuntime.jsx(CheckCircle$2, {}), type === exports.NOTIFICATION_TYPE.DANGER && jsxRuntime.jsx(CheckCircle$1, {})] }), jsxRuntime.jsxs(FillParent, { children: [jsxRuntime.jsx(Title, { type: type, children: title }), jsxRuntime.jsx(Body, { children: description }), buttonText && (jsxRuntime.jsx(Footer, { children: jsxRuntime.jsx(ActionButton, { onClick: () => {
|
|
4090
|
+
buttonClick === null || buttonClick === void 0 ? void 0 : buttonClick();
|
|
4091
|
+
}, children: buttonText }) }))] }), jsxRuntime.jsx(CloseButton, { onClick: this.closeClickHandler(id), "aria-label": closeButtonAriaLabel || 'Close notification', tabIndex: 0, children: jsxRuntime.jsx(Close, {}) })] }), id));
|
|
4092
|
+
}) })] }));
|
|
3201
4093
|
}
|
|
3202
4094
|
}
|
|
3203
4095
|
|
|
@@ -3231,6 +4123,8 @@ StoryProps.propTypes = {
|
|
|
3231
4123
|
buttonClick: PropTypes.func,
|
|
3232
4124
|
/** Notification close callback. */
|
|
3233
4125
|
onClose: PropTypes.func,
|
|
4126
|
+
/** Aria label for the close button on the notification. Defaults to "Close notification" */
|
|
4127
|
+
closeButtonAriaLabel: PropTypes.string,
|
|
3234
4128
|
};
|
|
3235
4129
|
StoryProps.defaultProps = {
|
|
3236
4130
|
duration: 5000,
|
|
@@ -3252,56 +4146,83 @@ class Notification {
|
|
|
3252
4146
|
/**
|
|
3253
4147
|
* Adds a notification
|
|
3254
4148
|
*
|
|
3255
|
-
* @param position
|
|
3256
|
-
* @param options
|
|
4149
|
+
* @param position - The position where the notification should appear
|
|
4150
|
+
* @param options - Configuration options for the notification
|
|
4151
|
+
* @returns The notification ID or a promise that resolves to the notification ID
|
|
3257
4152
|
*/
|
|
3258
|
-
this.add = (position, options) => {
|
|
3259
|
-
let notification;
|
|
4153
|
+
this.add = (position, options, ariaLabel = 'Notifications') => {
|
|
3260
4154
|
if (!this.containers.has(position)) {
|
|
3261
|
-
|
|
3262
|
-
const
|
|
4155
|
+
/** Callback ref to capture the NotificationManager instance when it mounts */
|
|
4156
|
+
const refCallback = (instance) => {
|
|
4157
|
+
if (instance) {
|
|
4158
|
+
const container = this.containers.get(position);
|
|
4159
|
+
if (container) {
|
|
4160
|
+
container.manager = instance;
|
|
4161
|
+
}
|
|
4162
|
+
}
|
|
4163
|
+
};
|
|
3263
4164
|
const [Component] = LayerManager$1.renderLayer({
|
|
3264
4165
|
closeOnEsc: false,
|
|
3265
4166
|
closeOnOverlayClick: false,
|
|
3266
4167
|
position: positionMap[position],
|
|
3267
4168
|
alwaysOnTop: true,
|
|
3268
|
-
component: (jsxRuntime.jsx(NotificationManager, { ref:
|
|
4169
|
+
component: (jsxRuntime.jsx(NotificationManager, { ref: refCallback, position: position, onEmpty: () => this.destroy(position), ariaLabel: ariaLabel })),
|
|
3269
4170
|
});
|
|
4171
|
+
// Create a div to mount the Component
|
|
4172
|
+
const div = document.createElement('div');
|
|
4173
|
+
document.body.appendChild(div);
|
|
4174
|
+
const root = client.createRoot(div);
|
|
3270
4175
|
this.containers.set(position, {
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
4176
|
+
manager: null,
|
|
4177
|
+
root,
|
|
4178
|
+
div,
|
|
3274
4179
|
});
|
|
4180
|
+
// Render the Component which will trigger the LayerManager's useEffect
|
|
3275
4181
|
ReactDOM.flushSync(() => {
|
|
3276
|
-
|
|
4182
|
+
root.render(jsxRuntime.jsx(Component, {}));
|
|
3277
4183
|
});
|
|
3278
|
-
notification = ref;
|
|
3279
4184
|
}
|
|
3280
|
-
|
|
3281
|
-
|
|
4185
|
+
const container = this.containers.get(position);
|
|
4186
|
+
if (container && container.manager) {
|
|
4187
|
+
return container.manager.add(options);
|
|
3282
4188
|
}
|
|
3283
|
-
|
|
4189
|
+
// If manager is not ready yet, wait a bit and retry
|
|
4190
|
+
return new Promise((resolve) => {
|
|
4191
|
+
setTimeout(() => {
|
|
4192
|
+
const container = this.containers.get(position);
|
|
4193
|
+
if (container && container.manager) {
|
|
4194
|
+
resolve(container.manager.add(options));
|
|
4195
|
+
}
|
|
4196
|
+
}, 10);
|
|
4197
|
+
});
|
|
3284
4198
|
};
|
|
3285
4199
|
/**
|
|
3286
4200
|
* Removes a notification
|
|
3287
4201
|
*
|
|
3288
|
-
* @param position
|
|
3289
|
-
* @param id
|
|
4202
|
+
* @param position - The position of the notification container
|
|
4203
|
+
* @param id - The unique ID of the notification to remove
|
|
3290
4204
|
*/
|
|
3291
4205
|
this.remove = (position, id) => {
|
|
3292
|
-
|
|
3293
|
-
|
|
4206
|
+
const container = this.containers.get(position);
|
|
4207
|
+
if (container && container.manager) {
|
|
4208
|
+
container.manager.remove(id);
|
|
3294
4209
|
}
|
|
3295
4210
|
};
|
|
3296
4211
|
/**
|
|
3297
|
-
* Destroys entire stack of notifications.
|
|
4212
|
+
* Destroys entire stack of notifications at a position.
|
|
4213
|
+
* Unmounts the React root and cleans up DOM elements.
|
|
3298
4214
|
*
|
|
3299
|
-
* @param position
|
|
4215
|
+
* @param position - The position of the notification container to destroy
|
|
3300
4216
|
*/
|
|
3301
4217
|
this.destroy = (position) => {
|
|
3302
|
-
const
|
|
3303
|
-
|
|
3304
|
-
|
|
4218
|
+
const container = this.containers.get(position);
|
|
4219
|
+
if (container) {
|
|
4220
|
+
container.root.unmount();
|
|
4221
|
+
if (document.body.contains(container.div)) {
|
|
4222
|
+
document.body.removeChild(container.div);
|
|
4223
|
+
}
|
|
4224
|
+
this.containers.delete(position);
|
|
4225
|
+
}
|
|
3305
4226
|
};
|
|
3306
4227
|
}
|
|
3307
4228
|
}
|
|
@@ -3309,8 +4230,8 @@ class Notification {
|
|
|
3309
4230
|
var Notification$1 = new Notification();
|
|
3310
4231
|
|
|
3311
4232
|
const SpinnerDiv = styled.div `
|
|
3312
|
-
border: 4px solid
|
|
3313
|
-
border-top: 4px solid
|
|
4233
|
+
border: 4px solid ${getThemeValue(THEME_NAME.PRIMARY)};
|
|
4234
|
+
border-top: 4px solid ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};
|
|
3314
4235
|
border-radius: 50%;
|
|
3315
4236
|
width: ${(props) => props.size}px;
|
|
3316
4237
|
height: ${(props) => props.size}px;
|
|
@@ -3327,14 +4248,18 @@ const SpinnerDiv = styled.div `
|
|
|
3327
4248
|
}
|
|
3328
4249
|
`;
|
|
3329
4250
|
function Spinner(props) {
|
|
3330
|
-
|
|
4251
|
+
const { label } = props, rest = __rest(props, ["label"]);
|
|
4252
|
+
return (jsxRuntime.jsx(SpinnerDiv, Object.assign({}, rest, { role: "status", "aria-label": label, "aria-live": "polite", "aria-busy": "true" })));
|
|
3331
4253
|
}
|
|
3332
4254
|
Spinner.propTypes = {
|
|
3333
4255
|
/** Spinner's size */
|
|
3334
4256
|
size: PropTypes.number,
|
|
4257
|
+
/** Accessible label for screen readers */
|
|
4258
|
+
label: PropTypes.string,
|
|
3335
4259
|
};
|
|
3336
4260
|
Spinner.defaultProps = {
|
|
3337
4261
|
size: 30,
|
|
4262
|
+
label: 'Loading',
|
|
3338
4263
|
};
|
|
3339
4264
|
|
|
3340
4265
|
const Container$1 = styled.div `
|
|
@@ -3347,7 +4272,7 @@ const Header = styled.div `
|
|
|
3347
4272
|
display: flex;
|
|
3348
4273
|
flex-direction: row;
|
|
3349
4274
|
justify-content: space-between;
|
|
3350
|
-
border-bottom: 1px solid
|
|
4275
|
+
border-bottom: 1px solid ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};
|
|
3351
4276
|
|
|
3352
4277
|
@media (min-width: 601px) {
|
|
3353
4278
|
&::before {
|
|
@@ -3356,7 +4281,7 @@ const Header = styled.div `
|
|
|
3356
4281
|
left: 0;
|
|
3357
4282
|
right: 0;
|
|
3358
4283
|
height: 2px;
|
|
3359
|
-
background-color:
|
|
4284
|
+
background-color: ${getThemeValue(THEME_NAME.LIGHT_GREY)};
|
|
3360
4285
|
content: ' ';
|
|
3361
4286
|
z-index: 0;
|
|
3362
4287
|
}
|
|
@@ -3372,21 +4297,22 @@ const HeaderButton = styled.button `
|
|
|
3372
4297
|
font-size: 16px;
|
|
3373
4298
|
cursor: pointer;
|
|
3374
4299
|
background-color: ${(props) => props.active
|
|
3375
|
-
?
|
|
3376
|
-
:
|
|
4300
|
+
? getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)
|
|
4301
|
+
: getThemeValue(THEME_NAME.BACKGROUND)};
|
|
3377
4302
|
font-weight: ${(props) => (props.active ? 'bold' : 'normal')};
|
|
3378
4303
|
overflow: hidden;
|
|
3379
4304
|
display: flex;
|
|
3380
4305
|
align-items: center;
|
|
4306
|
+
color: ${getThemeValue(THEME_NAME.TEXT_COLOR_DARK)};
|
|
3381
4307
|
|
|
3382
4308
|
&:disabled {
|
|
3383
4309
|
cursor: not-allowed;
|
|
3384
|
-
background-color:
|
|
4310
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};
|
|
3385
4311
|
}
|
|
3386
4312
|
|
|
3387
4313
|
&:enabled:hover,
|
|
3388
4314
|
&:focus {
|
|
3389
|
-
background-color:
|
|
4315
|
+
background-color: ${getThemeValue(THEME_NAME.PRIMARY_LIGHTER)};
|
|
3390
4316
|
}
|
|
3391
4317
|
|
|
3392
4318
|
@media (max-width: 600px) {
|
|
@@ -3416,9 +4342,13 @@ function Stepper(props) {
|
|
|
3416
4342
|
const [active, setActive] = React.useState(props.active);
|
|
3417
4343
|
const { children, onStepClick } = props;
|
|
3418
4344
|
const childrenArray = React.Children.toArray(children);
|
|
4345
|
+
const stepRefs = [];
|
|
3419
4346
|
const stepClickHandler = (index) => () => {
|
|
4347
|
+
var _a;
|
|
3420
4348
|
setActive(index);
|
|
3421
4349
|
onStepClick === null || onStepClick === void 0 ? void 0 : onStepClick(index);
|
|
4350
|
+
// Move focus to the active step
|
|
4351
|
+
(_a = stepRefs[index]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
3422
4352
|
};
|
|
3423
4353
|
const getBadgeType = (index, completed, disabled) => {
|
|
3424
4354
|
if (disabled) {
|
|
@@ -3432,10 +4362,24 @@ function Stepper(props) {
|
|
|
3432
4362
|
}
|
|
3433
4363
|
return exports.BADGE_TYPE.DISABLED;
|
|
3434
4364
|
};
|
|
3435
|
-
|
|
4365
|
+
// Keyboard navigation for step buttons
|
|
4366
|
+
const onStepKeyDown = (index) => (e) => {
|
|
4367
|
+
var _a, _b;
|
|
4368
|
+
if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
|
|
4369
|
+
e.preventDefault();
|
|
4370
|
+
const next = (index + 1) % childrenArray.length;
|
|
4371
|
+
(_a = stepRefs[next]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
4372
|
+
}
|
|
4373
|
+
else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
|
|
4374
|
+
e.preventDefault();
|
|
4375
|
+
const prev = (index - 1 + childrenArray.length) % childrenArray.length;
|
|
4376
|
+
(_b = stepRefs[prev]) === null || _b === void 0 ? void 0 : _b.focus();
|
|
4377
|
+
}
|
|
4378
|
+
};
|
|
4379
|
+
return (jsxRuntime.jsxs(Container$1, { children: [jsxRuntime.jsxs(Header, { role: "tablist", "aria-label": "Stepper Steps", children: [React.Children.map(children, (child, index) => {
|
|
3436
4380
|
if (!React.isValidElement(child))
|
|
3437
4381
|
return null;
|
|
3438
|
-
return (jsxRuntime.
|
|
4382
|
+
return (jsxRuntime.jsxs(HeaderButton, { ref: (el) => (stepRefs[index] = el), active: index === active, type: "button", role: "tab", "aria-selected": index === active, "aria-disabled": !!child.props.disabled, tabIndex: index === active ? 0 : -1, disabled: child.props.disabled, onClick: stepClickHandler(index), onKeyDown: onStepKeyDown(index), children: [jsxRuntime.jsx(Badge, { inline: true, type: getBadgeType(index, child.props.completed, child.props.disabled) }), jsxRuntime.jsx(Ellipsis, { children: child.props.name })] }));
|
|
3439
4383
|
}), jsxRuntime.jsxs(MobileHeader, { children: [jsxRuntime.jsx("span", { children: React.isValidElement(childrenArray[active])
|
|
3440
4384
|
? childrenArray[active].props.name
|
|
3441
4385
|
: '' }), jsxRuntime.jsxs(Badge, { inline: true, type: exports.BADGE_TYPE.PRIMARY, children: [active + 1, " of ", React.Children.count(children)] })] })] }), childrenArray[active]] }));
|
|
@@ -3471,26 +4415,28 @@ const Button = styled.button `
|
|
|
3471
4415
|
padding: 8px 12px;
|
|
3472
4416
|
font-size: 14px;
|
|
3473
4417
|
border-radius: 3px 3px 0 0;
|
|
3474
|
-
border-bottom: ${(props) => props.active ? `3px solid
|
|
3475
|
-
color: ${(props) =>
|
|
4418
|
+
border-bottom: ${(props) => props.active ? `3px solid ${getThemeValue(THEME_NAME.PRIMARY)}` : 'none'};
|
|
4419
|
+
color: ${(props) => props.active
|
|
4420
|
+
? getThemeValue(THEME_NAME.PRIMARY)
|
|
4421
|
+
: getThemeValue(THEME_NAME.TEXT_COLOR_DARK)};
|
|
3476
4422
|
cursor: pointer;
|
|
3477
4423
|
|
|
3478
4424
|
&:hover,
|
|
3479
4425
|
&:focus {
|
|
3480
|
-
background-color:
|
|
4426
|
+
background-color: ${getThemeValue(THEME_NAME.PRIMARY_LIGHTER)};
|
|
3481
4427
|
border-bottom: ${(props) => props.active
|
|
3482
|
-
? `3px solid
|
|
3483
|
-
: `3px solid
|
|
4428
|
+
? `3px solid ${getThemeValue(THEME_NAME.PRIMARY)}`
|
|
4429
|
+
: `3px solid ${getThemeValue(THEME_NAME.PRIMARY)}`};
|
|
3484
4430
|
}
|
|
3485
4431
|
|
|
3486
4432
|
&[disabled] {
|
|
3487
|
-
background-color:
|
|
3488
|
-
color:
|
|
3489
|
-
border-bottom: 3px solid
|
|
4433
|
+
background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};
|
|
4434
|
+
color: ${getThemeValue(THEME_NAME.DISABLED)};
|
|
4435
|
+
border-bottom: 3px solid ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
3490
4436
|
}
|
|
3491
4437
|
`;
|
|
3492
4438
|
const ButtonContainer = styled.div `
|
|
3493
|
-
border-bottom: 1px solid
|
|
4439
|
+
border-bottom: 1px solid ${getThemeValue(THEME_NAME.DISABLED_BORDER)};
|
|
3494
4440
|
margin-bottom: 5px;
|
|
3495
4441
|
position: relative;
|
|
3496
4442
|
`;
|
|
@@ -3499,14 +4445,45 @@ const TabBody = styled.div `
|
|
|
3499
4445
|
`;
|
|
3500
4446
|
function Tabs(props) {
|
|
3501
4447
|
const [active, setActive] = React.useState(props.active);
|
|
3502
|
-
const switchTab = (index) => () => setActive(index);
|
|
3503
4448
|
const { children } = props;
|
|
4449
|
+
const tabRefs = [];
|
|
4450
|
+
const childrenArray = React.Children.toArray(children);
|
|
4451
|
+
const switchTab = (index) => () => {
|
|
4452
|
+
var _a, _b;
|
|
4453
|
+
setActive(index);
|
|
4454
|
+
(_a = tabRefs[index]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
4455
|
+
(_b = props.onChange) === null || _b === void 0 ? void 0 : _b.call(props, index);
|
|
4456
|
+
};
|
|
4457
|
+
// Keyboard navigation for tab buttons
|
|
4458
|
+
const onTabKeyDown = (index) => (e) => {
|
|
4459
|
+
var _a, _b;
|
|
4460
|
+
if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
|
|
4461
|
+
e.preventDefault();
|
|
4462
|
+
const next = (index + 1) % childrenArray.length;
|
|
4463
|
+
(_a = tabRefs[next]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
4464
|
+
}
|
|
4465
|
+
else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
|
|
4466
|
+
e.preventDefault();
|
|
4467
|
+
const prev = (index - 1 + childrenArray.length) % childrenArray.length;
|
|
4468
|
+
(_b = tabRefs[prev]) === null || _b === void 0 ? void 0 : _b.focus();
|
|
4469
|
+
}
|
|
4470
|
+
};
|
|
3504
4471
|
React.useEffect(() => {
|
|
3505
4472
|
var _a;
|
|
3506
4473
|
setActive(props.active);
|
|
3507
4474
|
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, props.active);
|
|
3508
4475
|
}, [props]);
|
|
3509
|
-
|
|
4476
|
+
// Generate unique IDs for tabs and panels using sanitized tab name and index
|
|
4477
|
+
const sanitize = (str) => str.replace(/[^a-zA-Z0-9_-]/g, '').toLowerCase();
|
|
4478
|
+
const tabIds = childrenArray.map((child, i) => {
|
|
4479
|
+
const name = React.isValidElement(child) && child.props.name ? child.props.name : `tab${i}`;
|
|
4480
|
+
return `nfui-tab-${sanitize(name)}-${i}`;
|
|
4481
|
+
});
|
|
4482
|
+
const panelIds = childrenArray.map((child, i) => {
|
|
4483
|
+
const name = React.isValidElement(child) && child.props.name ? child.props.name : `tab${i}`;
|
|
4484
|
+
return `nfui-tabpanel-${sanitize(name)}-${i}`;
|
|
4485
|
+
});
|
|
4486
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ButtonContainer, Object.assign({ role: "tablist", "aria-label": "Tabs" }, props.props, { children: childrenArray.map((child, index) => (jsxRuntime.jsx(Button, { ref: (el) => (tabRefs[index] = el), id: tabIds[index], type: "button", role: "tab", "aria-selected": active === index, "aria-controls": panelIds[index], tabIndex: active === index ? 0 : -1, active: active === index, onClick: switchTab(index), onKeyDown: onTabKeyDown(index), disabled: React.isValidElement(child) ? child.props.disabled : false, "aria-disabled": React.isValidElement(child) ? child.props.disabled : false, children: React.isValidElement(child) ? child.props.name : '' }, tabIds[index]))) })), jsxRuntime.jsx(TabBody, Object.assign({ id: panelIds[active], role: "tabpanel", "aria-labelledby": tabIds[active], tabIndex: 0 }, props.bodyProps, { children: childrenArray[active] }))] }));
|
|
3510
4487
|
}
|
|
3511
4488
|
Tabs.propTypes = {
|
|
3512
4489
|
/** Active Tab Index */
|
|
@@ -3547,15 +4524,15 @@ exports.TOAST_TYPE = void 0;
|
|
|
3547
4524
|
const getBackgroundColor = (type) => {
|
|
3548
4525
|
switch (type) {
|
|
3549
4526
|
case exports.TOAST_TYPE.INFO:
|
|
3550
|
-
return
|
|
4527
|
+
return getThemeValue(THEME_NAME.INFO);
|
|
3551
4528
|
case exports.TOAST_TYPE.SUCCESS:
|
|
3552
|
-
return
|
|
4529
|
+
return getThemeValue(THEME_NAME.SUCCESS);
|
|
3553
4530
|
case exports.TOAST_TYPE.WARNING:
|
|
3554
|
-
return
|
|
4531
|
+
return getThemeValue(THEME_NAME.WARNING);
|
|
3555
4532
|
case exports.TOAST_TYPE.DANGER:
|
|
3556
|
-
return
|
|
4533
|
+
return getThemeValue(THEME_NAME.ERROR);
|
|
3557
4534
|
case exports.TOAST_TYPE.NORMAL:
|
|
3558
|
-
return
|
|
4535
|
+
return getThemeValue(THEME_NAME.TOAST);
|
|
3559
4536
|
}
|
|
3560
4537
|
};
|
|
3561
4538
|
const ToastContainer = styled(Card) `
|
|
@@ -3563,7 +4540,7 @@ const ToastContainer = styled(Card) `
|
|
|
3563
4540
|
border-radius: 3px;
|
|
3564
4541
|
padding: 12px;
|
|
3565
4542
|
background-color: ${(props) => getBackgroundColor(props.type)};
|
|
3566
|
-
color:
|
|
4543
|
+
color: ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};
|
|
3567
4544
|
margin: 20px;
|
|
3568
4545
|
font-size: 14px;
|
|
3569
4546
|
line-height: 20px;
|
|
@@ -3572,6 +4549,7 @@ const ToastContainer = styled(Card) `
|
|
|
3572
4549
|
width: 344px;
|
|
3573
4550
|
display: flex;
|
|
3574
4551
|
align-items: center;
|
|
4552
|
+
position: relative;
|
|
3575
4553
|
|
|
3576
4554
|
& svg {
|
|
3577
4555
|
width: 20px;
|
|
@@ -3596,7 +4574,7 @@ const TextContainer = styled.div `
|
|
|
3596
4574
|
`;
|
|
3597
4575
|
const CloseContainer = styled.button `
|
|
3598
4576
|
background-color: transparent;
|
|
3599
|
-
color:
|
|
4577
|
+
color: ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};
|
|
3600
4578
|
padding: 6px 10px;
|
|
3601
4579
|
border: none;
|
|
3602
4580
|
border-radius: 3px;
|
|
@@ -3608,8 +4586,71 @@ const CloseContainer = styled.button `
|
|
|
3608
4586
|
}
|
|
3609
4587
|
`;
|
|
3610
4588
|
const DEFAULT_DURATION = 2000;
|
|
4589
|
+
const createAriaLiveRegion = (id, ariaLive) => {
|
|
4590
|
+
const region = document.createElement('div');
|
|
4591
|
+
region.id = id;
|
|
4592
|
+
region.style.position = 'absolute';
|
|
4593
|
+
region.style.width = '1px';
|
|
4594
|
+
region.style.height = '1px';
|
|
4595
|
+
region.style.padding = '0';
|
|
4596
|
+
region.style.margin = '-1px';
|
|
4597
|
+
region.style.overflow = 'hidden';
|
|
4598
|
+
region.style.clip = 'rect(0, 0, 0, 0)';
|
|
4599
|
+
region.style.whiteSpace = 'nowrap';
|
|
4600
|
+
region.style.borderWidth = '0';
|
|
4601
|
+
region.setAttribute('role', ariaLive === 'assertive' ? 'alert' : 'log');
|
|
4602
|
+
region.setAttribute('aria-live', ariaLive);
|
|
4603
|
+
region.setAttribute('aria-atomic', 'true');
|
|
4604
|
+
return region;
|
|
4605
|
+
};
|
|
3611
4606
|
class Toast {
|
|
3612
4607
|
constructor() {
|
|
4608
|
+
this.isPaused = false;
|
|
4609
|
+
this.currentOptions = null;
|
|
4610
|
+
/**
|
|
4611
|
+
* Set up keyboard listener for dismissing toast with Escape key
|
|
4612
|
+
*/
|
|
4613
|
+
this.setupKeyboardListeners = () => {
|
|
4614
|
+
if (typeof document !== 'undefined') {
|
|
4615
|
+
document.addEventListener('keydown', this.handleKeyDown);
|
|
4616
|
+
}
|
|
4617
|
+
};
|
|
4618
|
+
/**
|
|
4619
|
+
* Handle keyboard events for toast interaction
|
|
4620
|
+
*/
|
|
4621
|
+
this.handleKeyDown = (event) => {
|
|
4622
|
+
if (!this.toast)
|
|
4623
|
+
return;
|
|
4624
|
+
// Escape key dismisses the toast
|
|
4625
|
+
if (event.key === 'Escape') {
|
|
4626
|
+
this.remove();
|
|
4627
|
+
}
|
|
4628
|
+
// Space key pauses/resumes auto-dismiss
|
|
4629
|
+
else if (event.key === ' ' && this.currentOptions) {
|
|
4630
|
+
event.preventDefault();
|
|
4631
|
+
if (this.isPaused) {
|
|
4632
|
+
this.resumeTimeout();
|
|
4633
|
+
}
|
|
4634
|
+
else {
|
|
4635
|
+
this.pauseTimeout();
|
|
4636
|
+
}
|
|
4637
|
+
}
|
|
4638
|
+
};
|
|
4639
|
+
/**
|
|
4640
|
+
* Update the appropriate live region with toast content
|
|
4641
|
+
*/
|
|
4642
|
+
this.updateLiveRegion = (content, isAssertive) => {
|
|
4643
|
+
const region = isAssertive ? this.assertiveRegion : this.politeRegion;
|
|
4644
|
+
region.textContent = '';
|
|
4645
|
+
if (region) {
|
|
4646
|
+
// Add content after delay
|
|
4647
|
+
setTimeout(() => {
|
|
4648
|
+
if (region) {
|
|
4649
|
+
region.textContent = content;
|
|
4650
|
+
}
|
|
4651
|
+
}, 200);
|
|
4652
|
+
}
|
|
4653
|
+
};
|
|
3613
4654
|
this.remove = () => {
|
|
3614
4655
|
if (this.toast) {
|
|
3615
4656
|
this.toast[1]();
|
|
@@ -3623,36 +4664,68 @@ class Toast {
|
|
|
3623
4664
|
}
|
|
3624
4665
|
}, 300);
|
|
3625
4666
|
};
|
|
4667
|
+
/**
|
|
4668
|
+
* Pause toast auto-dismiss
|
|
4669
|
+
*/
|
|
4670
|
+
this.pauseTimeout = () => {
|
|
4671
|
+
if (this.timeout) {
|
|
4672
|
+
clearTimeout(this.timeout);
|
|
4673
|
+
this.isPaused = true;
|
|
4674
|
+
}
|
|
4675
|
+
};
|
|
4676
|
+
/**
|
|
4677
|
+
* Resume toast auto-dismiss
|
|
4678
|
+
*/
|
|
4679
|
+
this.resumeTimeout = () => {
|
|
4680
|
+
if (this.currentOptions && this.isPaused) {
|
|
4681
|
+
this.timeout = setTimeout(() => {
|
|
4682
|
+
this.remove();
|
|
4683
|
+
}, this.currentOptions.duration || DEFAULT_DURATION);
|
|
4684
|
+
this.isPaused = false;
|
|
4685
|
+
}
|
|
4686
|
+
};
|
|
3626
4687
|
/**
|
|
3627
4688
|
* Pause toast when user is hovering over it.
|
|
3628
|
-
*
|
|
3629
|
-
* @param id
|
|
3630
4689
|
*/
|
|
3631
4690
|
this.pause = () => {
|
|
3632
|
-
|
|
4691
|
+
this.pauseTimeout();
|
|
3633
4692
|
};
|
|
3634
4693
|
/**
|
|
3635
4694
|
* Restart the removal of toast.
|
|
3636
|
-
*
|
|
3637
|
-
* @param id
|
|
3638
4695
|
*/
|
|
3639
4696
|
this.resume = (options) => () => {
|
|
3640
|
-
this.
|
|
3641
|
-
|
|
3642
|
-
}, options.duration || DEFAULT_DURATION);
|
|
4697
|
+
this.currentOptions = options;
|
|
4698
|
+
this.resumeTimeout();
|
|
3643
4699
|
};
|
|
4700
|
+
if (typeof document === 'undefined')
|
|
4701
|
+
return;
|
|
3644
4702
|
this.element = document === null || document === void 0 ? void 0 : document.createElement('div');
|
|
4703
|
+
this.ariaLiveContainer = document === null || document === void 0 ? void 0 : document.createElement('div');
|
|
4704
|
+
this.ariaLiveContainer.id = 'nf-toast-container';
|
|
4705
|
+
document.body.appendChild(this.ariaLiveContainer);
|
|
4706
|
+
this.politeRegion = createAriaLiveRegion('nf-toast-polite-region', 'polite');
|
|
4707
|
+
this.assertiveRegion = createAriaLiveRegion('nf-toast-assertive-region', 'assertive');
|
|
4708
|
+
this.ariaLiveContainer.appendChild(this.politeRegion);
|
|
4709
|
+
this.ariaLiveContainer.appendChild(this.assertiveRegion);
|
|
4710
|
+
this.setupKeyboardListeners();
|
|
3645
4711
|
}
|
|
3646
4712
|
add(options) {
|
|
3647
4713
|
const { text, buttonText, buttonClick, duration, type = exports.TOAST_TYPE.NORMAL } = options;
|
|
4714
|
+
this.currentOptions = options;
|
|
4715
|
+
this.isPaused = false;
|
|
3648
4716
|
this.remove();
|
|
4717
|
+
// Determine if this is an assertive message (warning/danger)
|
|
4718
|
+
const isAssertive = type === exports.TOAST_TYPE.WARNING || type === exports.TOAST_TYPE.DANGER;
|
|
4719
|
+
// Announce to screen readers
|
|
4720
|
+
const announcement = buttonText ? `${text} ${buttonText} button available` : text;
|
|
4721
|
+
this.updateLiveRegion(announcement, isAssertive);
|
|
3649
4722
|
this.toast = LayerManager$1.renderLayer({
|
|
3650
4723
|
exitDelay: 300,
|
|
3651
4724
|
closeOnEsc: false,
|
|
3652
4725
|
closeOnOverlayClick: false,
|
|
3653
4726
|
alwaysOnTop: true,
|
|
3654
4727
|
position: LAYER_POSITION.BOTTOM_LEFT,
|
|
3655
|
-
component: (jsxRuntime.jsxs(ToastContainer, Object.assign({}, options, { type: type, elevated: true, onMouseEnter: this.pause, onMouseLeave: this.resume(options), children: [jsxRuntime.jsx(TextContainer, { children: text }), buttonText && (jsxRuntime.jsx(CloseContainer, { onClick: buttonClick, type: "button", children: buttonText }))] }))),
|
|
4728
|
+
component: (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(ToastContainer, Object.assign({}, options, { type: type, elevated: true, onMouseEnter: this.pause, onMouseLeave: this.resume(options), "aria-hidden": "true", children: [jsxRuntime.jsx(TextContainer, { children: text }), buttonText && (jsxRuntime.jsx(CloseContainer, { onClick: buttonClick, type: "button", "aria-label": `${buttonText} - Press Space to pause auto-dismiss, Escape to close`, children: buttonText }))] })) })),
|
|
3656
4729
|
});
|
|
3657
4730
|
const Component = this.toast[0];
|
|
3658
4731
|
this.root = client.createRoot(this.element);
|
|
@@ -3705,9 +4778,9 @@ const positionHoverStyle = {
|
|
|
3705
4778
|
};
|
|
3706
4779
|
const TooltipDiv = styled.div `
|
|
3707
4780
|
position: absolute;
|
|
3708
|
-
background-color:
|
|
4781
|
+
background-color: ${getThemeValue(THEME_NAME.TOOLTIP_COLOR)};
|
|
3709
4782
|
padding: 5px;
|
|
3710
|
-
color:
|
|
4783
|
+
color: ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};
|
|
3711
4784
|
border-radius: 3px;
|
|
3712
4785
|
transition: transform 0.3s ease;
|
|
3713
4786
|
font-size: 12px;
|
|
@@ -3720,13 +4793,23 @@ const TooltipContainer = styled.div `
|
|
|
3720
4793
|
justify-content: center;
|
|
3721
4794
|
align-items: center;
|
|
3722
4795
|
|
|
3723
|
-
&:hover ${TooltipDiv} {
|
|
4796
|
+
&:hover ${TooltipDiv}, &:focus-within ${TooltipDiv} {
|
|
3724
4797
|
${(props) => positionHoverStyle[props.position]}
|
|
3725
4798
|
}
|
|
3726
4799
|
`;
|
|
3727
4800
|
function Tooltip(props) {
|
|
3728
4801
|
const { children, position } = props, rest = __rest(props, ["children", "position"]);
|
|
3729
|
-
|
|
4802
|
+
const tooltipId = React.useId();
|
|
4803
|
+
// Clone the child to inject aria-describedby and tabIndex if possible
|
|
4804
|
+
const trigger = React.isValidElement(children)
|
|
4805
|
+
? React.cloneElement(children, {
|
|
4806
|
+
'aria-describedby': tooltipId,
|
|
4807
|
+
tabIndex: children.props && typeof children.props.tabIndex !== 'undefined'
|
|
4808
|
+
? children.props.tabIndex
|
|
4809
|
+
: 0,
|
|
4810
|
+
})
|
|
4811
|
+
: children;
|
|
4812
|
+
return (jsxRuntime.jsxs(TooltipContainer, Object.assign({ position: position }, rest, { children: [trigger, jsxRuntime.jsx(TooltipDiv, { id: tooltipId, "aria-hidden": "true", role: "tooltip", position: position, children: rest.tooltipText })] })));
|
|
3730
4813
|
}
|
|
3731
4814
|
Tooltip.propTypes = {
|
|
3732
4815
|
/** Text to show in the tooltip */
|
|
@@ -3750,7 +4833,7 @@ exports.AccordionStepFooter = AccordionStepFooter;
|
|
|
3750
4833
|
exports.ActionButton = ActionButton;
|
|
3751
4834
|
exports.AlertDialog = AlertDialog;
|
|
3752
4835
|
exports.Badge = Badge;
|
|
3753
|
-
exports.Button =
|
|
4836
|
+
exports.Button = StyledButton;
|
|
3754
4837
|
exports.Card = Card;
|
|
3755
4838
|
exports.CardBody = Body$1;
|
|
3756
4839
|
exports.CardFooter = Footer$1;
|
|
@@ -3772,7 +4855,7 @@ exports.Dropdown = Dropdown;
|
|
|
3772
4855
|
exports.Group = Group;
|
|
3773
4856
|
exports.GroupLabel = GroupLabel;
|
|
3774
4857
|
exports.IconButton = IconButton;
|
|
3775
|
-
exports.Input = Input$
|
|
4858
|
+
exports.Input = Input$2;
|
|
3776
4859
|
exports.LinkButton = LinkButton;
|
|
3777
4860
|
exports.Menu = Menu;
|
|
3778
4861
|
exports.MenuItem = MenuItem;
|