reshaped 3.10.0-canary.5 → 3.10.0-canary.6

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.
@@ -11,7 +11,7 @@ import useIsomorphicLayoutEffect from "../../hooks/useIsomorphicLayoutEffect.js"
11
11
  import s from "./Autocomplete.module.css";
12
12
  const AutocompleteContext = React.createContext({});
13
13
  const Autocomplete = (props) => {
14
- const { children, onChange, onInput, onItemSelect, name, containerRef, instanceRef, onBackspace, onEnter, active, onOpen, onClose, fallbackAdjustLayout, fallbackMinWidth, fallbackMinHeight, contentMaxHeight, ...textFieldProps } = props;
14
+ const { children, onChange, onInput, onItemSelect, name, containerRef, instanceRef, onBackspace, onEnter, active, onOpen, onClose, fallbackAdjustLayout, fallbackMinWidth, fallbackMinHeight, contentMaxHeight, contentZIndex, ...textFieldProps } = props;
15
15
  const [highlightedId, setHighlightedId] = React.useState();
16
16
  const onBackspaceRef = useHandlerRef(onBackspace);
17
17
  const contentRef = React.useRef(null);
@@ -120,7 +120,7 @@ const Autocomplete = (props) => {
120
120
  highlightedId,
121
121
  setHighlightedId,
122
122
  }), [highlightedId, handleItemClick]);
123
- return (_jsx(AutocompleteContext.Provider, { value: contextValue, children: _jsxs(DropdownMenu, { position: "bottom", width: "trigger", triggerType: "focus", trapFocusMode: false, active: isDropdownActive, onClose: handleClose, onOpen: handleOpen, containerRef: containerRef, fallbackAdjustLayout: fallbackAdjustLayout, fallbackMinWidth: fallbackMinWidth, fallbackMinHeight: fallbackMinHeight, contentMaxHeight: contentMaxHeight, disableHideAnimation: true, instanceRef: instanceRef, children: [_jsx(DropdownMenu.Trigger, { children: ({ ref, ...attributes }) => (_jsx(TextField, { ...textFieldProps, name: name, onChange: handleChange, focused: isDropdownActive, attributes: {
123
+ return (_jsx(AutocompleteContext.Provider, { value: contextValue, children: _jsxs(DropdownMenu, { position: "bottom", width: "trigger", triggerType: "focus", trapFocusMode: false, active: isDropdownActive, onClose: handleClose, onOpen: handleOpen, containerRef: containerRef, fallbackAdjustLayout: fallbackAdjustLayout, fallbackMinWidth: fallbackMinWidth, fallbackMinHeight: fallbackMinHeight, contentMaxHeight: contentMaxHeight, contentZIndex: contentZIndex, disableHideAnimation: true, instanceRef: instanceRef, children: [_jsx(DropdownMenu.Trigger, { children: ({ ref, ...attributes }) => (_jsx(TextField, { ...textFieldProps, name: name, onChange: handleChange, focused: isDropdownActive, attributes: {
124
124
  ...textFieldProps.attributes,
125
125
  // Ignoring the type check since TS can't infer the correct html element type
126
126
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -7,7 +7,7 @@ type SelectArgs = {
7
7
  /** Additional data that will be passed to the onItemSelect callback */
8
8
  data?: unknown;
9
9
  };
10
- export type Props = TextFieldProps & Pick<DropdownMenuProps, "containerRef" | "instanceRef" | "active" | "onOpen" | "onClose" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "contentMaxHeight"> & {
10
+ export type Props = TextFieldProps & Pick<DropdownMenuProps, "containerRef" | "instanceRef" | "active" | "onOpen" | "onClose" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "contentMaxHeight" | "contentZIndex"> & {
11
11
  /** Callback for when value changes from user input */
12
12
  onInput?: TextFieldProps["onChange"];
13
13
  /** Callback for when an item is selected in the dropdown */
@@ -3,7 +3,7 @@ import type { MenuItemProps } from "../MenuItem";
3
3
  import type { PopoverProps, PopoverInstance } from "../Popover";
4
4
  import type React from "react";
5
5
  export type Instance = PopoverInstance;
6
- export type Props = Pick<PopoverProps, "children" | "position" | "forcePosition" | "fallbackPositions" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "triggerType" | "contentGap" | "contentShift" | "contentMaxHeight" | "onOpen" | "onClose" | "active" | "defaultActive" | "width" | "disableHideAnimation" | "disableCloseOnOutsideClick" | "instanceRef" | "containerRef" | "positionRef" | "originCoordinates" | "borderRadius" | "elevation" | "initialFocusRef"> & {
6
+ export type Props = Pick<PopoverProps, "children" | "position" | "forcePosition" | "fallbackPositions" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "triggerType" | "contentGap" | "contentShift" | "contentMaxHeight" | "contentZIndex" | "onOpen" | "onClose" | "active" | "defaultActive" | "width" | "disableHideAnimation" | "disableCloseOnOutsideClick" | "instanceRef" | "containerRef" | "positionRef" | "originCoordinates" | "borderRadius" | "elevation" | "initialFocusRef"> & {
7
7
  /** Change component trap focus keyboard behavior and shortcuts */
8
8
  trapFocusMode?: Extract<PopoverProps["trapFocusMode"], "action-menu" | "selection-menu"> | false;
9
9
  };
@@ -1 +1 @@
1
- .content{--rs-flyout-max-h:100%;--rs-flyout-max-w:100%;--rs-flyout-origin-x:50%;--rs-flyout-origin-y:50%;display:flex;flex-direction:column;isolation:isolate;pointer-events:none;position:absolute;z-index:var(--rs-z-index-absolute)}.content.--hover{pointer-events:all}.content.--hover-disabled,.content.--hover-disabled .inner{pointer-events:none}.inner{backface-visibility:hidden;flex-grow:1;height:100%;max-height:var(--rs-flyout-max-h);max-width:var(--rs-flyout-max-w);opacity:0;outline:none;overflow:auto;pointer-events:all;transform:scale(.92) translateY(0);transform-origin:var(--rs-flyout-origin-x) var(--rs-flyout-origin-y);transition:1ms var(--rs-easing-accelerate)}[data-rs-keyboard] .inner:focus{box-shadow:var(--rs-shadow-focus)}.content.--width-trigger .inner{transform:scale(1) translateY(var(--rs-unit-x2))}.content.--position-top,.content.--position-top-end,.content.--position-top-start{--rs-flyout-origin-y:100%}.content.--position-bottom,.content.--position-bottom-end,.content.--position-bottom-start{--rs-flyout-origin-y:0%}.content.--position-bottom-start,.content.--position-top-start{--rs-flyout-origin-x:0%}.content.--position-bottom-end,.content.--position-start,.content.--position-start-bottom,.content.--position-start-top,.content.--position-top-end{--rs-flyout-origin-x:100%}.content.--position-end,.content.--position-end-bottom,.content.--position-end-top{--rs-flyout-origin-x:0%}.content.--position-end-top,.content.--position-start-top{--rs-flyout-origin-y:0%}.content.--position-end-bottom,.content.--position-start-bottom{--rs-flyout-origin-y:100%}.content.--visible .inner{opacity:1;transform:scale(1) translateY(0)}.content.--animated .inner{transition-duration:var(--rs-duration-rapid);transition-property:opacity,transform}.content.--animated.--visible .inner{transition-duration:var(--rs-duration-fast);transition-timing-function:var(--rs-easing-decelerate)}
1
+ .content{--rs-flyout-max-h:100%;--rs-flyout-max-w:100%;--rs-flyout-z-index:var(--rs-z-index-absolute);--rs-flyout-origin-x:50%;--rs-flyout-origin-y:50%;display:flex;flex-direction:column;isolation:isolate;pointer-events:none;position:absolute;z-index:var(--rs-flyout-z-index)}.content.--hover{pointer-events:all}.content.--hover-disabled,.content.--hover-disabled .inner{pointer-events:none}.inner{backface-visibility:hidden;flex-grow:1;height:100%;max-height:var(--rs-flyout-max-h);max-width:var(--rs-flyout-max-w);opacity:0;outline:none;overflow:auto;pointer-events:all;transform:scale(.92) translateY(0);transform-origin:var(--rs-flyout-origin-x) var(--rs-flyout-origin-y);transition:1ms var(--rs-easing-accelerate)}[data-rs-keyboard] .inner:focus{box-shadow:var(--rs-shadow-focus)}.content.--width-trigger .inner{transform:scale(1) translateY(var(--rs-unit-x2))}.content.--position-top,.content.--position-top-end,.content.--position-top-start{--rs-flyout-origin-y:100%}.content.--position-bottom,.content.--position-bottom-end,.content.--position-bottom-start{--rs-flyout-origin-y:0%}.content.--position-bottom-start,.content.--position-top-start{--rs-flyout-origin-x:0%}.content.--position-bottom-end,.content.--position-start,.content.--position-start-bottom,.content.--position-start-top,.content.--position-top-end{--rs-flyout-origin-x:100%}.content.--position-end,.content.--position-end-bottom,.content.--position-end-top{--rs-flyout-origin-x:0%}.content.--position-end-top,.content.--position-start-top{--rs-flyout-origin-y:0%}.content.--position-end-bottom,.content.--position-start-bottom{--rs-flyout-origin-y:100%}.content.--visible .inner{opacity:1;transform:scale(1) translateY(0)}.content.--animated .inner{transition-duration:var(--rs-duration-rapid);transition-property:opacity,transform}.content.--animated.--visible .inner{transition-duration:var(--rs-duration-fast);transition-timing-function:var(--rs-easing-decelerate)}
@@ -134,6 +134,8 @@ type BaseProps = {
134
134
  contentMaxHeight?: string;
135
135
  /** Maximum width for the content */
136
136
  contentMaxWidth?: string;
137
+ /** Z-index for the content element */
138
+ contentZIndex?: number;
137
139
  /** Additional classname for the content element */
138
140
  contentClassName?: string;
139
141
  /** Additional attributes for the content element */
@@ -190,7 +192,7 @@ export type ContextProps = {
190
192
  handleContentMouseDown: () => void;
191
193
  handleContentMouseUp: () => void;
192
194
  isSubmenu: boolean;
193
- } & Pick<Props, "triggerType" | "contentClassName" | "contentAttributes" | "contentGap" | "contentMaxHeight" | "contentMaxWidth" | "trapFocusMode" | "containerRef" | "disableContentHover" | "autoFocus">;
195
+ } & Pick<Props, "triggerType" | "contentClassName" | "contentAttributes" | "contentGap" | "contentMaxHeight" | "contentMaxWidth" | "contentZIndex" | "trapFocusMode" | "containerRef" | "disableContentHover" | "autoFocus">;
194
196
  export type TriggerContextProps = {
195
197
  elRef?: ContextProps["triggerElRef"];
196
198
  };
@@ -9,7 +9,7 @@ import s from "./Flyout.module.css";
9
9
  import cooldown from "./utilities/cooldown.js";
10
10
  const FlyoutContent = (props) => {
11
11
  const { children, className, attributes } = props;
12
- const { flyout, id, flyoutElRef, handleTransitionEnd, triggerType, handleContentMouseEnter, handleMouseLeave, handleContentMouseDown, handleContentMouseUp, contentClassName, contentAttributes, contentMaxHeight, contentMaxWidth, trapFocusMode, disableContentHover, autoFocus, width, isSubmenu, } = useFlyoutContext();
12
+ const { flyout, id, flyoutElRef, handleTransitionEnd, triggerType, handleContentMouseEnter, handleMouseLeave, handleContentMouseDown, handleContentMouseUp, contentClassName, contentAttributes, contentMaxHeight, contentMaxWidth, contentZIndex, trapFocusMode, disableContentHover, autoFocus, width, isSubmenu, } = useFlyoutContext();
13
13
  const { status, position } = flyout;
14
14
  const [mounted, setMounted] = React.useState(false);
15
15
  useIsomorphicLayoutEffect(() => {
@@ -43,6 +43,7 @@ const FlyoutContent = (props) => {
43
43
  const content = (_jsx(ContentProvider, { value: { elRef: flyoutElRef }, children: _jsx("div", { className: rootClassNames, style: {
44
44
  "--rs-flyout-max-h": contentMaxHeight,
45
45
  "--rs-flyout-max-w": contentMaxWidth,
46
+ "--rs-flyout-z-index": contentZIndex,
46
47
  }, ref: flyoutElRef, onTransitionEnd: handleTransitionEnd, onMouseEnter: triggerType === "hover" ? handleContentMouseEnter : undefined, onMouseLeave: triggerType === "hover" ? handleMouseLeave : undefined, onMouseDown: handleContentMouseDown, onTouchStart: handleContentMouseDown, onMouseUp: handleContentMouseUp, onTouchEnd: handleContentMouseUp, children: _jsx("div", { role: role, ...attributes, id: id, tabIndex: !autoFocus ? -1 : undefined, "aria-modal": role === "dialog" ? true : undefined, style: { ...attributes?.style, ...contentAttributes?.style }, className: innerClassNames, children: children }) }) }));
47
48
  return _jsx(Portal, { children: content });
48
49
  };
@@ -17,7 +17,7 @@ import useFlyout from "./useFlyout.js";
17
17
  import cooldown from "./utilities/cooldown.js";
18
18
  import { createSafeArea } from "./utilities/safeArea.js";
19
19
  const FlyoutControlled = (props) => {
20
- const { triggerType = "click", groupTimeouts, onOpen, onClose, children, disabled, forcePosition, fallbackAdjustLayout, fallbackMinHeight, trapFocusMode = "dialog", width, disableHideAnimation, disableContentHover, disableCloseOnOutsideClick, autoFocus = true, originCoordinates, contentGap = 2, contentShift, contentMaxHeight, contentMaxWidth, contentClassName, contentAttributes, position: passedPosition, active: passedActive, id: passedId, instanceRef, containerRef, initialFocusRef, positionRef, } = props;
20
+ const { triggerType = "click", groupTimeouts, onOpen, onClose, children, disabled, forcePosition, fallbackAdjustLayout, fallbackMinHeight, trapFocusMode = "dialog", width, disableHideAnimation, disableContentHover, disableCloseOnOutsideClick, autoFocus = true, originCoordinates, contentGap = 2, contentShift, contentMaxHeight, contentMaxWidth, contentZIndex, contentClassName, contentAttributes, position: passedPosition, active: passedActive, id: passedId, instanceRef, containerRef, initialFocusRef, positionRef, } = props;
21
21
  const fallbackPositions = props.fallbackPositions === false || forcePosition ? [] : props.fallbackPositions;
22
22
  const onOpenRef = useHandlerRef(onOpen);
23
23
  const onCloseRef = useHandlerRef(onClose);
@@ -350,6 +350,7 @@ const FlyoutControlled = (props) => {
350
350
  handleContentMouseUp,
351
351
  triggerType,
352
352
  trapFocusMode,
353
+ contentZIndex,
353
354
  contentClassName,
354
355
  contentAttributes,
355
356
  contentGap,
@@ -41,7 +41,7 @@ export const ModalSubtitle = (props) => {
41
41
  return (_jsx(Text, { variant: "body-3", color: "neutral-faded", attributes: { id: `${id}-subtitle` }, children: children }));
42
42
  };
43
43
  const Modal = (props) => {
44
- const { children, onClose, onOpen, onAfterClose, onAfterOpen, active, size, padding = 4, position = "center", overflow, transparentOverlay, blurredOverlay, ariaLabel, autoFocus = true, disableSwipeGesture, disableCloseOnOutsideClick, containerRef, overlayClassName, className, attributes, } = props;
44
+ const { children, onClose, onOpen, onAfterClose, onAfterOpen, active, size, padding = 4, position = "center", overflow, transparentOverlay, blurredOverlay, ariaLabel, autoFocus = true, disableSwipeGesture, disableCloseOnOutsideClick, containerRef, contained, overlayClassName, className, attributes, } = props;
45
45
  const onCloseRef = useHandlerRef(onClose);
46
46
  const id = useElementId();
47
47
  const clientPosition = useResponsiveClientValue(position);
@@ -57,6 +57,7 @@ const Modal = (props) => {
57
57
  const [dragDistance, setDragDistance] = React.useState(0);
58
58
  const [hideProgress, setHideProgress] = React.useState(0);
59
59
  const mixinStyles = resolveMixin({ padding });
60
+ const shouldBeContained = containerRef && contained !== false;
60
61
  const value = React.useMemo(() => ({
61
62
  titleMounted,
62
63
  setTitleMounted,
@@ -166,10 +167,10 @@ const Modal = (props) => {
166
167
  setHideProgress(progress / 2);
167
168
  dragDistanceRef.current = dragDistance;
168
169
  }, [dragDistance, clientPosition, rootRef]);
169
- return (_jsx(Overlay, { onClose: onClose, onOpen: onOpen, onAfterClose: onAfterClose, onAfterOpen: onAfterOpen, disableCloseOnClick: disableCloseOnOutsideClick, active: active, transparent: transparentOverlay || hideProgress, blurred: blurredOverlay, overflow: clientPosition === "center" ? "auto" : "hidden", className: overlayClassName, containerRef: containerRef, attributes: {
170
+ return (_jsx(Overlay, { onClose: onClose, onOpen: onOpen, onAfterClose: onAfterClose, onAfterOpen: onAfterOpen, disableCloseOnClick: disableCloseOnOutsideClick, active: active, transparent: transparentOverlay || hideProgress, blurred: blurredOverlay, overflow: clientPosition === "center" ? "auto" : "hidden", className: overlayClassName, contained: contained, containerRef: containerRef, attributes: {
170
171
  onTouchStart: handleDragStart,
171
172
  }, children: ({ active }) => {
172
- const rootClassNames = classNames(s.root, className, active && s["--active"], dragging && s["--dragging"], overflow && s[`--overflow-${overflow}`], containerRef && s["--contained"], responsiveClassNames(s, "--position", position), mixinStyles.classNames);
173
+ const rootClassNames = classNames(s.root, className, active && s["--active"], dragging && s["--dragging"], overflow && s[`--overflow-${overflow}`], shouldBeContained && s["--contained"], responsiveClassNames(s, "--position", position), mixinStyles.classNames);
173
174
  return (_jsx(Context.Provider, { value: value, children: _jsx("div", { ...attributes, style: {
174
175
  ...mixinStyles.variables,
175
176
  ...responsiveVariables("--rs-modal-size", size),
@@ -53,4 +53,4 @@ export type Props = {
53
53
  attributes?: G.Attributes<"div"> & {
54
54
  ref?: React.RefObject<HTMLDivElement | null>;
55
55
  };
56
- } & Pick<OverlayProps, "onOpen" | "onAfterOpen" | "onAfterClose" | "active" | "containerRef">;
56
+ } & Pick<OverlayProps, "onOpen" | "onAfterOpen" | "onAfterClose" | "active" | "containerRef" | "contained">;
@@ -13,7 +13,7 @@ import useToggle from "../../hooks/useToggle.js";
13
13
  import { onNextFrame } from "../../utilities/animation.js";
14
14
  import s from "./Overlay.module.css";
15
15
  const Overlay = (props) => {
16
- const { active, children, transparent, blurred, overflow, onClose, onOpen, onAfterClose, onAfterOpen, disableCloseOnClick, containerRef, className, attributes, } = props;
16
+ const { active, children, transparent, blurred, overflow, onClose, onOpen, onAfterClose, onAfterOpen, disableCloseOnClick, containerRef, contained, className, attributes, } = props;
17
17
  // Selectors wrapped with refs to simplify working with useEffect dependency array
18
18
  const onCloseRef = useHandlerRef(onClose);
19
19
  const onOpenRef = useHandlerRef(onOpen);
@@ -32,7 +32,8 @@ const Overlay = (props) => {
32
32
  const { active: rendered, activate: render, deactivate: remove } = useToggle(active || false);
33
33
  const { active: visible, activate: show, deactivate: hide } = useToggle(active || false);
34
34
  const isDismissible = useIsDismissible({ active, contentRef, hasTrigger: false });
35
- const rootClassNames = classNames(s.root, visible && s["--visible"], isTransparent && s["--click-through"], blurred && s["--blurred"], animated && s["--animated"], containerRef && s["--contained"], overflow === "auto" && s["--overflow-auto"], className);
35
+ const shouldBeContained = containerRef && contained !== false;
36
+ const rootClassNames = classNames(s.root, visible && s["--visible"], isTransparent && s["--click-through"], blurred && s["--blurred"], animated && s["--animated"], shouldBeContained && s["--contained"], overflow === "auto" && s["--overflow-auto"], className);
36
37
  const isInsideContent = (el) => {
37
38
  if (!contentRef.current)
38
39
  return;
@@ -28,6 +28,8 @@ export type Props = {
28
28
  disableCloseOnClick?: boolean;
29
29
  /** Element to render the component in */
30
30
  containerRef?: React.RefObject<HTMLElement | null>;
31
+ /** Contain the component within the container element. Defaults to true when containerRef is provided */
32
+ contained?: boolean;
31
33
  /** Additional classname for the root element */
32
34
  className?: G.ClassName;
33
35
  /** Additional attributes for the root element */
@@ -1,7 +1,7 @@
1
1
  import type { FlyoutProps, FlyoutInstance } from "../Flyout";
2
2
  import type React from "react";
3
3
  export type Instance = FlyoutInstance;
4
- export type Props = Pick<FlyoutProps, "id" | "position" | "forcePosition" | "fallbackPositions" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "onOpen" | "onClose" | "width" | "trapFocusMode" | "active" | "defaultActive" | "contentGap" | "contentShift" | "contentMaxHeight" | "instanceRef" | "triggerType" | "disableHideAnimation" | "disableContentHover" | "disableCloseOnOutsideClick" | "autoFocus" | "containerRef" | "positionRef" | "initialFocusRef" | "originCoordinates"> & {
4
+ export type Props = Pick<FlyoutProps, "id" | "position" | "forcePosition" | "fallbackPositions" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight" | "onOpen" | "onClose" | "width" | "trapFocusMode" | "active" | "defaultActive" | "contentGap" | "contentShift" | "contentMaxHeight" | "contentZIndex" | "instanceRef" | "triggerType" | "disableHideAnimation" | "disableContentHover" | "disableCloseOnOutsideClick" | "autoFocus" | "containerRef" | "positionRef" | "initialFocusRef" | "originCoordinates"> & {
5
5
  /** Node for inserting children */
6
6
  children?: React.ReactNode;
7
7
  /** Content element padding, unit token multiplier */
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import type { FlyoutProps, FlyoutTriggerAttributes } from "../Flyout";
3
- export type Props = Pick<FlyoutProps, "id" | "position" | "onOpen" | "onClose" | "active" | "disabled" | "disableContentHover" | "containerRef" | "positionRef" | "contentGap" | "contentShift" | "contentMaxWidth" | "originCoordinates" | "contentAttributes" | "contentClassName" | "instanceRef"> & {
3
+ export type Props = Pick<FlyoutProps, "id" | "position" | "onOpen" | "onClose" | "active" | "disabled" | "disableContentHover" | "containerRef" | "positionRef" | "contentGap" | "contentShift" | "contentMaxWidth" | "contentZIndex" | "originCoordinates" | "contentAttributes" | "contentClassName" | "instanceRef"> & {
4
4
  /** Node for inserting children */
5
5
  children: (attributes: FlyoutTriggerAttributes) => React.ReactNode;
6
6
  /** Text content for the tooltip */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reshaped",
3
3
  "description": "Professionally crafted design system in React & Figma for building products of any scale and complexity",
4
- "version": "3.10.0-canary.5",
4
+ "version": "3.10.0-canary.6",
5
5
  "license": "MIT",
6
6
  "email": "hello@reshaped.so",
7
7
  "homepage": "https://reshaped.so",
@@ -91,7 +91,7 @@
91
91
  "csstype": "3.1.3",
92
92
  "culori": "4.0.2",
93
93
  "postcss-custom-media": "11.0.6",
94
- "@reshaped/utilities": "3.10.0-canary.5"
94
+ "@reshaped/utilities": "3.10.0-canary.6"
95
95
  },
96
96
  "scripts": {
97
97
  "clean": "bash ./bin/clean.sh",