@dnanpm/styleguide 3.9.8 → 3.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/components/Carousel/Carousel.d.ts +188 -0
- package/build/cjs/components/Carousel/Carousel.js +23 -10
- package/build/cjs/components/Divider/Divider.d.ts +4 -0
- package/build/cjs/components/Divider/Divider.js +2 -1
- package/build/cjs/components/InfoDialog/InfoDialog.d.ts +4 -0
- package/build/cjs/components/InfoDialog/InfoDialog.js +1 -1
- package/build/cjs/components/Input/Input.js +1 -2
- package/build/cjs/components/LabelText/LabelText.d.ts +5 -3
- package/build/cjs/components/LabelText/LabelText.js +1 -1
- package/build/cjs/components/ProgressIndicator/ProgressIndicator.d.ts +2 -2
- package/build/cjs/components/ProgressIndicator/ProgressIndicator.js +13 -6
- package/build/cjs/components/ReadMore/ReadMore.d.ts +4 -0
- package/build/cjs/components/ReadMore/ReadMore.js +30 -3
- package/build/es/components/Carousel/Carousel.d.ts +188 -0
- package/build/es/components/Carousel/Carousel.js +23 -11
- package/build/es/components/Divider/Divider.d.ts +4 -0
- package/build/es/components/Divider/Divider.js +2 -1
- package/build/es/components/InfoDialog/InfoDialog.d.ts +4 -0
- package/build/es/components/InfoDialog/InfoDialog.js +1 -1
- package/build/es/components/Input/Input.js +1 -2
- package/build/es/components/LabelText/LabelText.d.ts +5 -3
- package/build/es/components/LabelText/LabelText.js +1 -1
- package/build/es/components/ProgressIndicator/ProgressIndicator.d.ts +2 -2
- package/build/es/components/ProgressIndicator/ProgressIndicator.js +13 -6
- package/build/es/components/ReadMore/ReadMore.d.ts +4 -0
- package/build/es/components/ReadMore/ReadMore.js +31 -4
- package/package.json +5 -5
|
@@ -54,8 +54,196 @@ interface Props {
|
|
|
54
54
|
* If not provided, visibleItems property will be used
|
|
55
55
|
*/
|
|
56
56
|
responsive?: Partial<Responsive>;
|
|
57
|
+
/**
|
|
58
|
+
* Allows to pass a screen reader label for the pagination item next to the current slide number
|
|
59
|
+
*/
|
|
60
|
+
paginationAriaLabel?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Allows to pass a screen reader label for the next arrow button
|
|
63
|
+
*/
|
|
64
|
+
nextAriaLabel?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Allows to pass a screen reader label for the previous arrow button
|
|
67
|
+
*/
|
|
68
|
+
previousAriaLabel?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Number of items to move when navigating the carousel
|
|
71
|
+
*
|
|
72
|
+
* @default 1
|
|
73
|
+
*/
|
|
74
|
+
swipeStep?: number;
|
|
57
75
|
}
|
|
76
|
+
declare const SlideItem: import("styled-components").StyledComponent<"div", {
|
|
77
|
+
base: {
|
|
78
|
+
baseHeight: {
|
|
79
|
+
value: number;
|
|
80
|
+
unit: string;
|
|
81
|
+
};
|
|
82
|
+
baseWidth: {
|
|
83
|
+
value: number;
|
|
84
|
+
unit: string;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
breakpoints: import("../../themes/themeComponents/breakpoints").ViewBreakpoints;
|
|
88
|
+
color: {
|
|
89
|
+
default: {
|
|
90
|
+
pink: string;
|
|
91
|
+
plum: string;
|
|
92
|
+
white: string;
|
|
93
|
+
black: string;
|
|
94
|
+
};
|
|
95
|
+
accent: {
|
|
96
|
+
lemon: string;
|
|
97
|
+
sky: string;
|
|
98
|
+
orange: string;
|
|
99
|
+
};
|
|
100
|
+
active: {
|
|
101
|
+
pink: string;
|
|
102
|
+
};
|
|
103
|
+
hover: {
|
|
104
|
+
pink: string;
|
|
105
|
+
};
|
|
106
|
+
text: {
|
|
107
|
+
gray: string;
|
|
108
|
+
pink: string;
|
|
109
|
+
plum: string;
|
|
110
|
+
white: string;
|
|
111
|
+
black: string;
|
|
112
|
+
};
|
|
113
|
+
line: {
|
|
114
|
+
L01: string;
|
|
115
|
+
L02: string;
|
|
116
|
+
L03: string;
|
|
117
|
+
L04: string;
|
|
118
|
+
};
|
|
119
|
+
notification: {
|
|
120
|
+
info: string;
|
|
121
|
+
success: string;
|
|
122
|
+
warning: string;
|
|
123
|
+
error: string;
|
|
124
|
+
};
|
|
125
|
+
background: {
|
|
126
|
+
sand: {
|
|
127
|
+
default: string;
|
|
128
|
+
E01: string;
|
|
129
|
+
E02: string;
|
|
130
|
+
};
|
|
131
|
+
pink: {
|
|
132
|
+
default: string;
|
|
133
|
+
E01: string;
|
|
134
|
+
E02: string;
|
|
135
|
+
};
|
|
136
|
+
plum: {
|
|
137
|
+
default: string;
|
|
138
|
+
E01: string;
|
|
139
|
+
E02: string;
|
|
140
|
+
};
|
|
141
|
+
lemon: {
|
|
142
|
+
default: string;
|
|
143
|
+
E01: string;
|
|
144
|
+
E02: string;
|
|
145
|
+
};
|
|
146
|
+
sky: {
|
|
147
|
+
default: string;
|
|
148
|
+
E01: string;
|
|
149
|
+
E02: string;
|
|
150
|
+
};
|
|
151
|
+
orange: {
|
|
152
|
+
default: string;
|
|
153
|
+
E01: string;
|
|
154
|
+
E02: string;
|
|
155
|
+
};
|
|
156
|
+
white: {
|
|
157
|
+
default: string;
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
focus: {
|
|
161
|
+
dark: string;
|
|
162
|
+
light: string;
|
|
163
|
+
};
|
|
164
|
+
transparency: {
|
|
165
|
+
T0: string;
|
|
166
|
+
T10: string;
|
|
167
|
+
T20: string;
|
|
168
|
+
T30: string;
|
|
169
|
+
T40: string;
|
|
170
|
+
T50: string;
|
|
171
|
+
T60: string;
|
|
172
|
+
T70: string;
|
|
173
|
+
T80: string;
|
|
174
|
+
T90: string;
|
|
175
|
+
T100: string;
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
fontFamily: {
|
|
179
|
+
default: string;
|
|
180
|
+
heading: string;
|
|
181
|
+
numerals: string;
|
|
182
|
+
};
|
|
183
|
+
fontSize: {
|
|
184
|
+
default: string;
|
|
185
|
+
xl: string;
|
|
186
|
+
l: string;
|
|
187
|
+
s: string;
|
|
188
|
+
xs: string;
|
|
189
|
+
h1XL: string;
|
|
190
|
+
h1L: string;
|
|
191
|
+
h1M: string;
|
|
192
|
+
h1S: string;
|
|
193
|
+
h2M: string;
|
|
194
|
+
h2S: string;
|
|
195
|
+
h3: string;
|
|
196
|
+
h4: string;
|
|
197
|
+
h5: string;
|
|
198
|
+
h1: string;
|
|
199
|
+
h2: string;
|
|
200
|
+
};
|
|
201
|
+
fontWeight: {
|
|
202
|
+
book: number;
|
|
203
|
+
medium: number;
|
|
204
|
+
bold: number;
|
|
205
|
+
black: number;
|
|
206
|
+
};
|
|
207
|
+
form: {
|
|
208
|
+
smallSelectWidth: string;
|
|
209
|
+
smallSelectHeight: string;
|
|
210
|
+
};
|
|
211
|
+
grid: {
|
|
212
|
+
gutter: string;
|
|
213
|
+
};
|
|
214
|
+
lineHeight: {
|
|
215
|
+
default: string;
|
|
216
|
+
xl: string;
|
|
217
|
+
s: string;
|
|
218
|
+
xs: string;
|
|
219
|
+
xxs: string;
|
|
220
|
+
auto: string;
|
|
221
|
+
h1XL: string;
|
|
222
|
+
h1L: string;
|
|
223
|
+
h1M: string;
|
|
224
|
+
h1S: string;
|
|
225
|
+
h2M: string;
|
|
226
|
+
h2S: string;
|
|
227
|
+
h3: string;
|
|
228
|
+
h4: string;
|
|
229
|
+
h5: string;
|
|
230
|
+
h1: string;
|
|
231
|
+
h2: string;
|
|
232
|
+
};
|
|
233
|
+
media: Record<string | number, (l: TemplateStringsArray, ...p: (string | number)[]) => string>;
|
|
234
|
+
radius: {
|
|
235
|
+
default: string;
|
|
236
|
+
s: string;
|
|
237
|
+
xs: string;
|
|
238
|
+
circle: string;
|
|
239
|
+
pill: string;
|
|
240
|
+
};
|
|
241
|
+
}, Required<Pick<Props, "visibleItems">> & {
|
|
242
|
+
itemWidthCorrection: number;
|
|
243
|
+
isSwiping: boolean;
|
|
244
|
+
}, never>;
|
|
58
245
|
/** @visibleName Carousel */
|
|
59
246
|
declare const Carousel: ({ "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
|
|
60
247
|
/** @component */
|
|
61
248
|
export default Carousel;
|
|
249
|
+
export { SlideItem };
|
|
@@ -146,6 +146,7 @@ const Counter = styled.default.span `
|
|
|
146
146
|
`;
|
|
147
147
|
/** @visibleName Carousel */
|
|
148
148
|
const Carousel = (_a) => {
|
|
149
|
+
var _b;
|
|
149
150
|
var { 'data-testid': dataTestId } = _a, props = tslib.__rest(_a, ['data-testid']);
|
|
150
151
|
const slidesWrapperRef = React.useRef(null);
|
|
151
152
|
const scrollbarRef = React.useRef(null);
|
|
@@ -175,9 +176,18 @@ const Carousel = (_a) => {
|
|
|
175
176
|
}, 100);
|
|
176
177
|
return () => clearTimeout(timeoutId);
|
|
177
178
|
}, [width, isMobile, props.responsive, props.visibleItems, props.children]);
|
|
179
|
+
const getStep = (step, visibleItems) => {
|
|
180
|
+
if (step > visibleItems) {
|
|
181
|
+
return Math.floor(visibleItems);
|
|
182
|
+
}
|
|
183
|
+
return Math.floor(step);
|
|
184
|
+
};
|
|
178
185
|
const visibleItems = props.visibleItems || calculatedItems;
|
|
179
186
|
const slidesWrapperGapSizePx = 20;
|
|
180
187
|
const slideScreensCount = React.Children.count(props.children) - Math.floor(visibleItems) + 1;
|
|
188
|
+
const step = getStep((_b = props.swipeStep) !== null && _b !== void 0 ? _b : 1, visibleItems);
|
|
189
|
+
const currentStepIndex = Math.ceil(currentIndex / step);
|
|
190
|
+
const totalSwipeSteps = Math.ceil(slideScreensCount / step + ((slideScreensCount - 1) % step !== 0 ? 1 : 0));
|
|
181
191
|
const itemWidthCorrectionRatio = (slidesWrapperGapSizePx * visibleItems) % Math.floor(visibleItems) === 0
|
|
182
192
|
? (visibleItems - 1) / visibleItems
|
|
183
193
|
: Math.floor(visibleItems) / visibleItems;
|
|
@@ -224,14 +234,15 @@ const Carousel = (_a) => {
|
|
|
224
234
|
}
|
|
225
235
|
};
|
|
226
236
|
const handleNavigationButtonPreviousClick = () => {
|
|
227
|
-
handleSetCurrentIndex(currentIndex -
|
|
237
|
+
handleSetCurrentIndex(currentIndex - step);
|
|
228
238
|
};
|
|
229
239
|
const handleNavigationButtonNextClick = () => {
|
|
230
|
-
handleSetCurrentIndex(currentIndex +
|
|
240
|
+
handleSetCurrentIndex(currentIndex + step);
|
|
231
241
|
};
|
|
232
242
|
const handlePaginationItemClick = (e) => {
|
|
233
243
|
if (e.currentTarget.parentElement) {
|
|
234
|
-
|
|
244
|
+
const index = [...e.currentTarget.parentElement.children].indexOf(e.currentTarget);
|
|
245
|
+
handleSetCurrentIndex(index * step);
|
|
235
246
|
}
|
|
236
247
|
};
|
|
237
248
|
const handlePointerMove = (e) => {
|
|
@@ -272,14 +283,14 @@ const Carousel = (_a) => {
|
|
|
272
283
|
if (endTime - data.startTime > 300) {
|
|
273
284
|
const swipeRatio = Math.abs(data.currentTransform - data.startTransform) / data.itemWidth;
|
|
274
285
|
if (swipeRatio >= 0.5) {
|
|
275
|
-
handleSetCurrentIndex(currentIndex + Math.round(data.direction > 0 ? swipeRatio : -swipeRatio));
|
|
286
|
+
handleSetCurrentIndex(currentIndex + Math.round(data.direction > 0 ? swipeRatio : -swipeRatio) * step);
|
|
276
287
|
}
|
|
277
288
|
else {
|
|
278
289
|
handleSetCurrentIndex(currentIndex);
|
|
279
290
|
}
|
|
280
291
|
}
|
|
281
292
|
else {
|
|
282
|
-
handleSetCurrentIndex(currentIndex + data.direction);
|
|
293
|
+
handleSetCurrentIndex(currentIndex + data.direction * step);
|
|
283
294
|
}
|
|
284
295
|
if (data.scrollbarNavigation && data.direction === 0) {
|
|
285
296
|
if (knobRef.current) {
|
|
@@ -341,19 +352,21 @@ const Carousel = (_a) => {
|
|
|
341
352
|
props.title && React__default.default.createElement(Title, null, props.title),
|
|
342
353
|
React__default.default.createElement(Navigation, null,
|
|
343
354
|
props.hasCounter && (React__default.default.createElement(Counter, null,
|
|
344
|
-
slideScreensCount === 0 ? 0 :
|
|
355
|
+
slideScreensCount === 0 ? 0 : currentStepIndex + 1,
|
|
345
356
|
"/",
|
|
346
|
-
|
|
347
|
-
React__default.default.createElement(ButtonArrow.default, { direction: "left", "aria-label":
|
|
348
|
-
React__default.default.createElement(ButtonArrow.default, { direction: "right", "aria-label":
|
|
357
|
+
totalSwipeSteps)),
|
|
358
|
+
React__default.default.createElement(ButtonArrow.default, { direction: "left", "aria-label": props.previousAriaLabel, onClick: handleNavigationButtonPreviousClick, disabled: currentIndex <= 0, type: "button" }),
|
|
359
|
+
React__default.default.createElement(ButtonArrow.default, { direction: "right", "aria-label": props.nextAriaLabel, onClick: handleNavigationButtonNextClick, disabled: currentIndex + visibleItems >= React.Children.count(props.children), type: "button" }))),
|
|
349
360
|
React__default.default.createElement(Content, { "data-testid": dataTestId && `${dataTestId}-content` },
|
|
350
361
|
React__default.default.createElement(SlidesWrapper, { ref: slidesWrapperRef, onPointerDown: handleSlidesPointerDown, gap: slidesWrapperGapSizePx / 16 }, React.Children.map(props.children, child => (React__default.default.createElement(SlideItem, { visibleItems: visibleItems, itemWidthCorrection: itemWidthCorrection, isSwiping: isSwiping, onPointerDown: handlePointerDown }, child))))),
|
|
351
362
|
React__default.default.createElement(Footer, { "data-testid": dataTestId && `${dataTestId}-footer` },
|
|
352
|
-
React__default.default.createElement(Pagination, null, [...Array(
|
|
363
|
+
React__default.default.createElement(Pagination, null, [...Array(totalSwipeSteps).keys()].map((value, index) => (React__default.default.createElement(PaginationItem, { key: value, "aria-label": props.paginationAriaLabel &&
|
|
364
|
+
`${props.paginationAriaLabel} ${index + 1}`, "aria-current": Math.ceil(currentIndex / step) === index, isActive: Math.ceil(currentIndex / step) === index, onClick: handlePaginationItemClick, type: "button" })))),
|
|
353
365
|
React__default.default.createElement(Scrollbar, { ref: scrollbarRef, onPointerDown: handleScrollbarPointerDown },
|
|
354
366
|
React__default.default.createElement(Knob, { ref: knobRef, knobSize: slideScreensCount })),
|
|
355
367
|
props.footerButton && (React__default.default.createElement(FooterButton, null,
|
|
356
368
|
React__default.default.createElement(ButtonIcon.default, { icon: icons.ArrowRight, onClick: props.onFooterButtonClick }, props.footerButton))))));
|
|
357
369
|
};
|
|
358
370
|
|
|
371
|
+
exports.SlideItem = SlideItem;
|
|
359
372
|
exports.default = Carousel;
|
|
@@ -29,6 +29,10 @@ interface Props {
|
|
|
29
29
|
* Allows to pass a custom className
|
|
30
30
|
*/
|
|
31
31
|
className?: string;
|
|
32
|
+
/**
|
|
33
|
+
* An aria-label to the focusable separator should be included if there is more than one focusable separator
|
|
34
|
+
*/
|
|
35
|
+
ariaLabelFocusableSeparator?: string;
|
|
32
36
|
}
|
|
33
37
|
declare const Divider: ({ "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
|
|
34
38
|
/** @component */
|
|
@@ -26,7 +26,8 @@ const DividerWrapper = styled__default.default.div `
|
|
|
26
26
|
`;
|
|
27
27
|
const Divider = (_a) => {
|
|
28
28
|
var { 'data-testid': dataTestId } = _a, props = tslib.__rest(_a, ['data-testid']);
|
|
29
|
-
|
|
29
|
+
const isFocusableSeparator = Boolean(props.children);
|
|
30
|
+
return (React__default.default.createElement(DividerWrapper, { id: props.id, margin: props.margin, padding: props.padding, className: props.className, "data-testid": dataTestId, as: isFocusableSeparator ? 'div' : 'hr', role: isFocusableSeparator ? 'separator' : undefined, "aria-orientation": "horizontal", "aria-label": props.ariaLabelFocusableSeparator, "aria-hidden": !isFocusableSeparator, tabIndex: isFocusableSeparator ? 0 : -1 }, props.children));
|
|
30
31
|
};
|
|
31
32
|
|
|
32
33
|
exports.default = Divider;
|
|
@@ -37,6 +37,10 @@ interface Props {
|
|
|
37
37
|
* Allows to pass testid string for testing purposes
|
|
38
38
|
*/
|
|
39
39
|
'data-testid'?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Allows to pass a screen reader label to the component
|
|
42
|
+
*/
|
|
43
|
+
ariaLabel?: string;
|
|
40
44
|
}
|
|
41
45
|
/** @visibleName Info Dialog */
|
|
42
46
|
declare const InfoDialog: ({ position, type, "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
|
|
@@ -62,7 +62,7 @@ const InfoDialogContainer = styled.default.div `
|
|
|
62
62
|
/** @visibleName Info Dialog */
|
|
63
63
|
const InfoDialog = (_a) => {
|
|
64
64
|
var { position = 'middle', type = 'default', 'data-testid': dataTestId } = _a, props = tslib.__rest(_a, ["position", "type", 'data-testid']);
|
|
65
|
-
return (React__default.default.createElement(InfoDialogContainer, { id: props.id, "data-testid": dataTestId, className: props.className, position: position, type: type }, props.children));
|
|
65
|
+
return (React__default.default.createElement(InfoDialogContainer, { id: props.id, "data-testid": dataTestId, className: props.className, position: position, type: type, role: "region", "aria-label": props.ariaLabel }, props.children));
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
exports.default = InfoDialog;
|
|
@@ -166,8 +166,7 @@ const Input = (_a) => {
|
|
|
166
166
|
return (React__default.default.createElement(FieldContainer, { className: props.className },
|
|
167
167
|
props.label && (React__default.default.createElement(LabelText.default, { htmlFor: props.id, "data-testid": dataTestId && `${dataTestId}-label`, status: props.status === 'error' ? props.status : undefined, isMandatory: props.required }, props.label)),
|
|
168
168
|
React__default.default.createElement(FieldWrapper, { status: props.status, "$type": type, "$disabled": props.disabled },
|
|
169
|
-
React__default.default.createElement(StyledInput, { id: props.id, name: props.name, type:
|
|
170
|
-
props.readonly && React__default.default.createElement("div", null, props.value),
|
|
169
|
+
React__default.default.createElement(StyledInput, { id: props.id, name: props.name, type: type, value: props.value, placeholder: props.placeholder, onChange: handleChange, onBlur: handleOnBlur, onFocus: props.onFocus, onClick: onClick, onKeyDown: props.onKeyDown, onKeyPress: props.onKeyPress, required: props.required, disabled: props.disabled, autoComplete: props.autocomplete, "aria-disabled": props.disabled, "aria-label": !props.label ? (_b = props.ariaLabel) !== null && _b !== void 0 ? _b : props.id : undefined, ref: inputRef, tabIndex: props.tabIndex, "aria-describedby": getDescribedBy(), "data-testid": dataTestId, readOnly: props.readonly }),
|
|
171
170
|
((props.status && props.status !== 'comment') ||
|
|
172
171
|
props.showPasswordToggle ||
|
|
173
172
|
props.disabled ||
|
|
@@ -18,10 +18,12 @@ interface Props {
|
|
|
18
18
|
* Styling of `label` element changes depending on the passed status
|
|
19
19
|
*
|
|
20
20
|
* @param {LabelTextStatus} undefined Default styling
|
|
21
|
-
* @param {LabelTextStatus} info Changes color to
|
|
22
|
-
* @param {LabelTextStatus} success Changes color to
|
|
23
|
-
* @param {LabelTextStatus} warning Changes color to
|
|
21
|
+
* @param {LabelTextStatus} info Changes color to default color (this type will be deprecated in the future)
|
|
22
|
+
* @param {LabelTextStatus} success Changes color to default color (this type will be deprecated in the future)
|
|
23
|
+
* @param {LabelTextStatus} warning Changes color to default color (this type will be deprecated in the future)
|
|
24
24
|
* @param {LabelTextStatus} error Changes color to `theme.color.notification.error`
|
|
25
|
+
*
|
|
26
|
+
* @deprecated info, success and warning are deprecated, please switch to default or error status
|
|
25
27
|
*/
|
|
26
28
|
status?: LabelTextStatus;
|
|
27
29
|
/**
|
|
@@ -14,7 +14,7 @@ var React__default = /*#__PURE__*/_interopDefaultCompat(React);
|
|
|
14
14
|
|
|
15
15
|
const Label = styled.default.label `
|
|
16
16
|
display: block;
|
|
17
|
-
color: ${({ status }) =>
|
|
17
|
+
color: ${({ status }) => status === 'error' ? theme.default.color.notification.error : theme.default.color.text.gray};
|
|
18
18
|
font-weight: ${theme.default.fontWeight.medium};
|
|
19
19
|
font-size: ${theme.default.fontSize.default};
|
|
20
20
|
line-height: ${theme.default.lineHeight.default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MouseEvent } from 'react';
|
|
1
|
+
import type { MouseEvent, KeyboardEvent } from 'react';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
type ProgressIndicatorStatus = 'error';
|
|
4
4
|
interface Props {
|
|
@@ -15,7 +15,7 @@ interface Props {
|
|
|
15
15
|
* On Progress Indicator Item label or number click callback
|
|
16
16
|
* Use `e.currentTarget.parentElement` to get Progress Indicator Item element
|
|
17
17
|
*/
|
|
18
|
-
onStepClick?: (stepIndex: number, e: MouseEvent<HTMLElement>) => void;
|
|
18
|
+
onStepClick?: (stepIndex: number, e: MouseEvent<HTMLElement> | KeyboardEvent<HTMLElement>) => void;
|
|
19
19
|
/**
|
|
20
20
|
* Allows to change version of component to small
|
|
21
21
|
*/
|
|
@@ -126,14 +126,21 @@ const ProgressIndicator = (_a) => {
|
|
|
126
126
|
props.onStepClick(index, e);
|
|
127
127
|
}
|
|
128
128
|
};
|
|
129
|
-
|
|
129
|
+
const handleKeyDown = (e) => {
|
|
130
|
+
if ((e.key === 'Enter' || e.key === ' ') && props.onStepClick) {
|
|
131
|
+
e.preventDefault();
|
|
132
|
+
props.onStepClick(index, e);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
const isClickable = isCompleted && Boolean(props.onStepClick);
|
|
136
|
+
return (React__default.default.createElement(ProgressIndicatorItem, { key: id, small: props.small },
|
|
130
137
|
index > 0 && (React__default.default.createElement(ProgressIndicatorItemConnector, { small: props.small, isActive: isActive, isCompleted: isCompleted })),
|
|
131
|
-
React__default.default.createElement(ProgressIndicatorItemNumber, { small: props.small, onClick: handleClick, isActive: isActive, isCompleted: isCompleted, isError: isError, isClickable:
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
label && (React__default.default.createElement(ProgressIndicatorItemLabel, { small: props.small, onClick: handleClick, isActive: isActive, className: "visually-hidden" }, label))));
|
|
138
|
+
React__default.default.createElement(ProgressIndicatorItemNumber, { small: props.small, onClick: handleClick, isActive: isActive, isCompleted: isCompleted, isError: isError, onKeyDown: handleKeyDown, tabIndex: isClickable || isActive ? 0 : -1, isClickable: isClickable, role: "tab", "aria-current": isActive ? 'step' : 'false', "aria-label": isCompleted && props.completedStepLabel
|
|
139
|
+
? `${label}, ${props.completedStepLabel}`
|
|
140
|
+
: label }, isCompleted || isError ? (React__default.default.createElement(Icon.default, { icon: isError ? icons.Warning : icons.Check, color: isError ? theme.default.color.text.white : theme.default.color.text.pink, size: "1rem", "aria-hidden": true })) : (stepNumber)),
|
|
141
|
+
label && (React__default.default.createElement(ProgressIndicatorItemLabel, { "aria-hidden": true, small: props.small, onClick: handleClick, isActive: isActive, className: "visually-hidden" }, label))));
|
|
135
142
|
});
|
|
136
|
-
return (React__default.default.createElement(ProgressIndicatorWrapper, { className: props.className, "data-testid": dataTestId, "aria-label": props.ariaLabel, role: "
|
|
143
|
+
return (React__default.default.createElement(ProgressIndicatorWrapper, { className: props.className, "data-testid": dataTestId, "aria-label": props.ariaLabel, role: "tablist" }, progressIndicatorItems));
|
|
137
144
|
};
|
|
138
145
|
|
|
139
146
|
exports.default = ProgressIndicator;
|
|
@@ -68,6 +68,10 @@ interface Props {
|
|
|
68
68
|
* Allows to pass testid string for testing purposes
|
|
69
69
|
*/
|
|
70
70
|
'data-testid'?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Allows to pass an accessible label for the component, enhancing screen reader support.
|
|
73
|
+
*/
|
|
74
|
+
ariaLabel?: string;
|
|
71
75
|
}
|
|
72
76
|
/** @visibleName Read More */
|
|
73
77
|
declare const ReadMore: ({ collapsedSize, "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
|
|
@@ -45,6 +45,9 @@ const StyledButtonIcon = styled.default(ButtonIcon.default) `
|
|
|
45
45
|
const ReadMore = (_a) => {
|
|
46
46
|
var { collapsedSize = '10rem', 'data-testid': dataTestId } = _a, props = tslib.__rest(_a, ["collapsedSize", 'data-testid']);
|
|
47
47
|
const [expanded, setExpanded] = React.useState(props.seoInitExpanded === true || false);
|
|
48
|
+
const contentRef = React.useRef(null);
|
|
49
|
+
const buttonRef = React.useRef(null);
|
|
50
|
+
const userInteractedRef = React.useRef(false);
|
|
48
51
|
// TODO: Remove once https://jira.dna.fi/browse/STYLE-662 is done
|
|
49
52
|
const temporaryIsStatelessFlag = typeof props.isExpanded !== 'undefined';
|
|
50
53
|
const temporaryStateManagement = temporaryIsStatelessFlag ? props.isExpanded : expanded;
|
|
@@ -56,16 +59,40 @@ const ReadMore = (_a) => {
|
|
|
56
59
|
if (!temporaryIsStatelessFlag) {
|
|
57
60
|
setExpanded(!expanded);
|
|
58
61
|
}
|
|
62
|
+
userInteractedRef.current = true;
|
|
59
63
|
};
|
|
60
64
|
React.useEffect(() => {
|
|
61
65
|
if (props.seoInitExpanded) {
|
|
62
66
|
setExpanded(false);
|
|
63
67
|
}
|
|
64
68
|
}, [props.seoInitExpanded]);
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
React.useEffect(() => {
|
|
70
|
+
var _a, _b;
|
|
71
|
+
if (userInteractedRef.current) {
|
|
72
|
+
if (temporaryStateManagement) {
|
|
73
|
+
(_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
(_b = buttonRef.current) === null || _b === void 0 ? void 0 : _b.focus();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}, [temporaryStateManagement]);
|
|
80
|
+
// Function to apply tabIndex to all links elements of children (since we don't control what is passed as children)
|
|
81
|
+
const forceTabIndexOnTextLinks = (child) => {
|
|
82
|
+
if (!React.isValidElement(child)) {
|
|
83
|
+
return child;
|
|
84
|
+
}
|
|
85
|
+
if (child.type === 'a') {
|
|
86
|
+
return React.cloneElement(child, {
|
|
87
|
+
tabIndex: temporaryStateManagement ? 0 : -1,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return child;
|
|
91
|
+
};
|
|
92
|
+
return (React__default.default.createElement(Container, { id: props.id, className: props.className, "data-testid": dataTestId, "aria-label": props.ariaLabel, role: "region" },
|
|
93
|
+
React__default.default.createElement(Content, { ref: contentRef, isExpanded: temporaryStateManagement, collapsedSize: collapsedSize, "data-testid": dataTestId && `${dataTestId}-content`, "aria-hidden": temporaryStateManagement ? 'false' : 'true', tabIndex: temporaryStateManagement ? 0 : -1 }, React.Children.map(props.children, forceTabIndexOnTextLinks)),
|
|
67
94
|
React__default.default.createElement(ButtonWrapper, { buttonPosition: props.buttonPosition },
|
|
68
|
-
React__default.default.createElement(StyledButtonIcon, { icon: temporaryStateManagement ? icons.ChevronUp : icons.ChevronDown, onClick: handleOnClick }, temporaryButtonLabel || props.buttonLabel))));
|
|
95
|
+
React__default.default.createElement(StyledButtonIcon, { ref: buttonRef, icon: temporaryStateManagement ? icons.ChevronUp : icons.ChevronDown, onClick: handleOnClick, ariaHidden: true, "aria-expanded": temporaryStateManagement }, temporaryButtonLabel || props.buttonLabel))));
|
|
69
96
|
};
|
|
70
97
|
|
|
71
98
|
exports.default = ReadMore;
|
|
@@ -54,8 +54,196 @@ interface Props {
|
|
|
54
54
|
* If not provided, visibleItems property will be used
|
|
55
55
|
*/
|
|
56
56
|
responsive?: Partial<Responsive>;
|
|
57
|
+
/**
|
|
58
|
+
* Allows to pass a screen reader label for the pagination item next to the current slide number
|
|
59
|
+
*/
|
|
60
|
+
paginationAriaLabel?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Allows to pass a screen reader label for the next arrow button
|
|
63
|
+
*/
|
|
64
|
+
nextAriaLabel?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Allows to pass a screen reader label for the previous arrow button
|
|
67
|
+
*/
|
|
68
|
+
previousAriaLabel?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Number of items to move when navigating the carousel
|
|
71
|
+
*
|
|
72
|
+
* @default 1
|
|
73
|
+
*/
|
|
74
|
+
swipeStep?: number;
|
|
57
75
|
}
|
|
76
|
+
declare const SlideItem: import("styled-components").StyledComponent<"div", {
|
|
77
|
+
base: {
|
|
78
|
+
baseHeight: {
|
|
79
|
+
value: number;
|
|
80
|
+
unit: string;
|
|
81
|
+
};
|
|
82
|
+
baseWidth: {
|
|
83
|
+
value: number;
|
|
84
|
+
unit: string;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
breakpoints: import("../../themes/themeComponents/breakpoints").ViewBreakpoints;
|
|
88
|
+
color: {
|
|
89
|
+
default: {
|
|
90
|
+
pink: string;
|
|
91
|
+
plum: string;
|
|
92
|
+
white: string;
|
|
93
|
+
black: string;
|
|
94
|
+
};
|
|
95
|
+
accent: {
|
|
96
|
+
lemon: string;
|
|
97
|
+
sky: string;
|
|
98
|
+
orange: string;
|
|
99
|
+
};
|
|
100
|
+
active: {
|
|
101
|
+
pink: string;
|
|
102
|
+
};
|
|
103
|
+
hover: {
|
|
104
|
+
pink: string;
|
|
105
|
+
};
|
|
106
|
+
text: {
|
|
107
|
+
gray: string;
|
|
108
|
+
pink: string;
|
|
109
|
+
plum: string;
|
|
110
|
+
white: string;
|
|
111
|
+
black: string;
|
|
112
|
+
};
|
|
113
|
+
line: {
|
|
114
|
+
L01: string;
|
|
115
|
+
L02: string;
|
|
116
|
+
L03: string;
|
|
117
|
+
L04: string;
|
|
118
|
+
};
|
|
119
|
+
notification: {
|
|
120
|
+
info: string;
|
|
121
|
+
success: string;
|
|
122
|
+
warning: string;
|
|
123
|
+
error: string;
|
|
124
|
+
};
|
|
125
|
+
background: {
|
|
126
|
+
sand: {
|
|
127
|
+
default: string;
|
|
128
|
+
E01: string;
|
|
129
|
+
E02: string;
|
|
130
|
+
};
|
|
131
|
+
pink: {
|
|
132
|
+
default: string;
|
|
133
|
+
E01: string;
|
|
134
|
+
E02: string;
|
|
135
|
+
};
|
|
136
|
+
plum: {
|
|
137
|
+
default: string;
|
|
138
|
+
E01: string;
|
|
139
|
+
E02: string;
|
|
140
|
+
};
|
|
141
|
+
lemon: {
|
|
142
|
+
default: string;
|
|
143
|
+
E01: string;
|
|
144
|
+
E02: string;
|
|
145
|
+
};
|
|
146
|
+
sky: {
|
|
147
|
+
default: string;
|
|
148
|
+
E01: string;
|
|
149
|
+
E02: string;
|
|
150
|
+
};
|
|
151
|
+
orange: {
|
|
152
|
+
default: string;
|
|
153
|
+
E01: string;
|
|
154
|
+
E02: string;
|
|
155
|
+
};
|
|
156
|
+
white: {
|
|
157
|
+
default: string;
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
focus: {
|
|
161
|
+
dark: string;
|
|
162
|
+
light: string;
|
|
163
|
+
};
|
|
164
|
+
transparency: {
|
|
165
|
+
T0: string;
|
|
166
|
+
T10: string;
|
|
167
|
+
T20: string;
|
|
168
|
+
T30: string;
|
|
169
|
+
T40: string;
|
|
170
|
+
T50: string;
|
|
171
|
+
T60: string;
|
|
172
|
+
T70: string;
|
|
173
|
+
T80: string;
|
|
174
|
+
T90: string;
|
|
175
|
+
T100: string;
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
fontFamily: {
|
|
179
|
+
default: string;
|
|
180
|
+
heading: string;
|
|
181
|
+
numerals: string;
|
|
182
|
+
};
|
|
183
|
+
fontSize: {
|
|
184
|
+
default: string;
|
|
185
|
+
xl: string;
|
|
186
|
+
l: string;
|
|
187
|
+
s: string;
|
|
188
|
+
xs: string;
|
|
189
|
+
h1XL: string;
|
|
190
|
+
h1L: string;
|
|
191
|
+
h1M: string;
|
|
192
|
+
h1S: string;
|
|
193
|
+
h2M: string;
|
|
194
|
+
h2S: string;
|
|
195
|
+
h3: string;
|
|
196
|
+
h4: string;
|
|
197
|
+
h5: string;
|
|
198
|
+
h1: string;
|
|
199
|
+
h2: string;
|
|
200
|
+
};
|
|
201
|
+
fontWeight: {
|
|
202
|
+
book: number;
|
|
203
|
+
medium: number;
|
|
204
|
+
bold: number;
|
|
205
|
+
black: number;
|
|
206
|
+
};
|
|
207
|
+
form: {
|
|
208
|
+
smallSelectWidth: string;
|
|
209
|
+
smallSelectHeight: string;
|
|
210
|
+
};
|
|
211
|
+
grid: {
|
|
212
|
+
gutter: string;
|
|
213
|
+
};
|
|
214
|
+
lineHeight: {
|
|
215
|
+
default: string;
|
|
216
|
+
xl: string;
|
|
217
|
+
s: string;
|
|
218
|
+
xs: string;
|
|
219
|
+
xxs: string;
|
|
220
|
+
auto: string;
|
|
221
|
+
h1XL: string;
|
|
222
|
+
h1L: string;
|
|
223
|
+
h1M: string;
|
|
224
|
+
h1S: string;
|
|
225
|
+
h2M: string;
|
|
226
|
+
h2S: string;
|
|
227
|
+
h3: string;
|
|
228
|
+
h4: string;
|
|
229
|
+
h5: string;
|
|
230
|
+
h1: string;
|
|
231
|
+
h2: string;
|
|
232
|
+
};
|
|
233
|
+
media: Record<string | number, (l: TemplateStringsArray, ...p: (string | number)[]) => string>;
|
|
234
|
+
radius: {
|
|
235
|
+
default: string;
|
|
236
|
+
s: string;
|
|
237
|
+
xs: string;
|
|
238
|
+
circle: string;
|
|
239
|
+
pill: string;
|
|
240
|
+
};
|
|
241
|
+
}, Required<Pick<Props, "visibleItems">> & {
|
|
242
|
+
itemWidthCorrection: number;
|
|
243
|
+
isSwiping: boolean;
|
|
244
|
+
}, never>;
|
|
58
245
|
/** @visibleName Carousel */
|
|
59
246
|
declare const Carousel: ({ "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
|
|
60
247
|
/** @component */
|
|
61
248
|
export default Carousel;
|
|
249
|
+
export { SlideItem };
|
|
@@ -138,6 +138,7 @@ const Counter = styled.span `
|
|
|
138
138
|
`;
|
|
139
139
|
/** @visibleName Carousel */
|
|
140
140
|
const Carousel = (_a) => {
|
|
141
|
+
var _b;
|
|
141
142
|
var { 'data-testid': dataTestId } = _a, props = __rest(_a, ['data-testid']);
|
|
142
143
|
const slidesWrapperRef = useRef(null);
|
|
143
144
|
const scrollbarRef = useRef(null);
|
|
@@ -167,9 +168,18 @@ const Carousel = (_a) => {
|
|
|
167
168
|
}, 100);
|
|
168
169
|
return () => clearTimeout(timeoutId);
|
|
169
170
|
}, [width, isMobile, props.responsive, props.visibleItems, props.children]);
|
|
171
|
+
const getStep = (step, visibleItems) => {
|
|
172
|
+
if (step > visibleItems) {
|
|
173
|
+
return Math.floor(visibleItems);
|
|
174
|
+
}
|
|
175
|
+
return Math.floor(step);
|
|
176
|
+
};
|
|
170
177
|
const visibleItems = props.visibleItems || calculatedItems;
|
|
171
178
|
const slidesWrapperGapSizePx = 20;
|
|
172
179
|
const slideScreensCount = Children.count(props.children) - Math.floor(visibleItems) + 1;
|
|
180
|
+
const step = getStep((_b = props.swipeStep) !== null && _b !== void 0 ? _b : 1, visibleItems);
|
|
181
|
+
const currentStepIndex = Math.ceil(currentIndex / step);
|
|
182
|
+
const totalSwipeSteps = Math.ceil(slideScreensCount / step + ((slideScreensCount - 1) % step !== 0 ? 1 : 0));
|
|
173
183
|
const itemWidthCorrectionRatio = (slidesWrapperGapSizePx * visibleItems) % Math.floor(visibleItems) === 0
|
|
174
184
|
? (visibleItems - 1) / visibleItems
|
|
175
185
|
: Math.floor(visibleItems) / visibleItems;
|
|
@@ -216,14 +226,15 @@ const Carousel = (_a) => {
|
|
|
216
226
|
}
|
|
217
227
|
};
|
|
218
228
|
const handleNavigationButtonPreviousClick = () => {
|
|
219
|
-
handleSetCurrentIndex(currentIndex -
|
|
229
|
+
handleSetCurrentIndex(currentIndex - step);
|
|
220
230
|
};
|
|
221
231
|
const handleNavigationButtonNextClick = () => {
|
|
222
|
-
handleSetCurrentIndex(currentIndex +
|
|
232
|
+
handleSetCurrentIndex(currentIndex + step);
|
|
223
233
|
};
|
|
224
234
|
const handlePaginationItemClick = (e) => {
|
|
225
235
|
if (e.currentTarget.parentElement) {
|
|
226
|
-
|
|
236
|
+
const index = [...e.currentTarget.parentElement.children].indexOf(e.currentTarget);
|
|
237
|
+
handleSetCurrentIndex(index * step);
|
|
227
238
|
}
|
|
228
239
|
};
|
|
229
240
|
const handlePointerMove = (e) => {
|
|
@@ -264,14 +275,14 @@ const Carousel = (_a) => {
|
|
|
264
275
|
if (endTime - data.startTime > 300) {
|
|
265
276
|
const swipeRatio = Math.abs(data.currentTransform - data.startTransform) / data.itemWidth;
|
|
266
277
|
if (swipeRatio >= 0.5) {
|
|
267
|
-
handleSetCurrentIndex(currentIndex + Math.round(data.direction > 0 ? swipeRatio : -swipeRatio));
|
|
278
|
+
handleSetCurrentIndex(currentIndex + Math.round(data.direction > 0 ? swipeRatio : -swipeRatio) * step);
|
|
268
279
|
}
|
|
269
280
|
else {
|
|
270
281
|
handleSetCurrentIndex(currentIndex);
|
|
271
282
|
}
|
|
272
283
|
}
|
|
273
284
|
else {
|
|
274
|
-
handleSetCurrentIndex(currentIndex + data.direction);
|
|
285
|
+
handleSetCurrentIndex(currentIndex + data.direction * step);
|
|
275
286
|
}
|
|
276
287
|
if (data.scrollbarNavigation && data.direction === 0) {
|
|
277
288
|
if (knobRef.current) {
|
|
@@ -333,19 +344,20 @@ const Carousel = (_a) => {
|
|
|
333
344
|
props.title && React__default.createElement(Title, null, props.title),
|
|
334
345
|
React__default.createElement(Navigation, null,
|
|
335
346
|
props.hasCounter && (React__default.createElement(Counter, null,
|
|
336
|
-
slideScreensCount === 0 ? 0 :
|
|
347
|
+
slideScreensCount === 0 ? 0 : currentStepIndex + 1,
|
|
337
348
|
"/",
|
|
338
|
-
|
|
339
|
-
React__default.createElement(ButtonArrow, { direction: "left", "aria-label":
|
|
340
|
-
React__default.createElement(ButtonArrow, { direction: "right", "aria-label":
|
|
349
|
+
totalSwipeSteps)),
|
|
350
|
+
React__default.createElement(ButtonArrow, { direction: "left", "aria-label": props.previousAriaLabel, onClick: handleNavigationButtonPreviousClick, disabled: currentIndex <= 0, type: "button" }),
|
|
351
|
+
React__default.createElement(ButtonArrow, { direction: "right", "aria-label": props.nextAriaLabel, onClick: handleNavigationButtonNextClick, disabled: currentIndex + visibleItems >= Children.count(props.children), type: "button" }))),
|
|
341
352
|
React__default.createElement(Content, { "data-testid": dataTestId && `${dataTestId}-content` },
|
|
342
353
|
React__default.createElement(SlidesWrapper, { ref: slidesWrapperRef, onPointerDown: handleSlidesPointerDown, gap: slidesWrapperGapSizePx / 16 }, Children.map(props.children, child => (React__default.createElement(SlideItem, { visibleItems: visibleItems, itemWidthCorrection: itemWidthCorrection, isSwiping: isSwiping, onPointerDown: handlePointerDown }, child))))),
|
|
343
354
|
React__default.createElement(Footer, { "data-testid": dataTestId && `${dataTestId}-footer` },
|
|
344
|
-
React__default.createElement(Pagination, null, [...Array(
|
|
355
|
+
React__default.createElement(Pagination, null, [...Array(totalSwipeSteps).keys()].map((value, index) => (React__default.createElement(PaginationItem, { key: value, "aria-label": props.paginationAriaLabel &&
|
|
356
|
+
`${props.paginationAriaLabel} ${index + 1}`, "aria-current": Math.ceil(currentIndex / step) === index, isActive: Math.ceil(currentIndex / step) === index, onClick: handlePaginationItemClick, type: "button" })))),
|
|
345
357
|
React__default.createElement(Scrollbar, { ref: scrollbarRef, onPointerDown: handleScrollbarPointerDown },
|
|
346
358
|
React__default.createElement(Knob, { ref: knobRef, knobSize: slideScreensCount })),
|
|
347
359
|
props.footerButton && (React__default.createElement(FooterButton, null,
|
|
348
360
|
React__default.createElement(ButtonIcon, { icon: ArrowRight, onClick: props.onFooterButtonClick }, props.footerButton))))));
|
|
349
361
|
};
|
|
350
362
|
|
|
351
|
-
export { Carousel as default };
|
|
363
|
+
export { SlideItem, Carousel as default };
|
|
@@ -29,6 +29,10 @@ interface Props {
|
|
|
29
29
|
* Allows to pass a custom className
|
|
30
30
|
*/
|
|
31
31
|
className?: string;
|
|
32
|
+
/**
|
|
33
|
+
* An aria-label to the focusable separator should be included if there is more than one focusable separator
|
|
34
|
+
*/
|
|
35
|
+
ariaLabelFocusableSeparator?: string;
|
|
32
36
|
}
|
|
33
37
|
declare const Divider: ({ "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
|
|
34
38
|
/** @component */
|
|
@@ -17,7 +17,8 @@ const DividerWrapper = styled__default.div `
|
|
|
17
17
|
`;
|
|
18
18
|
const Divider = (_a) => {
|
|
19
19
|
var { 'data-testid': dataTestId } = _a, props = __rest(_a, ['data-testid']);
|
|
20
|
-
|
|
20
|
+
const isFocusableSeparator = Boolean(props.children);
|
|
21
|
+
return (React__default.createElement(DividerWrapper, { id: props.id, margin: props.margin, padding: props.padding, className: props.className, "data-testid": dataTestId, as: isFocusableSeparator ? 'div' : 'hr', role: isFocusableSeparator ? 'separator' : undefined, "aria-orientation": "horizontal", "aria-label": props.ariaLabelFocusableSeparator, "aria-hidden": !isFocusableSeparator, tabIndex: isFocusableSeparator ? 0 : -1 }, props.children));
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
export { Divider as default };
|
|
@@ -37,6 +37,10 @@ interface Props {
|
|
|
37
37
|
* Allows to pass testid string for testing purposes
|
|
38
38
|
*/
|
|
39
39
|
'data-testid'?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Allows to pass a screen reader label to the component
|
|
42
|
+
*/
|
|
43
|
+
ariaLabel?: string;
|
|
40
44
|
}
|
|
41
45
|
/** @visibleName Info Dialog */
|
|
42
46
|
declare const InfoDialog: ({ position, type, "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
|
|
@@ -54,7 +54,7 @@ const InfoDialogContainer = styled.div `
|
|
|
54
54
|
/** @visibleName Info Dialog */
|
|
55
55
|
const InfoDialog = (_a) => {
|
|
56
56
|
var { position = 'middle', type = 'default', 'data-testid': dataTestId } = _a, props = __rest(_a, ["position", "type", 'data-testid']);
|
|
57
|
-
return (React__default.createElement(InfoDialogContainer, { id: props.id, "data-testid": dataTestId, className: props.className, position: position, type: type }, props.children));
|
|
57
|
+
return (React__default.createElement(InfoDialogContainer, { id: props.id, "data-testid": dataTestId, className: props.className, position: position, type: type, role: "region", "aria-label": props.ariaLabel }, props.children));
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
export { InfoDialog as default };
|
|
@@ -158,8 +158,7 @@ const Input = (_a) => {
|
|
|
158
158
|
return (React__default.createElement(FieldContainer, { className: props.className },
|
|
159
159
|
props.label && (React__default.createElement(LabelText, { htmlFor: props.id, "data-testid": dataTestId && `${dataTestId}-label`, status: props.status === 'error' ? props.status : undefined, isMandatory: props.required }, props.label)),
|
|
160
160
|
React__default.createElement(FieldWrapper, { status: props.status, "$type": type, "$disabled": props.disabled },
|
|
161
|
-
React__default.createElement(StyledInput, { id: props.id, name: props.name, type:
|
|
162
|
-
props.readonly && React__default.createElement("div", null, props.value),
|
|
161
|
+
React__default.createElement(StyledInput, { id: props.id, name: props.name, type: type, value: props.value, placeholder: props.placeholder, onChange: handleChange, onBlur: handleOnBlur, onFocus: props.onFocus, onClick: onClick, onKeyDown: props.onKeyDown, onKeyPress: props.onKeyPress, required: props.required, disabled: props.disabled, autoComplete: props.autocomplete, "aria-disabled": props.disabled, "aria-label": !props.label ? (_b = props.ariaLabel) !== null && _b !== void 0 ? _b : props.id : undefined, ref: inputRef, tabIndex: props.tabIndex, "aria-describedby": getDescribedBy(), "data-testid": dataTestId, readOnly: props.readonly }),
|
|
163
162
|
((props.status && props.status !== 'comment') ||
|
|
164
163
|
props.showPasswordToggle ||
|
|
165
164
|
props.disabled ||
|
|
@@ -18,10 +18,12 @@ interface Props {
|
|
|
18
18
|
* Styling of `label` element changes depending on the passed status
|
|
19
19
|
*
|
|
20
20
|
* @param {LabelTextStatus} undefined Default styling
|
|
21
|
-
* @param {LabelTextStatus} info Changes color to
|
|
22
|
-
* @param {LabelTextStatus} success Changes color to
|
|
23
|
-
* @param {LabelTextStatus} warning Changes color to
|
|
21
|
+
* @param {LabelTextStatus} info Changes color to default color (this type will be deprecated in the future)
|
|
22
|
+
* @param {LabelTextStatus} success Changes color to default color (this type will be deprecated in the future)
|
|
23
|
+
* @param {LabelTextStatus} warning Changes color to default color (this type will be deprecated in the future)
|
|
24
24
|
* @param {LabelTextStatus} error Changes color to `theme.color.notification.error`
|
|
25
|
+
*
|
|
26
|
+
* @deprecated info, success and warning are deprecated, please switch to default or error status
|
|
25
27
|
*/
|
|
26
28
|
status?: LabelTextStatus;
|
|
27
29
|
/**
|
|
@@ -6,7 +6,7 @@ import { getDividedSize } from '../../utils/styledUtils.js';
|
|
|
6
6
|
|
|
7
7
|
const Label = styled.label `
|
|
8
8
|
display: block;
|
|
9
|
-
color: ${({ status }) =>
|
|
9
|
+
color: ${({ status }) => status === 'error' ? theme.color.notification.error : theme.color.text.gray};
|
|
10
10
|
font-weight: ${theme.fontWeight.medium};
|
|
11
11
|
font-size: ${theme.fontSize.default};
|
|
12
12
|
line-height: ${theme.lineHeight.default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MouseEvent } from 'react';
|
|
1
|
+
import type { MouseEvent, KeyboardEvent } from 'react';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
type ProgressIndicatorStatus = 'error';
|
|
4
4
|
interface Props {
|
|
@@ -15,7 +15,7 @@ interface Props {
|
|
|
15
15
|
* On Progress Indicator Item label or number click callback
|
|
16
16
|
* Use `e.currentTarget.parentElement` to get Progress Indicator Item element
|
|
17
17
|
*/
|
|
18
|
-
onStepClick?: (stepIndex: number, e: MouseEvent<HTMLElement>) => void;
|
|
18
|
+
onStepClick?: (stepIndex: number, e: MouseEvent<HTMLElement> | KeyboardEvent<HTMLElement>) => void;
|
|
19
19
|
/**
|
|
20
20
|
* Allows to change version of component to small
|
|
21
21
|
*/
|
|
@@ -118,14 +118,21 @@ const ProgressIndicator = (_a) => {
|
|
|
118
118
|
props.onStepClick(index, e);
|
|
119
119
|
}
|
|
120
120
|
};
|
|
121
|
-
|
|
121
|
+
const handleKeyDown = (e) => {
|
|
122
|
+
if ((e.key === 'Enter' || e.key === ' ') && props.onStepClick) {
|
|
123
|
+
e.preventDefault();
|
|
124
|
+
props.onStepClick(index, e);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const isClickable = isCompleted && Boolean(props.onStepClick);
|
|
128
|
+
return (React__default.createElement(ProgressIndicatorItem, { key: id, small: props.small },
|
|
122
129
|
index > 0 && (React__default.createElement(ProgressIndicatorItemConnector, { small: props.small, isActive: isActive, isCompleted: isCompleted })),
|
|
123
|
-
React__default.createElement(ProgressIndicatorItemNumber, { small: props.small, onClick: handleClick, isActive: isActive, isCompleted: isCompleted, isError: isError, isClickable:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
label && (React__default.createElement(ProgressIndicatorItemLabel, { small: props.small, onClick: handleClick, isActive: isActive, className: "visually-hidden" }, label))));
|
|
130
|
+
React__default.createElement(ProgressIndicatorItemNumber, { small: props.small, onClick: handleClick, isActive: isActive, isCompleted: isCompleted, isError: isError, onKeyDown: handleKeyDown, tabIndex: isClickable || isActive ? 0 : -1, isClickable: isClickable, role: "tab", "aria-current": isActive ? 'step' : 'false', "aria-label": isCompleted && props.completedStepLabel
|
|
131
|
+
? `${label}, ${props.completedStepLabel}`
|
|
132
|
+
: label }, isCompleted || isError ? (React__default.createElement(Icon, { icon: isError ? Warning : Check, color: isError ? theme.color.text.white : theme.color.text.pink, size: "1rem", "aria-hidden": true })) : (stepNumber)),
|
|
133
|
+
label && (React__default.createElement(ProgressIndicatorItemLabel, { "aria-hidden": true, small: props.small, onClick: handleClick, isActive: isActive, className: "visually-hidden" }, label))));
|
|
127
134
|
});
|
|
128
|
-
return (React__default.createElement(ProgressIndicatorWrapper, { className: props.className, "data-testid": dataTestId, "aria-label": props.ariaLabel, role: "
|
|
135
|
+
return (React__default.createElement(ProgressIndicatorWrapper, { className: props.className, "data-testid": dataTestId, "aria-label": props.ariaLabel, role: "tablist" }, progressIndicatorItems));
|
|
129
136
|
};
|
|
130
137
|
|
|
131
138
|
export { ProgressIndicator as default };
|
|
@@ -68,6 +68,10 @@ interface Props {
|
|
|
68
68
|
* Allows to pass testid string for testing purposes
|
|
69
69
|
*/
|
|
70
70
|
'data-testid'?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Allows to pass an accessible label for the component, enhancing screen reader support.
|
|
73
|
+
*/
|
|
74
|
+
ariaLabel?: string;
|
|
71
75
|
}
|
|
72
76
|
/** @visibleName Read More */
|
|
73
77
|
declare const ReadMore: ({ collapsedSize, "data-testid": dataTestId, ...props }: Props) => React.JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __rest } from 'tslib';
|
|
2
2
|
import { ChevronUp, ChevronDown } from '@dnanpm/icons';
|
|
3
|
-
import React__default, { useState, useEffect } from 'react';
|
|
3
|
+
import React__default, { useState, useRef, useEffect, Children, isValidElement, cloneElement } from 'react';
|
|
4
4
|
import styled from '../../themes/styled.js';
|
|
5
5
|
import theme from '../../themes/theme.js';
|
|
6
6
|
import ButtonIcon from '../ButtonIcon/ButtonIcon.js';
|
|
@@ -37,6 +37,9 @@ const StyledButtonIcon = styled(ButtonIcon) `
|
|
|
37
37
|
const ReadMore = (_a) => {
|
|
38
38
|
var { collapsedSize = '10rem', 'data-testid': dataTestId } = _a, props = __rest(_a, ["collapsedSize", 'data-testid']);
|
|
39
39
|
const [expanded, setExpanded] = useState(props.seoInitExpanded === true || false);
|
|
40
|
+
const contentRef = useRef(null);
|
|
41
|
+
const buttonRef = useRef(null);
|
|
42
|
+
const userInteractedRef = useRef(false);
|
|
40
43
|
// TODO: Remove once https://jira.dna.fi/browse/STYLE-662 is done
|
|
41
44
|
const temporaryIsStatelessFlag = typeof props.isExpanded !== 'undefined';
|
|
42
45
|
const temporaryStateManagement = temporaryIsStatelessFlag ? props.isExpanded : expanded;
|
|
@@ -48,16 +51,40 @@ const ReadMore = (_a) => {
|
|
|
48
51
|
if (!temporaryIsStatelessFlag) {
|
|
49
52
|
setExpanded(!expanded);
|
|
50
53
|
}
|
|
54
|
+
userInteractedRef.current = true;
|
|
51
55
|
};
|
|
52
56
|
useEffect(() => {
|
|
53
57
|
if (props.seoInitExpanded) {
|
|
54
58
|
setExpanded(false);
|
|
55
59
|
}
|
|
56
60
|
}, [props.seoInitExpanded]);
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
var _a, _b;
|
|
63
|
+
if (userInteractedRef.current) {
|
|
64
|
+
if (temporaryStateManagement) {
|
|
65
|
+
(_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
(_b = buttonRef.current) === null || _b === void 0 ? void 0 : _b.focus();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}, [temporaryStateManagement]);
|
|
72
|
+
// Function to apply tabIndex to all links elements of children (since we don't control what is passed as children)
|
|
73
|
+
const forceTabIndexOnTextLinks = (child) => {
|
|
74
|
+
if (!isValidElement(child)) {
|
|
75
|
+
return child;
|
|
76
|
+
}
|
|
77
|
+
if (child.type === 'a') {
|
|
78
|
+
return cloneElement(child, {
|
|
79
|
+
tabIndex: temporaryStateManagement ? 0 : -1,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return child;
|
|
83
|
+
};
|
|
84
|
+
return (React__default.createElement(Container, { id: props.id, className: props.className, "data-testid": dataTestId, "aria-label": props.ariaLabel, role: "region" },
|
|
85
|
+
React__default.createElement(Content, { ref: contentRef, isExpanded: temporaryStateManagement, collapsedSize: collapsedSize, "data-testid": dataTestId && `${dataTestId}-content`, "aria-hidden": temporaryStateManagement ? 'false' : 'true', tabIndex: temporaryStateManagement ? 0 : -1 }, Children.map(props.children, forceTabIndexOnTextLinks)),
|
|
59
86
|
React__default.createElement(ButtonWrapper, { buttonPosition: props.buttonPosition },
|
|
60
|
-
React__default.createElement(StyledButtonIcon, { icon: temporaryStateManagement ? ChevronUp : ChevronDown, onClick: handleOnClick }, temporaryButtonLabel || props.buttonLabel))));
|
|
87
|
+
React__default.createElement(StyledButtonIcon, { ref: buttonRef, icon: temporaryStateManagement ? ChevronUp : ChevronDown, onClick: handleOnClick, ariaHidden: true, "aria-expanded": temporaryStateManagement }, temporaryButtonLabel || props.buttonLabel))));
|
|
61
88
|
};
|
|
62
89
|
|
|
63
90
|
export { ReadMore as default };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dnanpm/styleguide",
|
|
3
3
|
"sideEffects": false,
|
|
4
|
-
"version": "v3.9.
|
|
4
|
+
"version": "v3.9.9",
|
|
5
5
|
"main": "build/cjs/index.js",
|
|
6
6
|
"module": "build/es/index.js",
|
|
7
7
|
"jsnext:main": "build/es/index.js",
|
|
@@ -41,14 +41,14 @@
|
|
|
41
41
|
"not op_mini all"
|
|
42
42
|
],
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@babel/core": "^7.26.
|
|
44
|
+
"@babel/core": "^7.26.10",
|
|
45
45
|
"@babel/preset-env": "^7.26.0",
|
|
46
46
|
"@babel/preset-react": "^7.26.3",
|
|
47
47
|
"@babel/preset-typescript": "^7.27.0",
|
|
48
48
|
"@dnanpm/icons": "2.0.7",
|
|
49
|
-
"@rollup/plugin-commonjs": "^28.0.
|
|
49
|
+
"@rollup/plugin-commonjs": "^28.0.3",
|
|
50
50
|
"@rollup/plugin-node-resolve": "^15.3.0",
|
|
51
|
-
"@rollup/plugin-typescript": "^12.1.
|
|
51
|
+
"@rollup/plugin-typescript": "^12.1.2",
|
|
52
52
|
"@testing-library/jest-dom": "^6.6.3",
|
|
53
53
|
"@testing-library/react": "^14.3.1",
|
|
54
54
|
"@testing-library/user-event": "^14.5.2",
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"ts-node": "^10.9.2",
|
|
95
95
|
"tslib": "^2.8.1",
|
|
96
96
|
"typescript": "^5.1.6",
|
|
97
|
-
"webpack": "^5.
|
|
97
|
+
"webpack": "^5.99.6"
|
|
98
98
|
},
|
|
99
99
|
"dependencies": {
|
|
100
100
|
"ramda": "^0.27.1",
|