@semcore/carousel 3.28.3 → 3.29.0-prerelease.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Carousel.tsx CHANGED
@@ -23,6 +23,7 @@ import CarouselType, {
23
23
  import { BoxProps } from '@semcore/flex-box';
24
24
  import { findAllComponents } from '@semcore/utils/lib/findComponent';
25
25
  import { createBreakpoints } from '@semcore/breakpoints';
26
+ import keyboardFocusEnhance from '@semcore/utils/lib/enhances/keyboardFocusEnhance';
26
27
 
27
28
  const MAP_TRANSFORM: Record<string, 'left' | 'right'> = {
28
29
  ArrowLeft: 'left',
@@ -32,6 +33,7 @@ const MAP_TRANSFORM: Record<string, 'left' | 'right'> = {
32
33
  const enhance = {
33
34
  uid: uniqueIDEnhancement(),
34
35
  getI18nText: i18nEnhance(localizedMessages),
36
+ keyboardFocusEnhance: keyboardFocusEnhance(),
35
37
  };
36
38
  const media = ['(min-width: 481px)', '(max-width: 480px)'];
37
39
  const BreakPoints = createBreakpoints(media);
@@ -58,6 +60,7 @@ class CarouselRoot extends Component<
58
60
  static enhance = Object.values(enhance);
59
61
 
60
62
  defaultItemsCount = 0;
63
+ refCarousel = React.createRef<HTMLElement>();
61
64
  refContainer = React.createRef<HTMLElement>();
62
65
  refModalContainer = React.createRef<HTMLElement>();
63
66
  _touchStartCoord = -1;
@@ -74,7 +77,15 @@ class CarouselRoot extends Component<
74
77
 
75
78
  uncontrolledProps() {
76
79
  return {
77
- index: null,
80
+ index: [
81
+ null,
82
+ (_index: number) => {
83
+ this.refCarousel.current?.blur();
84
+ setTimeout(() => {
85
+ this.refCarousel.current?.focus();
86
+ }, 0);
87
+ },
88
+ ],
78
89
  };
79
90
  }
80
91
 
@@ -115,11 +126,36 @@ class CarouselRoot extends Component<
115
126
  }
116
127
 
117
128
  handlerKeyDown = (e: React.KeyboardEvent) => {
129
+ const firstSlide = 1;
130
+ const lastSlide = this.state.items.length + 1;
131
+
118
132
  switch (e.key) {
119
133
  case 'ArrowLeft':
120
134
  case 'ArrowRight': {
121
135
  e.preventDefault();
122
136
  this.transformItem(MAP_TRANSFORM[e.key]);
137
+ break;
138
+ }
139
+ case 'Home': {
140
+ e.preventDefault();
141
+ this.slideToValue(firstSlide);
142
+ break;
143
+ }
144
+ case 'End': {
145
+ e.preventDefault();
146
+ this.slideToValue(lastSlide);
147
+ break;
148
+ }
149
+ }
150
+
151
+ if (e.metaKey) {
152
+ // like home or end
153
+ if (e.key === 'ArrowLeft') {
154
+ e.preventDefault();
155
+ this.slideToValue(firstSlide);
156
+ } else if (e.key === 'ArrowRight') {
157
+ e.preventDefault();
158
+ this.slideToValue(lastSlide);
123
159
  }
124
160
  }
125
161
  };
@@ -333,6 +369,7 @@ class CarouselRoot extends Component<
333
369
  onKeyDown: this.bindHandlerKeydownControl('left'),
334
370
  disabled,
335
371
  label: getI18nText('prev'),
372
+ tabIndex: -1,
336
373
  };
337
374
  }
338
375
 
@@ -349,6 +386,7 @@ class CarouselRoot extends Component<
349
386
  onKeyDown: this.bindHandlerKeydownControl('right'),
350
387
  disabled,
351
388
  label: getI18nText('next'),
389
+ tabIndex: -1,
352
390
  };
353
391
  }
354
392
 
@@ -485,9 +523,9 @@ class CarouselRoot extends Component<
485
523
  render={Box}
486
524
  role='group'
487
525
  onKeyDown={this.handlerKeyDown}
488
- tabIndex={0}
489
526
  onTouchStart={this.handlerTouchStart}
490
527
  onTouchEnd={this.handlerTouchEnd}
528
+ ref={this.refCarousel}
491
529
  >
492
530
  {Controls.length === 0 ? (
493
531
  <>
@@ -589,7 +627,7 @@ class Item extends Component<CarouselItemProps> {
589
627
  }
590
628
 
591
629
  const Prev = (props: CarouselButtonProps) => {
592
- const { styles, children, Children, label, top = 0, inverted } = props;
630
+ const { styles, children, Children, label, top = 0, inverted, tabIndex } = props;
593
631
  const SPrev = Root;
594
632
  const SPrevButton = Button;
595
633
  const [isActive, setIsActive] = React.useState(false);
@@ -612,6 +650,7 @@ const Prev = (props: CarouselButtonProps) => {
612
650
  use={'tertiary'}
613
651
  active={isActive}
614
652
  size={'l'}
653
+ tabIndex={tabIndex}
615
654
  />
616
655
  )}
617
656
  </SPrev>,
@@ -619,7 +658,7 @@ const Prev = (props: CarouselButtonProps) => {
619
658
  };
620
659
 
621
660
  const Next = (props: CarouselButtonProps) => {
622
- const { styles, children, Children, label, top = 0, inverted } = props;
661
+ const { styles, children, Children, label, top = 0, inverted, tabIndex } = props;
623
662
  const SNext = Root;
624
663
  const SNextButton = Button;
625
664
  const [isActive, setIsActive] = React.useState(false);
@@ -642,6 +681,7 @@ const Next = (props: CarouselButtonProps) => {
642
681
  use={'tertiary'}
643
682
  active={isActive}
644
683
  size={'l'}
684
+ tabIndex={tabIndex}
645
685
  />
646
686
  )}
647
687
  </SNext>,
@@ -90,6 +90,7 @@ export type CarouselButtonProps = IRootComponentProps &
90
90
  BoxProps & {
91
91
  label?: string;
92
92
  inverted?: boolean;
93
+ tabIndex?: number;
93
94
  };
94
95
 
95
96
  export type CarouselIndicatorsProps = IRootComponentProps &
@@ -4,6 +4,11 @@ SCarousel {
4
4
  user-select: none;
5
5
  }
6
6
 
7
+ SCarousel[keyboardFocused] {
8
+ box-shadow: var(--intergalactic-keyboard-focus, 0px 0px 0px 3px rgba(0, 143, 248, 0.5));
9
+ z-index: 1;
10
+ }
11
+
7
12
  SContainer {
8
13
  display: flex;
9
14
  transition: transform var(--duration) ease-in-out;