ublo-lib 1.5.10 → 1.6.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.
@@ -0,0 +1,2 @@
1
+ import ScrollingCarousel from "./scrolling-carousel";
2
+ export default ScrollingCarousel;
@@ -0,0 +1,93 @@
1
+ import * as React from "react";
2
+ import Button from "dt-design-system/es/button";
3
+ import * as Icons from "dt-design-system/es/icons";
4
+ import useWindowSizes from "ublo-lib/es/common/hooks/use-window-sizes";
5
+ import css from "./scrolling-carousel.module.css";
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ import { jsxs as _jsxs } from "react/jsx-runtime";
8
+ const PREV = 0;
9
+ const NEXT = 1;
10
+
11
+ const ScrollingCarousel = ({
12
+ children
13
+ }) => {
14
+ const ref = React.useRef(null);
15
+ const zoneRef = React.useRef(null);
16
+ const [overflow, setOverflow] = React.useState(false);
17
+ const [controls, setControls] = React.useState({
18
+ prevDisabled: false,
19
+ nextDisabled: false
20
+ });
21
+ const {
22
+ width
23
+ } = useWindowSizes();
24
+
25
+ const slideTo = direction => () => {
26
+ const inner = ref.current;
27
+ const firstSection = zoneRef.current?.querySelector("section:not([data-hidden], [hidden])");
28
+
29
+ if (firstSection) {
30
+ const scrollDistance = firstSection.clientWidth;
31
+
32
+ if (direction === PREV) {
33
+ inner.scrollLeft -= scrollDistance;
34
+ }
35
+
36
+ if (direction === NEXT) {
37
+ inner.scrollLeft += scrollDistance;
38
+ }
39
+ }
40
+ };
41
+
42
+ const refreshControls = React.useCallback(() => {
43
+ const inner = ref.current;
44
+ const zone = zoneRef.current;
45
+
46
+ if (zone) {
47
+ setOverflow(inner.clientWidth < zone.clientWidth);
48
+ setControls({
49
+ prevDisabled: inner.scrollLeft === 0,
50
+ nextDisabled: inner.scrollLeft === Math.round(inner.scrollWidth) - Math.round(inner.clientWidth)
51
+ });
52
+ }
53
+ }, []);
54
+ React.useEffect(() => {
55
+ refreshControls();
56
+ }, [refreshControls]);
57
+ React.useEffect(() => {
58
+ const inner = ref.current;
59
+ inner.scrollLeft = 0;
60
+ }, [width]);
61
+ return _jsxs("div", {
62
+ className: css.carousel,
63
+ children: [overflow && _jsxs("div", {
64
+ className: css.controls,
65
+ children: [_jsx(Button, {
66
+ className: css.control,
67
+ variant: "link",
68
+ onClick: slideTo(PREV),
69
+ disabled: controls.prevDisabled,
70
+ children: _jsx(Icons.ChevronLeft, {
71
+ className: css.controlIcon
72
+ })
73
+ }), _jsx(Button, {
74
+ className: css.control,
75
+ variant: "link",
76
+ onClick: slideTo(NEXT),
77
+ disabled: controls.nextDisabled,
78
+ children: _jsx(Icons.ChevronRight, {
79
+ className: css.controlIcon
80
+ })
81
+ })]
82
+ }), _jsx("div", {
83
+ className: css.inner,
84
+ ref: ref,
85
+ onScroll: refreshControls,
86
+ children: React.cloneElement(children, {
87
+ ref: zoneRef
88
+ })
89
+ })]
90
+ });
91
+ };
92
+
93
+ export default ScrollingCarousel;
@@ -0,0 +1,49 @@
1
+ .carousel {
2
+ position: relative;
3
+ }
4
+
5
+ .controls {
6
+ position: absolute;
7
+ bottom: 100%;
8
+ right: 0;
9
+ display: flex;
10
+ align-items: center;
11
+ gap: 8px;
12
+ }
13
+
14
+ button.control {
15
+ color: var(--ds-primary, var(--ds-blue-500, #004cc2));
16
+ }
17
+
18
+ svg.controlIcon {
19
+ --size: 24px;
20
+ }
21
+
22
+ .inner {
23
+ display: flex;
24
+ padding: 20px 0;
25
+ scroll-snap-type: x proximity;
26
+ overflow: auto;
27
+ scroll-behavior: smooth;
28
+ }
29
+
30
+ @media (min-width: 990px) {
31
+ .inner {
32
+ padding: 40px 0;
33
+ overflow: hidden;
34
+ }
35
+ }
36
+
37
+ .inner > :global(.cms) {
38
+ flex: 0 0 auto;
39
+ }
40
+
41
+ :global(.cms--editing) .inner {
42
+ padding: 40px 60px;
43
+ overflow: auto;
44
+ scroll-snap-type: none;
45
+ }
46
+
47
+ .inner > :global(.cms) > :global(section) {
48
+ scroll-snap-align: start;
49
+ }
@@ -59,6 +59,9 @@ const renderField = (lang, label, classes, name, field, data, setData) => {
59
59
  required,
60
60
  className
61
61
  } = field;
62
+ const isOptionArrayValid = Array.isArray(options);
63
+ const firstKey = !isOptionArrayValid && Object.keys(options)[0];
64
+ const optionsToDisplay = isOptionArrayValid ? options : options[firstKey];
62
65
  const Tag = getTag(type);
63
66
  const fieldClasses = classnames(className, {
64
67
  [classes]: classes
@@ -82,7 +85,7 @@ const renderField = (lang, label, classes, name, field, data, setData) => {
82
85
  const formatedOptions = [{
83
86
  label: Messages.get(lang, "select"),
84
87
  value: ""
85
- }].concat(options.map(option => {
88
+ }].concat(optionsToDisplay.map(option => {
86
89
  return {
87
90
  label: option.label?.[lang],
88
91
  value: option.value ?? option.label?.[lang]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ublo-lib",
3
- "version": "1.5.10",
3
+ "version": "1.6.0",
4
4
  "peerDependencies": {
5
5
  "dt-design-system": "^2.1.0",
6
6
  "next": "^12.0.0",