@7shifts/sous-chef 4.9.0 → 4.10.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.
@@ -1,6 +1,8 @@
1
1
  import React from 'react';
2
2
  type Props = {
3
3
  testId?: string;
4
+ children?: React.ReactNode;
5
+ line?: 'top' | 'bottom' | 'both';
4
6
  };
5
- declare const DropdownListDivider: ({ testId }: Props) => React.JSX.Element;
7
+ declare const DropdownListDivider: ({ testId, children, line }: Props) => React.JSX.Element;
6
8
  export default DropdownListDivider;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ type Props = {
3
+ testId?: string;
4
+ };
5
+ declare const DropdownListDividerLine: ({ testId }: Props) => React.JSX.Element;
6
+ export default DropdownListDividerLine;
@@ -0,0 +1 @@
1
+ export { default } from './DropdownListDividerLine';
@@ -10,9 +10,10 @@ export type Props = {
10
10
  secondaryButton?: React.ReactElement;
11
11
  testId?: string;
12
12
  onSetDoNotShowAgainStatus?: (doNotShowAgain: boolean) => void;
13
+ hideDoNotShowAgainCheckbox?: boolean;
13
14
  } & PositionStyles;
14
15
  /**
15
16
  * Hint Modal is a lightweight modal used to surface tips, guidance, or onboarding callouts to users the first time they encounter a feature or page. Unlike a regular Modal, it is not triggered by a user action — it appears automatically when the user navigates somewhere that warrants a guided introduction. It includes a "Don't show this again" option so users can dismiss it permanently once they've absorbed the information.
16
17
  */
17
- declare const HintModal: ({ header, children, mediaUrl, onClose, modalId, primaryButton, secondaryButton, testId, onSetDoNotShowAgainStatus, ...positionProps }: Props) => React.JSX.Element;
18
+ declare const HintModal: ({ header, children, mediaUrl, onClose, modalId, primaryButton, secondaryButton, testId, onSetDoNotShowAgainStatus, hideDoNotShowAgainCheckbox, ...positionProps }: Props) => React.JSX.Element;
18
19
  export default HintModal;
@@ -17,12 +17,19 @@ type Props = {
17
17
  maxWidth?: number | string;
18
18
  shouldReturnFocusAfterClose?: boolean;
19
19
  testId?: string;
20
+ /** Enables drag-to-reposition. The overlay becomes transparent and the modal can be moved by dragging its header. */
21
+ draggable?: boolean;
22
+ /** Initial screen position when draggable is true. Defaults to centered horizontally at 25% from top. */
23
+ initialPosition?: {
24
+ top: number;
25
+ left: number;
26
+ };
20
27
  } & DataProps;
21
28
  /**
22
29
  * Modal is a focused overlay that interrupts the current experience and demands the user's attention. It blocks all interaction with the rest of the page until the user responds — making it best suited for decisions, confirmations, and self-contained flows where that level of focus is warranted.
23
30
  */
24
31
  declare const Modal: {
25
- ({ children, header, subHeader, onClose, loading, zIndex, rootElementId, width, height, maxWidth, shouldReturnFocusAfterClose, testId, ...otherProps }: Props): React.JSX.Element;
32
+ ({ children, header, subHeader, onClose, loading, zIndex, rootElementId, width, height, maxWidth, shouldReturnFocusAfterClose, testId, draggable, initialPosition, ...otherProps }: Props): React.JSX.Element;
26
33
  setAppElement(rootElement: string | HTMLElement): void;
27
34
  };
28
35
  export default Modal;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  export type ModalContextType = {
3
3
  isModalMounted: boolean;
4
+ draggable: boolean;
4
5
  };
5
6
  declare const ModalContext: React.Context<ModalContextType>;
6
7
  export declare const useModalContext: () => ModalContextType;
@@ -0,0 +1,38 @@
1
+ export type Options = {
2
+ width: number | string;
3
+ height?: number | string;
4
+ initialPosition?: {
5
+ top: number;
6
+ left: number;
7
+ };
8
+ };
9
+ export type DraggableModalState = {
10
+ nodeRef: React.RefObject<HTMLElement | null>;
11
+ /** Attach to the draggable inner div's `ref` prop. Keeps nodeRef in sync and drives measurement. */
12
+ callbackRef: React.RefCallback<HTMLElement>;
13
+ contentPosition: {
14
+ top: number;
15
+ left: number;
16
+ };
17
+ bounds: {
18
+ left: number;
19
+ top: number;
20
+ right: number;
21
+ bottom: number;
22
+ };
23
+ };
24
+ /**
25
+ * Encapsulates the ref, initial positioning, and viewport-aware bounds for a
26
+ * draggable modal. Pass the returned values to <Draggable> and the ReactModal
27
+ * style.content object.
28
+ *
29
+ * Bounds are expressed as pixel offsets from the element's rendered position
30
+ * (react-draggable v4.7+ no longer accepts "window" as a string shorthand).
31
+ *
32
+ * Initial bounds are estimated from the numeric width/height props (falling
33
+ * back to the CSS min-width/min-height defaults). After mount, the element is
34
+ * measured and bounds are corrected to the actual rendered dimensions so the
35
+ * modal cannot be dragged outside the viewport even when width/height are CSS
36
+ * strings or the content exceeds the fallback height.
37
+ */
38
+ export declare function useDraggableModal({ width, height, initialPosition, }: Options): DraggableModalState;
@@ -0,0 +1,10 @@
1
+ export type ModalPosition = {
2
+ top: number;
3
+ left: number;
4
+ };
5
+ /**
6
+ * Returns the current modal position and an updater that centers the modal on
7
+ * the provided mouse event's coordinates, clamped to a 20px viewport margin.
8
+ * Useful when opening a draggable Modal relative to a user click.
9
+ */
10
+ export declare const useModalPosition: (modalWidth?: number, modalHeight?: number) => [ModalPosition | undefined, (event: MouseEvent) => void];
@@ -10,4 +10,6 @@ import DropdownListItem from './DropdownListItem';
10
10
  import DropdownListItemSelectable from './DropdownListItemSelectable';
11
11
  import HintModal from './HintModal';
12
12
  import Popover from './Popover';
13
+ export { useModalPosition } from './Modal/useModalPosition';
14
+ export type { ModalPosition } from './Modal/useModalPosition';
13
15
  export { Tooltip, Modal, ModalBody, ModalFooter, Calendar, Dropdown, DropdownList, DropdownListDivider, DropdownListItem, DropdownListItemSelectable, HintModal, Popover };
@@ -45,3 +45,4 @@ A `primaryButton` is required — typically a "Got it" button that closes the mo
45
45
  - `primaryButton` is required. Pass a `Button` element — the component does not render default actions on its own.
46
46
  - Visibility is partially managed internally via local storage. Once a user checks "Don't show again", the modal will not render again for that `modalId` unless the key is cleared.
47
47
  - `onSetDoNotShowAgainStatus` fires when the checkbox state changes, if you need to sync this externally.
48
+ - `hideDoNotShowAgainCheckbox` hides the checkbox. `onSetDoNotShowAgainStatus` never fires.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7shifts/sous-chef",
3
- "version": "4.9.0",
3
+ "version": "4.10.0",
4
4
  "description": "7shifts component library",
5
5
  "author": "7shifts",
6
6
  "license": "MIT",
@@ -54,18 +54,21 @@
54
54
  "@babel/core": "^7.24.4",
55
55
  "@babel/preset-env": "^7.24.4",
56
56
  "@changesets/cli": "^2.29.8",
57
+ "@playwright/test": "^1.54.0",
57
58
  "@storybook/addon-a11y": "10.3.5",
58
59
  "@storybook/addon-docs": "10.3.5",
59
60
  "@storybook/addon-links": "10.3.5",
60
61
  "@storybook/addon-mcp": "^0.6.0",
61
62
  "@storybook/addon-onboarding": "10.3.5",
62
63
  "@storybook/react-vite": "10.3.5",
64
+ "@storybook/test-runner": "^0.24.4",
63
65
  "@svgr/cli": "^8.0.1",
64
66
  "@testing-library/jest-dom": "^5.12.0",
65
67
  "@testing-library/react": "^11.2.7",
66
68
  "@testing-library/react-hooks": "^8.0.1",
67
69
  "@testing-library/user-event": "^13.2.1",
68
70
  "@types/jest": "^25.1.4",
71
+ "@types/jest-image-snapshot": "^6.4.0",
69
72
  "@types/lodash-es": "^4.17.5",
70
73
  "@types/node": "^22",
71
74
  "@types/react": "^18.2.15",
@@ -75,13 +78,7 @@
75
78
  "@typescript-eslint/parser": "^6.11.0",
76
79
  "@vitejs/plugin-react": "^4.7.0",
77
80
  "babel-jest": "^29.7.0",
78
- "@playwright/test": "^1.54.0",
79
- "@storybook/test-runner": "^0.24.4",
80
- "@types/jest-image-snapshot": "^6.4.0",
81
81
  "concurrently": "^9.1.0",
82
- "http-server": "^14.1.1",
83
- "jest-image-snapshot": "^6.5.2",
84
- "wait-on": "^8.0.1",
85
82
  "cross-env": "^7.0.3",
86
83
  "eslint": "^8.53.0",
87
84
  "eslint-config-prettier": "^9.0.0",
@@ -97,10 +94,12 @@
97
94
  "eslint-plugin-standard": "^5.0.0",
98
95
  "eslint-plugin-storybook": "10.3.5",
99
96
  "formik": "^2.2.6",
97
+ "http-server": "^14.1.1",
100
98
  "identity-obj-proxy": "^3.0.0",
101
99
  "jest": "^29.7.0",
102
100
  "jest-environment-jsdom": "^29.7.0",
103
101
  "jest-environment-jsdom-sixteen": "^2.0.0",
102
+ "jest-image-snapshot": "^6.5.2",
104
103
  "microbundle": "^0.15.1",
105
104
  "npm-run-all": "^4.1.5",
106
105
  "prompt": "^1.3.0",
@@ -113,6 +112,7 @@
113
112
  "ts-jest": "^29.1.2",
114
113
  "typescript": "^5.3.2",
115
114
  "vite": "^6.4.1",
115
+ "wait-on": "^8.0.1",
116
116
  "yup": "^0.32.9"
117
117
  },
118
118
  "files": [
@@ -125,6 +125,7 @@
125
125
  "libphonenumber-js": "^1.10.36",
126
126
  "lodash-es": "^4.17.15",
127
127
  "react-day-picker": "^8.8.0",
128
+ "react-draggable": "^4.4.5",
128
129
  "react-modal": "^3.16.1",
129
130
  "react-router-dom": "5.1.2 - 6.7.0",
130
131
  "react-select": "^5.10.0",