@festo-ui/react 7.0.0-dev.395 → 7.0.0-dev.396

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,12 @@
1
+ /// <reference types="react" />
2
+ interface BottomSheetProps {
3
+ children: React.ReactNode;
4
+ defaultExpanded?: boolean;
5
+ open?: boolean;
6
+ expandFrom?: 'center' | 'bottom';
7
+ hasBackdrop?: boolean;
8
+ hideCloseIcon?: boolean;
9
+ onOpenChange?: (value: boolean) => void;
10
+ }
11
+ export default function BottomSheet({ children, open, defaultExpanded, expandFrom, hasBackdrop, hideCloseIcon, onOpenChange, }: BottomSheetProps): JSX.Element;
12
+ export {};
@@ -0,0 +1,95 @@
1
+ /* eslint-disable jsx-a11y/no-static-element-interactions */
2
+ /* eslint-disable jsx-a11y/click-events-have-key-events */
3
+ import cn from 'classnames';
4
+ import { useState } from 'react';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ import { jsxs as _jsxs } from "react/jsx-runtime";
7
+ import { Fragment as _Fragment } from "react/jsx-runtime";
8
+ export default function BottomSheet(_ref) {
9
+ let {
10
+ children,
11
+ open,
12
+ defaultExpanded,
13
+ expandFrom = 'center',
14
+ hasBackdrop = true,
15
+ hideCloseIcon,
16
+ onOpenChange
17
+ } = _ref;
18
+ const [expanded, setExpanded] = useState(defaultExpanded);
19
+ const [isClosing, setClosing] = useState(false);
20
+ const [startY, setStartY] = useState(0);
21
+ const [swiping, setSwiping] = useState(false);
22
+ function toggleExpand() {
23
+ const newExpanded = !expanded;
24
+ setExpanded(newExpanded);
25
+ }
26
+ function closeBottomSheet() {
27
+ setClosing(true);
28
+ setExpanded(defaultExpanded);
29
+ setTimeout(() => {
30
+ setClosing(false);
31
+ onOpenChange?.(false);
32
+ }, 300);
33
+ }
34
+ const handleTouchStart = event => {
35
+ setStartY(event.touches[0].clientY);
36
+ setSwiping(true);
37
+ };
38
+ const handleTouchMove = event => {
39
+ if (!swiping) return;
40
+ const currentY = event.touches[0].clientY;
41
+ const deltaY = currentY - startY;
42
+ if (deltaY < -50 && !expanded) {
43
+ // swipe up to expand
44
+ setExpanded(true);
45
+ setSwiping(false);
46
+ } else if (deltaY > 50 && expanded) {
47
+ // swipe down to collapse
48
+ setExpanded(false);
49
+ setSwiping(false);
50
+ } else if (deltaY > 100 && !expanded) {
51
+ // swipe down to close
52
+ closeBottomSheet();
53
+ setSwiping(false);
54
+ }
55
+ };
56
+ return /*#__PURE__*/_jsxs(_Fragment, {
57
+ children: [/*#__PURE__*/_jsx("div", {
58
+ className: cn('fwe-bottom-sheet-backdrop', {
59
+ 'fwe-bottom-sheet-backdrop--visible': hasBackdrop && open && !isClosing
60
+ }),
61
+ onClick: closeBottomSheet
62
+ }), /*#__PURE__*/_jsxs("div", {
63
+ className: cn('fwe-bottom-sheet-container', {
64
+ 'fwe-bottom-sheet-container--open': open,
65
+ 'fwe-bottom-sheet-container--expanded': expanded,
66
+ 'fwe-bottom-sheet-container--expand-from-center': expandFrom === 'center',
67
+ 'fwe-bottom-sheet-container--with-backdrop': hasBackdrop,
68
+ 'fwe-bottom-sheet-container--closing': isClosing
69
+ }),
70
+ onTouchStart: handleTouchStart,
71
+ onTouchMove: handleTouchMove,
72
+ children: [/*#__PURE__*/_jsxs("div", {
73
+ className: "fwe-bottom-sheet-header",
74
+ children: [/*#__PURE__*/_jsx("div", {
75
+ className: "fwe-bottom-sheet-drag-handle-container",
76
+ onClick: toggleExpand,
77
+ children: /*#__PURE__*/_jsx("div", {
78
+ className: "fwe-bottom-sheet-drag-handle"
79
+ })
80
+ }), !hideCloseIcon && /*#__PURE__*/_jsx("button", {
81
+ type: "button",
82
+ className: "fwe-bottom-sheet-close-btn",
83
+ onClick: closeBottomSheet,
84
+ children: /*#__PURE__*/_jsx("span", {
85
+ className: "fwe-sr-only",
86
+ children: "Close"
87
+ })
88
+ })]
89
+ }), /*#__PURE__*/_jsx("div", {
90
+ className: "fwe-bottom-sheet-content",
91
+ children: children
92
+ })]
93
+ })]
94
+ });
95
+ }
@@ -0,0 +1,9 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import BottomSheet from './BottomSheet';
3
+ declare const meta: Meta<typeof BottomSheet>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof BottomSheet>;
6
+ export declare const Default: Story;
7
+ export declare const WithoutBackdrop: Story;
8
+ export declare const ExpandFromBottom: Story;
9
+ export declare const WithoutCloseIcon: Story;
@@ -0,0 +1,51 @@
1
+ import { useState } from 'react';
2
+ import BottomSheet from './BottomSheet';
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ import { Fragment as _Fragment } from "react/jsx-runtime";
5
+ import { jsxs as _jsxs } from "react/jsx-runtime";
6
+ const meta = {
7
+ component: BottomSheet,
8
+ title: 'Components/Bottom Sheet',
9
+ decorators: [Story => /*#__PURE__*/_jsx("div", {
10
+ style: {
11
+ minHeight: 600
12
+ },
13
+ children: /*#__PURE__*/_jsx(Story, {})
14
+ })]
15
+ };
16
+ export default meta;
17
+ export const Default = {
18
+ render: args => {
19
+ const [open, setOpen] = useState(false);
20
+ return /*#__PURE__*/_jsxs(_Fragment, {
21
+ children: [/*#__PURE__*/_jsx("button", {
22
+ type: "button",
23
+ className: "fwe-btn",
24
+ onClick: () => setOpen(true),
25
+ children: "Open"
26
+ }), /*#__PURE__*/_jsx(BottomSheet, {
27
+ ...args,
28
+ open: open,
29
+ onOpenChange: setOpen
30
+ })]
31
+ });
32
+ }
33
+ };
34
+ export const WithoutBackdrop = {
35
+ args: {
36
+ hasBackdrop: false
37
+ },
38
+ render: Default.render
39
+ };
40
+ export const ExpandFromBottom = {
41
+ args: {
42
+ expandFrom: 'bottom'
43
+ },
44
+ render: Default.render
45
+ };
46
+ export const WithoutCloseIcon = {
47
+ args: {
48
+ hideCloseIcon: true
49
+ },
50
+ render: Default.render
51
+ };
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = BottomSheet;
7
+ var _classnames = _interopRequireDefault(require("classnames"));
8
+ var _react = require("react");
9
+ var _jsxRuntime = require("react/jsx-runtime");
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+ /* eslint-disable jsx-a11y/no-static-element-interactions */
12
+ /* eslint-disable jsx-a11y/click-events-have-key-events */
13
+
14
+ function BottomSheet(_ref) {
15
+ let {
16
+ children,
17
+ open,
18
+ defaultExpanded,
19
+ expandFrom = 'center',
20
+ hasBackdrop = true,
21
+ hideCloseIcon,
22
+ onOpenChange
23
+ } = _ref;
24
+ const [expanded, setExpanded] = (0, _react.useState)(defaultExpanded);
25
+ const [isClosing, setClosing] = (0, _react.useState)(false);
26
+ const [startY, setStartY] = (0, _react.useState)(0);
27
+ const [swiping, setSwiping] = (0, _react.useState)(false);
28
+ function toggleExpand() {
29
+ const newExpanded = !expanded;
30
+ setExpanded(newExpanded);
31
+ }
32
+ function closeBottomSheet() {
33
+ setClosing(true);
34
+ setExpanded(defaultExpanded);
35
+ setTimeout(() => {
36
+ setClosing(false);
37
+ onOpenChange?.(false);
38
+ }, 300);
39
+ }
40
+ const handleTouchStart = event => {
41
+ setStartY(event.touches[0].clientY);
42
+ setSwiping(true);
43
+ };
44
+ const handleTouchMove = event => {
45
+ if (!swiping) return;
46
+ const currentY = event.touches[0].clientY;
47
+ const deltaY = currentY - startY;
48
+ if (deltaY < -50 && !expanded) {
49
+ // swipe up to expand
50
+ setExpanded(true);
51
+ setSwiping(false);
52
+ } else if (deltaY > 50 && expanded) {
53
+ // swipe down to collapse
54
+ setExpanded(false);
55
+ setSwiping(false);
56
+ } else if (deltaY > 100 && !expanded) {
57
+ // swipe down to close
58
+ closeBottomSheet();
59
+ setSwiping(false);
60
+ }
61
+ };
62
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
63
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
64
+ className: (0, _classnames.default)('fwe-bottom-sheet-backdrop', {
65
+ 'fwe-bottom-sheet-backdrop--visible': hasBackdrop && open && !isClosing
66
+ }),
67
+ onClick: closeBottomSheet
68
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
69
+ className: (0, _classnames.default)('fwe-bottom-sheet-container', {
70
+ 'fwe-bottom-sheet-container--open': open,
71
+ 'fwe-bottom-sheet-container--expanded': expanded,
72
+ 'fwe-bottom-sheet-container--expand-from-center': expandFrom === 'center',
73
+ 'fwe-bottom-sheet-container--with-backdrop': hasBackdrop,
74
+ 'fwe-bottom-sheet-container--closing': isClosing
75
+ }),
76
+ onTouchStart: handleTouchStart,
77
+ onTouchMove: handleTouchMove,
78
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
79
+ className: "fwe-bottom-sheet-header",
80
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
81
+ className: "fwe-bottom-sheet-drag-handle-container",
82
+ onClick: toggleExpand,
83
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
84
+ className: "fwe-bottom-sheet-drag-handle"
85
+ })
86
+ }), !hideCloseIcon && /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
87
+ type: "button",
88
+ className: "fwe-bottom-sheet-close-btn",
89
+ onClick: closeBottomSheet,
90
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
91
+ className: "fwe-sr-only",
92
+ children: "Close"
93
+ })
94
+ })]
95
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
96
+ className: "fwe-bottom-sheet-content",
97
+ children: children
98
+ })]
99
+ })]
100
+ });
101
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.WithoutCloseIcon = exports.WithoutBackdrop = exports.ExpandFromBottom = exports.Default = void 0;
7
+ var _react = require("react");
8
+ var _BottomSheet = _interopRequireDefault(require("./BottomSheet"));
9
+ var _jsxRuntime = require("react/jsx-runtime");
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+ const meta = {
12
+ component: _BottomSheet.default,
13
+ title: 'Components/Bottom Sheet',
14
+ decorators: [Story => /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
15
+ style: {
16
+ minHeight: 600
17
+ },
18
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Story, {})
19
+ })]
20
+ };
21
+ var _default = exports.default = meta;
22
+ const Default = exports.Default = {
23
+ render: args => {
24
+ const [open, setOpen] = (0, _react.useState)(false);
25
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
26
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
27
+ type: "button",
28
+ className: "fwe-btn",
29
+ onClick: () => setOpen(true),
30
+ children: "Open"
31
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_BottomSheet.default, {
32
+ ...args,
33
+ open: open,
34
+ onOpenChange: setOpen
35
+ })]
36
+ });
37
+ }
38
+ };
39
+ const WithoutBackdrop = exports.WithoutBackdrop = {
40
+ args: {
41
+ hasBackdrop: false
42
+ },
43
+ render: Default.render
44
+ };
45
+ const ExpandFromBottom = exports.ExpandFromBottom = {
46
+ args: {
47
+ expandFrom: 'bottom'
48
+ },
49
+ render: Default.render
50
+ };
51
+ const WithoutCloseIcon = exports.WithoutCloseIcon = {
52
+ args: {
53
+ hideCloseIcon: true
54
+ },
55
+ render: Default.render
56
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@festo-ui/react",
3
- "version": "7.0.0-dev.395",
3
+ "version": "7.0.0-dev.396",
4
4
  "author": "Festo UI (styleguide@festo.com)",
5
5
  "license": "apache-2.0",
6
6
  "exports": {