@sproutsocial/seeds-react-collapsible 1.0.0 → 1.0.2

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.
@@ -8,14 +8,14 @@ CLI Target: es2022
8
8
  CLI Cleaning output folder
9
9
  CJS Build start
10
10
  ESM Build start
11
- ESM dist/esm/index.js 4.68 KB
12
- ESM dist/esm/index.js.map 17.91 KB
13
- ESM ⚡️ Build success in 223ms
14
- CJS dist/index.js 6.58 KB
15
- CJS dist/index.js.map 17.90 KB
16
- CJS ⚡️ Build success in 254ms
11
+ ESM dist/esm/index.js 3.92 KB
12
+ ESM dist/esm/index.js.map 8.89 KB
13
+ ESM ⚡️ Build success in 158ms
14
+ CJS dist/index.js 5.92 KB
15
+ CJS dist/index.js.map 8.98 KB
16
+ CJS ⚡️ Build success in 170ms
17
17
  DTS Build start
18
- DTS ⚡️ Build success in 15193ms
19
- DTS dist/index.d.ts 1.03 KB
20
- DTS dist/index.d.mts 1.03 KB
21
- Done in 18.99s.
18
+ DTS ⚡️ Build success in 40024ms
19
+ DTS dist/index.d.ts 1.28 KB
20
+ DTS dist/index.d.mts 1.28 KB
21
+ Done in 48.21s.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @sproutsocial/seeds-react-collapsible
2
2
 
3
+ ## 1.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 9fd8bac: Update dependencies to use semantic package version instead of wildcards
8
+ - Updated dependencies [9fd8bac]
9
+ - @sproutsocial/seeds-react-hooks@3.0.2
10
+ - @sproutsocial/seeds-react-box@1.1.2
11
+
12
+ ## 1.0.1
13
+
14
+ ### Patch Changes
15
+
16
+ - 753d7c9: Fix various ts issues for Menu.Item, Collapsible, and VisuallyHidden
17
+
3
18
  ## 1.0.0
4
19
 
5
20
  ### Major Changes
package/dist/esm/index.js CHANGED
@@ -1,29 +1,7 @@
1
1
  // src/Collapsible.tsx
2
2
  import * as React from "react";
3
- import { useState as useState2, useRef as useRef2, useContext, useEffect as useEffect2 } from "react";
4
-
5
- // ../seeds-react-hooks/dist/index.mjs
6
- import { useState, useLayoutEffect, useCallback, useReducer, useRef, useEffect, useMemo } from "react";
7
- import { useTheme } from "styled-components";
8
- var v = Object.freeze({ x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 });
9
- function q(r) {
10
- let [t, e] = useState(v);
11
- return useLayoutEffect(() => {
12
- if (!r.current || !("ResizeObserver" in window))
13
- return;
14
- let n = new ResizeObserver(([o]) => {
15
- if (!o)
16
- return;
17
- let { x: u, y: a, width: i, height: f, top: m, right: b, bottom: d, left: y } = o.contentRect;
18
- e({ x: u, y: a, width: i, height: f, top: m, right: b, bottom: d, left: y });
19
- });
20
- return n.observe(r.current), () => {
21
- n.disconnect();
22
- };
23
- }, [r]), t;
24
- }
25
-
26
- // src/Collapsible.tsx
3
+ import { useState, useRef, useContext, useEffect } from "react";
4
+ import { useMeasure } from "@sproutsocial/seeds-react-hooks";
27
5
  import Box2 from "@sproutsocial/seeds-react-box";
28
6
 
29
7
  // src/styles.ts
@@ -69,7 +47,7 @@ var Collapsible = ({
69
47
  collapsedHeight = 0,
70
48
  openHeight
71
49
  }) => {
72
- const [id] = useState2(`Racine-collapsible-${idCounter++}`);
50
+ const [id] = useState(`Racine-collapsible-${idCounter++}`);
73
51
  return /* @__PURE__ */ jsx(
74
52
  CollapsibleContext.Provider,
75
53
  {
@@ -85,10 +63,8 @@ var Collapsible = ({
85
63
  );
86
64
  };
87
65
  var determineMaxHeight = (isHidden, openHeight, computedHeight) => {
88
- if (isHidden === void 0)
89
- return void 0;
90
- if (openHeight)
91
- return openHeight;
66
+ if (isHidden === void 0) return void 0;
67
+ if (openHeight) return openHeight;
92
68
  return computedHeight;
93
69
  };
94
70
  var Trigger = ({ children, ...rest }) => {
@@ -108,16 +84,16 @@ var Panel = ({ children, ...rest }) => {
108
84
  collapsedHeight,
109
85
  openHeight
110
86
  } = useContext(CollapsibleContext);
111
- const ref = useRef2(null);
112
- const measurement = q(ref);
113
- const [isHidden, setIsHidden] = useState2(void 0);
87
+ const ref = useRef(null);
88
+ const measurement = useMeasure(ref);
89
+ const [isHidden, setIsHidden] = useState(void 0);
114
90
  const maxHeight = determineMaxHeight(
115
91
  isHidden,
116
92
  openHeight,
117
93
  // Round up to the nearest pixel to prevent subpixel rendering issues
118
94
  Math.ceil(measurement.height + offset)
119
95
  );
120
- useEffect2(() => {
96
+ useEffect(() => {
121
97
  if (!isOpen) {
122
98
  const timeoutID = setTimeout(() => setIsHidden(!isOpen), 300);
123
99
  return () => clearTimeout(timeoutID);
@@ -159,9 +135,9 @@ var Collapsible_default = Collapsible;
159
135
  import "react";
160
136
 
161
137
  // src/index.ts
162
- var src_default = Collapsible_default;
138
+ var index_default = Collapsible_default;
163
139
  export {
164
140
  Collapsible_default as Collapsible,
165
- src_default as default
141
+ index_default as default
166
142
  };
167
143
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Collapsible.tsx","../../../seeds-react-hooks/src/useMeasure/useMeasure.ts","../../../seeds-react-hooks/src/useSelect/useSelect.ts","../../../seeds-react-hooks/src/useMultiselect/useMultiselect.ts","../../../seeds-react-hooks/src/useMutationObserver/useMutationObserver.ts","../../../seeds-react-hooks/src/useTextContent/useTextContent.ts","../../../seeds-react-hooks/src/useWhyDidYouUpdate/useWhyDidYouUpdate.ts","../../../seeds-react-hooks/src/useInteractiveColor/useInteractiveColor.ts","../../src/styles.ts","../../src/CollapsibleTypes.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\nimport { useState, useRef, useContext, useEffect } from \"react\";\nimport { useMeasure } from \"@sproutsocial/seeds-react-hooks\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport { CollapsingBox } from \"./styles\";\nimport type { TypeCollapsibleProps } from \"./CollapsibleTypes\";\n\nlet idCounter = 0;\n\ninterface TypeCollapsibleContext {\n isOpen?: boolean;\n id?: string;\n offset?: number;\n openHeight?: number;\n collapsedHeight?: number;\n}\n\nconst CollapsibleContext = React.createContext<TypeCollapsibleContext>({});\n\nconst Collapsible = ({\n children,\n isOpen = false,\n offset = 0,\n collapsedHeight = 0,\n openHeight,\n}: TypeCollapsibleProps) => {\n const [id] = useState(`Racine-collapsible-${idCounter++}`);\n return (\n <CollapsibleContext.Provider\n value={{\n isOpen,\n id,\n offset,\n collapsedHeight,\n openHeight,\n }}\n >\n {children}\n </CollapsibleContext.Provider>\n );\n};\n\nconst determineMaxHeight = (\n isHidden?: boolean,\n openHeight?: number,\n computedHeight?: number\n): number | undefined => {\n // If isHidden is undefined this is the first render. Return undefined so the max-height prop is not added\n // This is a hack to prevent css from animating if it begins in the open state\n // css animates when attribute values change (IE from 0 to another number)\n // css does not animate when simply adding an attribute to an HTML element\n if (isHidden === undefined) return undefined;\n // If the user has defined an explicit open height, return that as the max height\n if (openHeight) return openHeight;\n // Otherwise, fallback to the computed height\n return computedHeight;\n};\n\nconst Trigger = ({ children, ...rest }: { children: React.ReactElement }) => {\n const { isOpen, id } = useContext(CollapsibleContext);\n return (\n <React.Fragment>\n {React.cloneElement(children, {\n \"aria-controls\": id,\n \"aria-expanded\": !!isOpen,\n ...rest,\n })}\n </React.Fragment>\n );\n};\n\nTrigger.displayName = \"Collapsible.Trigger\";\n\nconst Panel = ({ children, ...rest }: { children: React.ReactNode }) => {\n const {\n isOpen,\n id,\n offset = 0,\n collapsedHeight,\n openHeight,\n } = useContext(CollapsibleContext);\n\n const ref = useRef<HTMLDivElement | null>(null);\n const measurement = useMeasure(ref);\n const [isHidden, setIsHidden] = useState<boolean | undefined>(undefined);\n const maxHeight = determineMaxHeight(\n isHidden,\n openHeight,\n // Round up to the nearest pixel to prevent subpixel rendering issues\n Math.ceil(measurement.height + offset)\n );\n\n /* We use the \"hidden\" attribute to remove the contents of the panel from the tab order of the page, but it interferes with the animation. This logic sets a slight timeout on setting the prop so that the animation has time to complete before the attribute is set. */\n useEffect(() => {\n if (!isOpen) {\n const timeoutID = setTimeout(() => setIsHidden(!isOpen), 300);\n return () => clearTimeout(timeoutID);\n } else {\n // Similar to the close animation, we need to delay setting hidden to run slightly async.\n // An issue occurs with the initial render isHidden logic that causes the animation to occur sporadically.\n // using this 0 second timeout just allows this component to initially render with an undefined max height,\n // Then go directly from undefined to the full max height, without a brief 0 value that triggers an animation\n const timeoutID = setTimeout(() => setIsHidden(!isOpen), 0);\n return () => clearTimeout(timeoutID);\n }\n }, [isOpen]);\n\n return (\n <CollapsingBox\n hasShadow={Boolean(collapsedHeight || (openHeight && openHeight > 0))}\n scrollable={isOpen}\n maxHeight={isOpen ? maxHeight : collapsedHeight}\n minHeight={collapsedHeight}\n data-qa-collapsible=\"\"\n data-qa-collapsible-isopen={isOpen === true}\n {...rest}\n >\n <Box\n width=\"100%\"\n hidden={isHidden && collapsedHeight === 0}\n aria-hidden={!isOpen}\n id={id}\n ref={ref}\n >\n {children}\n </Box>\n </CollapsingBox>\n );\n};\n\nPanel.displayName = \"Collapsible.Panel\";\n\nCollapsible.Trigger = Trigger;\nCollapsible.Panel = Panel;\n\nexport default Collapsible;\n","import { useState, useLayoutEffect, type RefObject } from \"react\";\n\ninterface DOMRectObject {\n x: number;\n y: number;\n width: number;\n height: number;\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\nconst initialBounds = Object.freeze({\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n});\n\nexport function useMeasure<TElement extends Element>(ref: RefObject<TElement>) {\n const [bounds, setContentRect] =\n useState<Readonly<DOMRectObject>>(initialBounds);\n\n useLayoutEffect(() => {\n const element = ref.current;\n\n if (\n !element ||\n // in non-browser environments (e.g. Jest tests) ResizeObserver is not defined\n !(\"ResizeObserver\" in window)\n ) {\n return;\n }\n\n const resizeObserver = new ResizeObserver(([entry]) => {\n if (!entry) return;\n const { x, y, width, height, top, right, bottom, left } =\n entry.contentRect;\n setContentRect({\n x,\n y,\n width,\n height,\n top,\n right,\n bottom,\n left,\n });\n });\n resizeObserver.observe(ref.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [ref]);\n\n return bounds;\n}\n","import { useState, useCallback } from \"react\";\n\ntype TypeSingleSelectProps<T extends string> = {\n initialValue?: T | \"\";\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onChange?: (value: string | T) => any;\n};\n\nexport const useSelect = <T extends string>(\n {\n initialValue = \"\",\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: userOnChange = () => {},\n }: TypeSingleSelectProps<T> = {\n initialValue: \"\",\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: () => {},\n }\n) => {\n const [value, setValue] = useState<string | T>(initialValue);\n\n const onChange = useCallback(\n (newValue: string) => {\n if (newValue !== value) {\n setValue(newValue);\n userOnChange(newValue);\n }\n },\n [userOnChange, value]\n );\n\n return { value, onChange };\n};\n","import { useCallback, useEffect, useReducer, useRef } from \"react\";\n\ntype TypeMultiSelectProps<T extends string> = {\n initialValue?: T[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onChange?: (value: Array<string | T>) => any;\n};\n\nconst valueReducer = (\n state: Set<string>,\n action: { type: string; value?: string }\n): Set<string> => {\n const newState = new Set(state);\n switch (action.type) {\n case \"reset\": {\n return new Set();\n }\n case \"toggle_item\":\n default: {\n if (action.value) {\n if (newState.has(action.value)) {\n newState.delete(action.value);\n } else {\n newState.add(action.value);\n }\n }\n return newState;\n }\n }\n};\n\nexport const useMultiselect = <T extends string>(\n {\n initialValue = [],\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: userOnChange = () => {},\n }: TypeMultiSelectProps<T> = {\n initialValue: [],\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: () => {},\n }\n) => {\n const [value, dispatch] = useReducer(valueReducer, new Set(initialValue));\n\n const getArrayValue = (value: Set<string | T>) =>\n Array.from<string | T>(value);\n\n const onChange = useCallback(\n (newValue: string) => {\n dispatch({ type: \"toggle_item\", value: newValue });\n },\n [dispatch]\n );\n\n const isFirstRun = useRef(true);\n\n useEffect(() => {\n if (isFirstRun.current) {\n isFirstRun.current = false;\n return;\n }\n userOnChange(getArrayValue(value));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [userOnChange, value]);\n\n const onClear = useCallback(() => {\n dispatch({ type: \"reset\" });\n }, [dispatch]);\n\n return { value: getArrayValue(value), onChange, onClear };\n};\n","import { canUseDOM } from \"@sproutsocial/seeds-react-utilities\";\nimport { useEffect, useMemo, useState } from \"react\";\n\ntype TypeMutationObserverInitRequired =\n | {\n childList: true;\n }\n | {\n attributes: true;\n }\n | {\n characterData: true;\n };\n\ntype TypeMutationObserverInit = {\n subtree?: boolean;\n attributeOldValue?: boolean;\n characterDataOldValue?: boolean;\n attributeFilter?: Array<string>;\n} & TypeMutationObserverInitRequired;\n\ntype TypeMutationObserverCallback = (\n mutationList?: MutationRecord[],\n observer?: MutationObserver\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n) => any;\n\nconst defaultCallback: TypeMutationObserverCallback = (mutationList) =>\n mutationList;\n\nexport function useMutationObserver(\n targetNode: Node | null,\n config: TypeMutationObserverInit,\n callback: TypeMutationObserverCallback = defaultCallback\n) {\n if (!canUseDOM()) {\n return;\n }\n /* eslint-disable-next-line */\n const [value, setValue] = useState(undefined);\n /* eslint-disable-next-line */\n const observer = useMemo(\n () =>\n new MutationObserver((mutationList, observer) => {\n const result = callback(mutationList, observer);\n setValue(result);\n }),\n [callback]\n );\n /* eslint-disable-next-line */\n useEffect(() => {\n if (targetNode) {\n observer.observe(targetNode, config);\n return () => {\n observer.disconnect();\n };\n }\n }, [targetNode, config, observer]);\n\n return value;\n}\n\nexport function useMutationObserverOnce(\n targetNode: Node | null,\n config: TypeMutationObserverInit,\n callback: TypeMutationObserverCallback\n) {\n const [isObserving, setObserving] = useState(true);\n const node = isObserving ? targetNode : null;\n const value = useMutationObserver(node, config, callback);\n if (value !== undefined && isObserving) {\n setObserving(false);\n }\n return value;\n}\n","import { useCallback, useState } from \"react\";\n\nexport type textContentRef = ((node: Node) => void) & { current?: string };\nexport function useTextContent(initial: string) {\n const [textContent, setTextContent] = useState(initial);\n\n const ref: textContentRef = useCallback((node: Node) => {\n if (node && node.textContent !== null) {\n setTextContent(node.textContent);\n }\n }, []);\n\n ref.current = textContent;\n return ref;\n}\n","import { useRef, useEffect } from \"react\";\n\nexport function useWhyDidYouUpdate(\n name: string,\n props: { [key: string]: any }\n) {\n // Get a mutable ref object where we can store props ...\n // ... for comparison next time this hook runs.\n const previousProps = useRef<typeof props>({});\n\n useEffect(() => {\n if (previousProps.current) {\n // Get all keys from previous and current props\n const allKeys = Object.keys({ ...previousProps.current, ...props });\n // Use this object to keep track of changed props\n const changesObj: typeof props = {};\n // Iterate through keys\n allKeys.forEach((key) => {\n // If previous is different from current\n\n if (previousProps.current[key] !== props[key]) {\n // Add to changesObj\n\n changesObj[key] = {\n from: previousProps.current[key],\n\n to: props[key],\n };\n }\n });\n\n // If changesObj not empty then output to console\n if (Object.keys(changesObj).length) {\n // eslint-disable-next-line no-console\n console.log(\"[why-did-you-update]\", name, changesObj);\n }\n }\n\n // Finally update previousProps with current props for next hook call\n previousProps.current = props;\n });\n}\n","import { darken, lighten } from \"polished\";\nimport { useTheme } from \"styled-components\";\nimport type { TypeTheme } from \"@sproutsocial/seeds-react-theme\";\n\n/**\n * The useInteractiveColor hook has context of theme mode (light or dark)\n * and can be used to lighten or darken a color dynamically\n *\n * note: colors are limited to our theme colors\n */\nconst useInteractiveColor = (themeColor: string): string => {\n // Throw error if used outside of a ThemeProvider (styled-components)\n if (!useTheme()) {\n throw new Error(\n \"useInteractiveColor() must be used within a Styled Components ThemeProvider\"\n );\n }\n\n // Get the current theme mode ie. 'light' or 'dark'\n const theme: TypeTheme = useTheme() as TypeTheme;\n const themeMode = theme.mode;\n\n // If the theme mode is dark, return a lightened version of the themeValue\n if (themeMode === \"dark\") {\n return lighten(0.2, themeColor);\n } else {\n // If the theme mode is light, return a darkened version of the themeValue\n return darken(0.2, themeColor);\n }\n};\n\nexport { useInteractiveColor };\n","import styled from \"styled-components\";\nimport Box from \"@sproutsocial/seeds-react-box\";\n\nexport const CollapsingBox = styled(Box)<{\n hasShadow?: boolean;\n scrollable?: boolean;\n}>`\n transition: max-height ${(p) => p.theme.duration.medium}\n ${(p) => p.theme.easing.ease_inout};\n will-change: max-height;\n position: relative;\n overflow: auto;\n ${({ hasShadow, scrollable }) =>\n hasShadow\n ? `background: /* Shadow covers */ linear-gradient(\n transparent 30%,\n rgba(255, 255, 255, 0)\n ),\n linear-gradient(rgba(255, 255, 255, 0), transparent 70%) 0 100%,\n /* Shadows */\n radial-gradient(\n farthest-side at 50% 0,\n rgb(39 51 51 / 5%),\n rgba(0, 0, 0, 0)\n ),\n radial-gradient(\n farthest-side at 50% 100%,\n rgb(39 51 51 / 5%),\n rgba(0, 0, 0, 0)\n )\n 0 100%;\n background-repeat: no-repeat;\n background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;\n background-attachment: local, local, scroll, scroll;\n ${scrollable ? `overflow: auto` : `overflow: hidden`};`\n : \"\"}\n`;\n","import * as React from \"react\";\n\n// The flow type is inexact but the underlying component does not accept any other props.\n// It might be worth extending the box props here for the refactor, but allowing it would provide no functionality right now.\nexport interface TypeCollapsibleProps {\n isOpen: boolean;\n children: React.ReactNode;\n\n /** If the children of the collapsible panel have a top or bottom margin, it will throw off the calculations for the height of the content. The total amount of vertical margin (in pixels) can be supplied to this prop to correct this. */\n offset?: number;\n collapsedHeight?: number;\n openHeight?: number;\n}\n","import Collapsible from \"./Collapsible\";\n\nexport default Collapsible;\nexport { Collapsible };\nexport * from \"./CollapsibleTypes\";\n"],"mappings":"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","names":["useState","useRef","useEffect","useState","Box","useState","useRef","useEffect","Box"]}
1
+ {"version":3,"sources":["../../src/Collapsible.tsx","../../src/styles.ts","../../src/CollapsibleTypes.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\nimport { useState, useRef, useContext, useEffect } from \"react\";\nimport { useMeasure } from \"@sproutsocial/seeds-react-hooks\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport { CollapsingBox } from \"./styles\";\nimport type {\n TypeCollapsibleProps,\n TypeCollapsiblePanelProps,\n TypeCollapsibleTriggerProps,\n} from \"./CollapsibleTypes\";\n\nlet idCounter = 0;\n\ninterface TypeCollapsibleContext {\n isOpen?: boolean;\n id?: string;\n offset?: number;\n openHeight?: number;\n collapsedHeight?: number;\n}\n\nconst CollapsibleContext = React.createContext<TypeCollapsibleContext>({});\n\nconst Collapsible = ({\n children,\n isOpen = false,\n offset = 0,\n collapsedHeight = 0,\n openHeight,\n}: TypeCollapsibleProps) => {\n const [id] = useState(`Racine-collapsible-${idCounter++}`);\n return (\n <CollapsibleContext.Provider\n value={{\n isOpen,\n id,\n offset,\n collapsedHeight,\n openHeight,\n }}\n >\n {children}\n </CollapsibleContext.Provider>\n );\n};\n\nconst determineMaxHeight = (\n isHidden?: boolean,\n openHeight?: number,\n computedHeight?: number\n): number | undefined => {\n // If isHidden is undefined this is the first render. Return undefined so the max-height prop is not added\n // This is a hack to prevent css from animating if it begins in the open state\n // css animates when attribute values change (IE from 0 to another number)\n // css does not animate when simply adding an attribute to an HTML element\n if (isHidden === undefined) return undefined;\n // If the user has defined an explicit open height, return that as the max height\n if (openHeight) return openHeight;\n // Otherwise, fallback to the computed height\n return computedHeight;\n};\n\nconst Trigger = ({ children, ...rest }: TypeCollapsibleTriggerProps) => {\n const { isOpen, id } = useContext(CollapsibleContext);\n return (\n <React.Fragment>\n {React.cloneElement(children, {\n \"aria-controls\": id,\n \"aria-expanded\": !!isOpen,\n ...rest,\n })}\n </React.Fragment>\n );\n};\n\nTrigger.displayName = \"Collapsible.Trigger\";\n\nconst Panel = ({ children, ...rest }: TypeCollapsiblePanelProps) => {\n const {\n isOpen,\n id,\n offset = 0,\n collapsedHeight,\n openHeight,\n } = useContext(CollapsibleContext);\n\n const ref = useRef<HTMLDivElement | null>(null);\n const measurement = useMeasure(ref);\n const [isHidden, setIsHidden] = useState<boolean | undefined>(undefined);\n const maxHeight = determineMaxHeight(\n isHidden,\n openHeight,\n // Round up to the nearest pixel to prevent subpixel rendering issues\n Math.ceil(measurement.height + offset)\n );\n\n /* We use the \"hidden\" attribute to remove the contents of the panel from the tab order of the page, but it interferes with the animation. This logic sets a slight timeout on setting the prop so that the animation has time to complete before the attribute is set. */\n useEffect(() => {\n if (!isOpen) {\n const timeoutID = setTimeout(() => setIsHidden(!isOpen), 300);\n return () => clearTimeout(timeoutID);\n } else {\n // Similar to the close animation, we need to delay setting hidden to run slightly async.\n // An issue occurs with the initial render isHidden logic that causes the animation to occur sporadically.\n // using this 0 second timeout just allows this component to initially render with an undefined max height,\n // Then go directly from undefined to the full max height, without a brief 0 value that triggers an animation\n const timeoutID = setTimeout(() => setIsHidden(!isOpen), 0);\n return () => clearTimeout(timeoutID);\n }\n }, [isOpen]);\n\n return (\n <CollapsingBox\n hasShadow={Boolean(collapsedHeight || (openHeight && openHeight > 0))}\n scrollable={isOpen}\n maxHeight={isOpen ? maxHeight : collapsedHeight}\n minHeight={collapsedHeight}\n data-qa-collapsible=\"\"\n data-qa-collapsible-isopen={isOpen === true}\n {...rest}\n >\n <Box\n width=\"100%\"\n hidden={isHidden && collapsedHeight === 0}\n aria-hidden={!isOpen}\n id={id}\n ref={ref}\n >\n {children}\n </Box>\n </CollapsingBox>\n );\n};\n\nPanel.displayName = \"Collapsible.Panel\";\n\nCollapsible.Trigger = Trigger;\nCollapsible.Panel = Panel;\n\nexport default Collapsible;\n","import styled from \"styled-components\";\nimport Box from \"@sproutsocial/seeds-react-box\";\n\nexport const CollapsingBox = styled(Box)<{\n hasShadow?: boolean;\n scrollable?: boolean;\n}>`\n transition: max-height ${(p) => p.theme.duration.medium}\n ${(p) => p.theme.easing.ease_inout};\n will-change: max-height;\n position: relative;\n overflow: auto;\n ${({ hasShadow, scrollable }) =>\n hasShadow\n ? `background: /* Shadow covers */ linear-gradient(\n transparent 30%,\n rgba(255, 255, 255, 0)\n ),\n linear-gradient(rgba(255, 255, 255, 0), transparent 70%) 0 100%,\n /* Shadows */\n radial-gradient(\n farthest-side at 50% 0,\n rgb(39 51 51 / 5%),\n rgba(0, 0, 0, 0)\n ),\n radial-gradient(\n farthest-side at 50% 100%,\n rgb(39 51 51 / 5%),\n rgba(0, 0, 0, 0)\n )\n 0 100%;\n background-repeat: no-repeat;\n background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;\n background-attachment: local, local, scroll, scroll;\n ${scrollable ? `overflow: auto` : `overflow: hidden`};`\n : \"\"}\n`;\n","import * as React from \"react\";\nimport type { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\n\n// The flow type is inexact but the underlying component does not accept any other props.\n// It might be worth extending the box props here for the refactor, but allowing it would provide no functionality right now.\nexport interface TypeCollapsibleProps {\n isOpen: boolean;\n children: React.ReactNode;\n\n /** If the children of the collapsible panel have a top or bottom margin, it will throw off the calculations for the height of the content. The total amount of vertical margin (in pixels) can be supplied to this prop to correct this. */\n offset?: number;\n collapsedHeight?: number;\n openHeight?: number;\n}\n\nexport interface TypeCollapsibleTriggerProps\n extends Omit<TypeBoxProps, \"children\"> {\n // Children is required for the Trigger\n children: React.ReactElement;\n}\n\nexport interface TypeCollapsiblePanelProps extends TypeBoxProps {}\n","import Collapsible from \"./Collapsible\";\n\nexport default Collapsible;\nexport { Collapsible };\nexport * from \"./CollapsibleTypes\";\n"],"mappings":"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","names":["Box","Box"]}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
+ import { TypeBoxProps } from '@sproutsocial/seeds-react-box';
3
4
 
4
5
  interface TypeCollapsibleProps {
5
6
  isOpen: boolean;
@@ -9,21 +10,22 @@ interface TypeCollapsibleProps {
9
10
  collapsedHeight?: number;
10
11
  openHeight?: number;
11
12
  }
13
+ interface TypeCollapsibleTriggerProps extends Omit<TypeBoxProps, "children"> {
14
+ children: React.ReactElement;
15
+ }
16
+ interface TypeCollapsiblePanelProps extends TypeBoxProps {
17
+ }
12
18
 
13
19
  declare const Collapsible: {
14
20
  ({ children, isOpen, offset, collapsedHeight, openHeight, }: TypeCollapsibleProps): react_jsx_runtime.JSX.Element;
15
21
  Trigger: {
16
- ({ children, ...rest }: {
17
- children: React.ReactElement;
18
- }): react_jsx_runtime.JSX.Element;
22
+ ({ children, ...rest }: TypeCollapsibleTriggerProps): react_jsx_runtime.JSX.Element;
19
23
  displayName: string;
20
24
  };
21
25
  Panel: {
22
- ({ children, ...rest }: {
23
- children: React.ReactNode;
24
- }): react_jsx_runtime.JSX.Element;
26
+ ({ children, ...rest }: TypeCollapsiblePanelProps): react_jsx_runtime.JSX.Element;
25
27
  displayName: string;
26
28
  };
27
29
  };
28
30
 
29
- export { Collapsible, type TypeCollapsibleProps, Collapsible as default };
31
+ export { Collapsible, type TypeCollapsiblePanelProps, type TypeCollapsibleProps, type TypeCollapsibleTriggerProps, Collapsible as default };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
+ import { TypeBoxProps } from '@sproutsocial/seeds-react-box';
3
4
 
4
5
  interface TypeCollapsibleProps {
5
6
  isOpen: boolean;
@@ -9,21 +10,22 @@ interface TypeCollapsibleProps {
9
10
  collapsedHeight?: number;
10
11
  openHeight?: number;
11
12
  }
13
+ interface TypeCollapsibleTriggerProps extends Omit<TypeBoxProps, "children"> {
14
+ children: React.ReactElement;
15
+ }
16
+ interface TypeCollapsiblePanelProps extends TypeBoxProps {
17
+ }
12
18
 
13
19
  declare const Collapsible: {
14
20
  ({ children, isOpen, offset, collapsedHeight, openHeight, }: TypeCollapsibleProps): react_jsx_runtime.JSX.Element;
15
21
  Trigger: {
16
- ({ children, ...rest }: {
17
- children: React.ReactElement;
18
- }): react_jsx_runtime.JSX.Element;
22
+ ({ children, ...rest }: TypeCollapsibleTriggerProps): react_jsx_runtime.JSX.Element;
19
23
  displayName: string;
20
24
  };
21
25
  Panel: {
22
- ({ children, ...rest }: {
23
- children: React.ReactNode;
24
- }): react_jsx_runtime.JSX.Element;
26
+ ({ children, ...rest }: TypeCollapsiblePanelProps): react_jsx_runtime.JSX.Element;
25
27
  displayName: string;
26
28
  };
27
29
  };
28
30
 
29
- export { Collapsible, type TypeCollapsibleProps, Collapsible as default };
31
+ export { Collapsible, type TypeCollapsiblePanelProps, type TypeCollapsibleProps, type TypeCollapsibleTriggerProps, Collapsible as default };
package/dist/index.js CHANGED
@@ -28,45 +28,23 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
30
  // src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
33
  Collapsible: () => Collapsible_default,
34
- default: () => src_default
34
+ default: () => index_default
35
35
  });
36
- module.exports = __toCommonJS(src_exports);
36
+ module.exports = __toCommonJS(index_exports);
37
37
 
38
38
  // src/Collapsible.tsx
39
39
  var React = __toESM(require("react"));
40
- var import_react2 = require("react");
41
-
42
- // ../seeds-react-hooks/dist/index.mjs
43
40
  var import_react = require("react");
44
- var import_styled_components = require("styled-components");
45
- var v = Object.freeze({ x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 });
46
- function q(r) {
47
- let [t, e] = (0, import_react.useState)(v);
48
- return (0, import_react.useLayoutEffect)(() => {
49
- if (!r.current || !("ResizeObserver" in window))
50
- return;
51
- let n = new ResizeObserver(([o]) => {
52
- if (!o)
53
- return;
54
- let { x: u, y: a, width: i, height: f, top: m, right: b, bottom: d, left: y } = o.contentRect;
55
- e({ x: u, y: a, width: i, height: f, top: m, right: b, bottom: d, left: y });
56
- });
57
- return n.observe(r.current), () => {
58
- n.disconnect();
59
- };
60
- }, [r]), t;
61
- }
62
-
63
- // src/Collapsible.tsx
41
+ var import_seeds_react_hooks = require("@sproutsocial/seeds-react-hooks");
64
42
  var import_seeds_react_box2 = __toESM(require("@sproutsocial/seeds-react-box"));
65
43
 
66
44
  // src/styles.ts
67
- var import_styled_components2 = __toESM(require("styled-components"));
45
+ var import_styled_components = __toESM(require("styled-components"));
68
46
  var import_seeds_react_box = __toESM(require("@sproutsocial/seeds-react-box"));
69
- var CollapsingBox = (0, import_styled_components2.default)(import_seeds_react_box.default)`
47
+ var CollapsingBox = (0, import_styled_components.default)(import_seeds_react_box.default)`
70
48
  transition: max-height ${(p) => p.theme.duration.medium}
71
49
  ${(p) => p.theme.easing.ease_inout};
72
50
  will-change: max-height;
@@ -106,7 +84,7 @@ var Collapsible = ({
106
84
  collapsedHeight = 0,
107
85
  openHeight
108
86
  }) => {
109
- const [id] = (0, import_react2.useState)(`Racine-collapsible-${idCounter++}`);
87
+ const [id] = (0, import_react.useState)(`Racine-collapsible-${idCounter++}`);
110
88
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
111
89
  CollapsibleContext.Provider,
112
90
  {
@@ -122,14 +100,12 @@ var Collapsible = ({
122
100
  );
123
101
  };
124
102
  var determineMaxHeight = (isHidden, openHeight, computedHeight) => {
125
- if (isHidden === void 0)
126
- return void 0;
127
- if (openHeight)
128
- return openHeight;
103
+ if (isHidden === void 0) return void 0;
104
+ if (openHeight) return openHeight;
129
105
  return computedHeight;
130
106
  };
131
107
  var Trigger = ({ children, ...rest }) => {
132
- const { isOpen, id } = (0, import_react2.useContext)(CollapsibleContext);
108
+ const { isOpen, id } = (0, import_react.useContext)(CollapsibleContext);
133
109
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(React.Fragment, { children: React.cloneElement(children, {
134
110
  "aria-controls": id,
135
111
  "aria-expanded": !!isOpen,
@@ -144,17 +120,17 @@ var Panel = ({ children, ...rest }) => {
144
120
  offset = 0,
145
121
  collapsedHeight,
146
122
  openHeight
147
- } = (0, import_react2.useContext)(CollapsibleContext);
148
- const ref = (0, import_react2.useRef)(null);
149
- const measurement = q(ref);
150
- const [isHidden, setIsHidden] = (0, import_react2.useState)(void 0);
123
+ } = (0, import_react.useContext)(CollapsibleContext);
124
+ const ref = (0, import_react.useRef)(null);
125
+ const measurement = (0, import_seeds_react_hooks.useMeasure)(ref);
126
+ const [isHidden, setIsHidden] = (0, import_react.useState)(void 0);
151
127
  const maxHeight = determineMaxHeight(
152
128
  isHidden,
153
129
  openHeight,
154
130
  // Round up to the nearest pixel to prevent subpixel rendering issues
155
131
  Math.ceil(measurement.height + offset)
156
132
  );
157
- (0, import_react2.useEffect)(() => {
133
+ (0, import_react.useEffect)(() => {
158
134
  if (!isOpen) {
159
135
  const timeoutID = setTimeout(() => setIsHidden(!isOpen), 300);
160
136
  return () => clearTimeout(timeoutID);
@@ -196,7 +172,7 @@ var Collapsible_default = Collapsible;
196
172
  var React2 = require("react");
197
173
 
198
174
  // src/index.ts
199
- var src_default = Collapsible_default;
175
+ var index_default = Collapsible_default;
200
176
  // Annotate the CommonJS export names for ESM import in node:
201
177
  0 && (module.exports = {
202
178
  Collapsible
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Collapsible.tsx","../../seeds-react-hooks/src/useMeasure/useMeasure.ts","../../seeds-react-hooks/src/useSelect/useSelect.ts","../../seeds-react-hooks/src/useMultiselect/useMultiselect.ts","../../seeds-react-hooks/src/useMutationObserver/useMutationObserver.ts","../../seeds-react-hooks/src/useTextContent/useTextContent.ts","../../seeds-react-hooks/src/useWhyDidYouUpdate/useWhyDidYouUpdate.ts","../../seeds-react-hooks/src/useInteractiveColor/useInteractiveColor.ts","../src/styles.ts","../src/CollapsibleTypes.ts"],"sourcesContent":["import Collapsible from \"./Collapsible\";\n\nexport default Collapsible;\nexport { Collapsible };\nexport * from \"./CollapsibleTypes\";\n","import * as React from \"react\";\nimport { useState, useRef, useContext, useEffect } from \"react\";\nimport { useMeasure } from \"@sproutsocial/seeds-react-hooks\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport { CollapsingBox } from \"./styles\";\nimport type { TypeCollapsibleProps } from \"./CollapsibleTypes\";\n\nlet idCounter = 0;\n\ninterface TypeCollapsibleContext {\n isOpen?: boolean;\n id?: string;\n offset?: number;\n openHeight?: number;\n collapsedHeight?: number;\n}\n\nconst CollapsibleContext = React.createContext<TypeCollapsibleContext>({});\n\nconst Collapsible = ({\n children,\n isOpen = false,\n offset = 0,\n collapsedHeight = 0,\n openHeight,\n}: TypeCollapsibleProps) => {\n const [id] = useState(`Racine-collapsible-${idCounter++}`);\n return (\n <CollapsibleContext.Provider\n value={{\n isOpen,\n id,\n offset,\n collapsedHeight,\n openHeight,\n }}\n >\n {children}\n </CollapsibleContext.Provider>\n );\n};\n\nconst determineMaxHeight = (\n isHidden?: boolean,\n openHeight?: number,\n computedHeight?: number\n): number | undefined => {\n // If isHidden is undefined this is the first render. Return undefined so the max-height prop is not added\n // This is a hack to prevent css from animating if it begins in the open state\n // css animates when attribute values change (IE from 0 to another number)\n // css does not animate when simply adding an attribute to an HTML element\n if (isHidden === undefined) return undefined;\n // If the user has defined an explicit open height, return that as the max height\n if (openHeight) return openHeight;\n // Otherwise, fallback to the computed height\n return computedHeight;\n};\n\nconst Trigger = ({ children, ...rest }: { children: React.ReactElement }) => {\n const { isOpen, id } = useContext(CollapsibleContext);\n return (\n <React.Fragment>\n {React.cloneElement(children, {\n \"aria-controls\": id,\n \"aria-expanded\": !!isOpen,\n ...rest,\n })}\n </React.Fragment>\n );\n};\n\nTrigger.displayName = \"Collapsible.Trigger\";\n\nconst Panel = ({ children, ...rest }: { children: React.ReactNode }) => {\n const {\n isOpen,\n id,\n offset = 0,\n collapsedHeight,\n openHeight,\n } = useContext(CollapsibleContext);\n\n const ref = useRef<HTMLDivElement | null>(null);\n const measurement = useMeasure(ref);\n const [isHidden, setIsHidden] = useState<boolean | undefined>(undefined);\n const maxHeight = determineMaxHeight(\n isHidden,\n openHeight,\n // Round up to the nearest pixel to prevent subpixel rendering issues\n Math.ceil(measurement.height + offset)\n );\n\n /* We use the \"hidden\" attribute to remove the contents of the panel from the tab order of the page, but it interferes with the animation. This logic sets a slight timeout on setting the prop so that the animation has time to complete before the attribute is set. */\n useEffect(() => {\n if (!isOpen) {\n const timeoutID = setTimeout(() => setIsHidden(!isOpen), 300);\n return () => clearTimeout(timeoutID);\n } else {\n // Similar to the close animation, we need to delay setting hidden to run slightly async.\n // An issue occurs with the initial render isHidden logic that causes the animation to occur sporadically.\n // using this 0 second timeout just allows this component to initially render with an undefined max height,\n // Then go directly from undefined to the full max height, without a brief 0 value that triggers an animation\n const timeoutID = setTimeout(() => setIsHidden(!isOpen), 0);\n return () => clearTimeout(timeoutID);\n }\n }, [isOpen]);\n\n return (\n <CollapsingBox\n hasShadow={Boolean(collapsedHeight || (openHeight && openHeight > 0))}\n scrollable={isOpen}\n maxHeight={isOpen ? maxHeight : collapsedHeight}\n minHeight={collapsedHeight}\n data-qa-collapsible=\"\"\n data-qa-collapsible-isopen={isOpen === true}\n {...rest}\n >\n <Box\n width=\"100%\"\n hidden={isHidden && collapsedHeight === 0}\n aria-hidden={!isOpen}\n id={id}\n ref={ref}\n >\n {children}\n </Box>\n </CollapsingBox>\n );\n};\n\nPanel.displayName = \"Collapsible.Panel\";\n\nCollapsible.Trigger = Trigger;\nCollapsible.Panel = Panel;\n\nexport default Collapsible;\n","import { useState, useLayoutEffect, type RefObject } from \"react\";\n\ninterface DOMRectObject {\n x: number;\n y: number;\n width: number;\n height: number;\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\nconst initialBounds = Object.freeze({\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n});\n\nexport function useMeasure<TElement extends Element>(ref: RefObject<TElement>) {\n const [bounds, setContentRect] =\n useState<Readonly<DOMRectObject>>(initialBounds);\n\n useLayoutEffect(() => {\n const element = ref.current;\n\n if (\n !element ||\n // in non-browser environments (e.g. Jest tests) ResizeObserver is not defined\n !(\"ResizeObserver\" in window)\n ) {\n return;\n }\n\n const resizeObserver = new ResizeObserver(([entry]) => {\n if (!entry) return;\n const { x, y, width, height, top, right, bottom, left } =\n entry.contentRect;\n setContentRect({\n x,\n y,\n width,\n height,\n top,\n right,\n bottom,\n left,\n });\n });\n resizeObserver.observe(ref.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [ref]);\n\n return bounds;\n}\n","import { useState, useCallback } from \"react\";\n\ntype TypeSingleSelectProps<T extends string> = {\n initialValue?: T | \"\";\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onChange?: (value: string | T) => any;\n};\n\nexport const useSelect = <T extends string>(\n {\n initialValue = \"\",\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: userOnChange = () => {},\n }: TypeSingleSelectProps<T> = {\n initialValue: \"\",\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: () => {},\n }\n) => {\n const [value, setValue] = useState<string | T>(initialValue);\n\n const onChange = useCallback(\n (newValue: string) => {\n if (newValue !== value) {\n setValue(newValue);\n userOnChange(newValue);\n }\n },\n [userOnChange, value]\n );\n\n return { value, onChange };\n};\n","import { useCallback, useEffect, useReducer, useRef } from \"react\";\n\ntype TypeMultiSelectProps<T extends string> = {\n initialValue?: T[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onChange?: (value: Array<string | T>) => any;\n};\n\nconst valueReducer = (\n state: Set<string>,\n action: { type: string; value?: string }\n): Set<string> => {\n const newState = new Set(state);\n switch (action.type) {\n case \"reset\": {\n return new Set();\n }\n case \"toggle_item\":\n default: {\n if (action.value) {\n if (newState.has(action.value)) {\n newState.delete(action.value);\n } else {\n newState.add(action.value);\n }\n }\n return newState;\n }\n }\n};\n\nexport const useMultiselect = <T extends string>(\n {\n initialValue = [],\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: userOnChange = () => {},\n }: TypeMultiSelectProps<T> = {\n initialValue: [],\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: () => {},\n }\n) => {\n const [value, dispatch] = useReducer(valueReducer, new Set(initialValue));\n\n const getArrayValue = (value: Set<string | T>) =>\n Array.from<string | T>(value);\n\n const onChange = useCallback(\n (newValue: string) => {\n dispatch({ type: \"toggle_item\", value: newValue });\n },\n [dispatch]\n );\n\n const isFirstRun = useRef(true);\n\n useEffect(() => {\n if (isFirstRun.current) {\n isFirstRun.current = false;\n return;\n }\n userOnChange(getArrayValue(value));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [userOnChange, value]);\n\n const onClear = useCallback(() => {\n dispatch({ type: \"reset\" });\n }, [dispatch]);\n\n return { value: getArrayValue(value), onChange, onClear };\n};\n","import { canUseDOM } from \"@sproutsocial/seeds-react-utilities\";\nimport { useEffect, useMemo, useState } from \"react\";\n\ntype TypeMutationObserverInitRequired =\n | {\n childList: true;\n }\n | {\n attributes: true;\n }\n | {\n characterData: true;\n };\n\ntype TypeMutationObserverInit = {\n subtree?: boolean;\n attributeOldValue?: boolean;\n characterDataOldValue?: boolean;\n attributeFilter?: Array<string>;\n} & TypeMutationObserverInitRequired;\n\ntype TypeMutationObserverCallback = (\n mutationList?: MutationRecord[],\n observer?: MutationObserver\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n) => any;\n\nconst defaultCallback: TypeMutationObserverCallback = (mutationList) =>\n mutationList;\n\nexport function useMutationObserver(\n targetNode: Node | null,\n config: TypeMutationObserverInit,\n callback: TypeMutationObserverCallback = defaultCallback\n) {\n if (!canUseDOM()) {\n return;\n }\n /* eslint-disable-next-line */\n const [value, setValue] = useState(undefined);\n /* eslint-disable-next-line */\n const observer = useMemo(\n () =>\n new MutationObserver((mutationList, observer) => {\n const result = callback(mutationList, observer);\n setValue(result);\n }),\n [callback]\n );\n /* eslint-disable-next-line */\n useEffect(() => {\n if (targetNode) {\n observer.observe(targetNode, config);\n return () => {\n observer.disconnect();\n };\n }\n }, [targetNode, config, observer]);\n\n return value;\n}\n\nexport function useMutationObserverOnce(\n targetNode: Node | null,\n config: TypeMutationObserverInit,\n callback: TypeMutationObserverCallback\n) {\n const [isObserving, setObserving] = useState(true);\n const node = isObserving ? targetNode : null;\n const value = useMutationObserver(node, config, callback);\n if (value !== undefined && isObserving) {\n setObserving(false);\n }\n return value;\n}\n","import { useCallback, useState } from \"react\";\n\nexport type textContentRef = ((node: Node) => void) & { current?: string };\nexport function useTextContent(initial: string) {\n const [textContent, setTextContent] = useState(initial);\n\n const ref: textContentRef = useCallback((node: Node) => {\n if (node && node.textContent !== null) {\n setTextContent(node.textContent);\n }\n }, []);\n\n ref.current = textContent;\n return ref;\n}\n","import { useRef, useEffect } from \"react\";\n\nexport function useWhyDidYouUpdate(\n name: string,\n props: { [key: string]: any }\n) {\n // Get a mutable ref object where we can store props ...\n // ... for comparison next time this hook runs.\n const previousProps = useRef<typeof props>({});\n\n useEffect(() => {\n if (previousProps.current) {\n // Get all keys from previous and current props\n const allKeys = Object.keys({ ...previousProps.current, ...props });\n // Use this object to keep track of changed props\n const changesObj: typeof props = {};\n // Iterate through keys\n allKeys.forEach((key) => {\n // If previous is different from current\n\n if (previousProps.current[key] !== props[key]) {\n // Add to changesObj\n\n changesObj[key] = {\n from: previousProps.current[key],\n\n to: props[key],\n };\n }\n });\n\n // If changesObj not empty then output to console\n if (Object.keys(changesObj).length) {\n // eslint-disable-next-line no-console\n console.log(\"[why-did-you-update]\", name, changesObj);\n }\n }\n\n // Finally update previousProps with current props for next hook call\n previousProps.current = props;\n });\n}\n","import { darken, lighten } from \"polished\";\nimport { useTheme } from \"styled-components\";\nimport type { TypeTheme } from \"@sproutsocial/seeds-react-theme\";\n\n/**\n * The useInteractiveColor hook has context of theme mode (light or dark)\n * and can be used to lighten or darken a color dynamically\n *\n * note: colors are limited to our theme colors\n */\nconst useInteractiveColor = (themeColor: string): string => {\n // Throw error if used outside of a ThemeProvider (styled-components)\n if (!useTheme()) {\n throw new Error(\n \"useInteractiveColor() must be used within a Styled Components ThemeProvider\"\n );\n }\n\n // Get the current theme mode ie. 'light' or 'dark'\n const theme: TypeTheme = useTheme() as TypeTheme;\n const themeMode = theme.mode;\n\n // If the theme mode is dark, return a lightened version of the themeValue\n if (themeMode === \"dark\") {\n return lighten(0.2, themeColor);\n } else {\n // If the theme mode is light, return a darkened version of the themeValue\n return darken(0.2, themeColor);\n }\n};\n\nexport { useInteractiveColor };\n","import styled from \"styled-components\";\nimport Box from \"@sproutsocial/seeds-react-box\";\n\nexport const CollapsingBox = styled(Box)<{\n hasShadow?: boolean;\n scrollable?: boolean;\n}>`\n transition: max-height ${(p) => p.theme.duration.medium}\n ${(p) => p.theme.easing.ease_inout};\n will-change: max-height;\n position: relative;\n overflow: auto;\n ${({ hasShadow, scrollable }) =>\n hasShadow\n ? `background: /* Shadow covers */ linear-gradient(\n transparent 30%,\n rgba(255, 255, 255, 0)\n ),\n linear-gradient(rgba(255, 255, 255, 0), transparent 70%) 0 100%,\n /* Shadows */\n radial-gradient(\n farthest-side at 50% 0,\n rgb(39 51 51 / 5%),\n rgba(0, 0, 0, 0)\n ),\n radial-gradient(\n farthest-side at 50% 100%,\n rgb(39 51 51 / 5%),\n rgba(0, 0, 0, 0)\n )\n 0 100%;\n background-repeat: no-repeat;\n background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;\n background-attachment: local, local, scroll, scroll;\n ${scrollable ? `overflow: auto` : `overflow: hidden`};`\n : \"\"}\n`;\n","import * as React from \"react\";\n\n// The flow type is inexact but the underlying component does not accept any other props.\n// It might be worth extending the box props here for the refactor, but allowing it would provide no functionality right now.\nexport interface TypeCollapsibleProps {\n isOpen: boolean;\n children: React.ReactNode;\n\n /** If the children of the collapsible panel have a top or bottom margin, it will throw off the calculations for the height of the content. The total amount of vertical margin (in pixels) can be supplied to this prop to correct this. */\n offset?: number;\n collapsedHeight?: number;\n openHeight?: number;\n}\n"],"mappings":"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","names":["import_react","import_seeds_react_box","import_styled_components","styled","Box","Box","React"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/Collapsible.tsx","../src/styles.ts","../src/CollapsibleTypes.ts"],"sourcesContent":["import Collapsible from \"./Collapsible\";\n\nexport default Collapsible;\nexport { Collapsible };\nexport * from \"./CollapsibleTypes\";\n","import * as React from \"react\";\nimport { useState, useRef, useContext, useEffect } from \"react\";\nimport { useMeasure } from \"@sproutsocial/seeds-react-hooks\";\nimport Box from \"@sproutsocial/seeds-react-box\";\nimport { CollapsingBox } from \"./styles\";\nimport type {\n TypeCollapsibleProps,\n TypeCollapsiblePanelProps,\n TypeCollapsibleTriggerProps,\n} from \"./CollapsibleTypes\";\n\nlet idCounter = 0;\n\ninterface TypeCollapsibleContext {\n isOpen?: boolean;\n id?: string;\n offset?: number;\n openHeight?: number;\n collapsedHeight?: number;\n}\n\nconst CollapsibleContext = React.createContext<TypeCollapsibleContext>({});\n\nconst Collapsible = ({\n children,\n isOpen = false,\n offset = 0,\n collapsedHeight = 0,\n openHeight,\n}: TypeCollapsibleProps) => {\n const [id] = useState(`Racine-collapsible-${idCounter++}`);\n return (\n <CollapsibleContext.Provider\n value={{\n isOpen,\n id,\n offset,\n collapsedHeight,\n openHeight,\n }}\n >\n {children}\n </CollapsibleContext.Provider>\n );\n};\n\nconst determineMaxHeight = (\n isHidden?: boolean,\n openHeight?: number,\n computedHeight?: number\n): number | undefined => {\n // If isHidden is undefined this is the first render. Return undefined so the max-height prop is not added\n // This is a hack to prevent css from animating if it begins in the open state\n // css animates when attribute values change (IE from 0 to another number)\n // css does not animate when simply adding an attribute to an HTML element\n if (isHidden === undefined) return undefined;\n // If the user has defined an explicit open height, return that as the max height\n if (openHeight) return openHeight;\n // Otherwise, fallback to the computed height\n return computedHeight;\n};\n\nconst Trigger = ({ children, ...rest }: TypeCollapsibleTriggerProps) => {\n const { isOpen, id } = useContext(CollapsibleContext);\n return (\n <React.Fragment>\n {React.cloneElement(children, {\n \"aria-controls\": id,\n \"aria-expanded\": !!isOpen,\n ...rest,\n })}\n </React.Fragment>\n );\n};\n\nTrigger.displayName = \"Collapsible.Trigger\";\n\nconst Panel = ({ children, ...rest }: TypeCollapsiblePanelProps) => {\n const {\n isOpen,\n id,\n offset = 0,\n collapsedHeight,\n openHeight,\n } = useContext(CollapsibleContext);\n\n const ref = useRef<HTMLDivElement | null>(null);\n const measurement = useMeasure(ref);\n const [isHidden, setIsHidden] = useState<boolean | undefined>(undefined);\n const maxHeight = determineMaxHeight(\n isHidden,\n openHeight,\n // Round up to the nearest pixel to prevent subpixel rendering issues\n Math.ceil(measurement.height + offset)\n );\n\n /* We use the \"hidden\" attribute to remove the contents of the panel from the tab order of the page, but it interferes with the animation. This logic sets a slight timeout on setting the prop so that the animation has time to complete before the attribute is set. */\n useEffect(() => {\n if (!isOpen) {\n const timeoutID = setTimeout(() => setIsHidden(!isOpen), 300);\n return () => clearTimeout(timeoutID);\n } else {\n // Similar to the close animation, we need to delay setting hidden to run slightly async.\n // An issue occurs with the initial render isHidden logic that causes the animation to occur sporadically.\n // using this 0 second timeout just allows this component to initially render with an undefined max height,\n // Then go directly from undefined to the full max height, without a brief 0 value that triggers an animation\n const timeoutID = setTimeout(() => setIsHidden(!isOpen), 0);\n return () => clearTimeout(timeoutID);\n }\n }, [isOpen]);\n\n return (\n <CollapsingBox\n hasShadow={Boolean(collapsedHeight || (openHeight && openHeight > 0))}\n scrollable={isOpen}\n maxHeight={isOpen ? maxHeight : collapsedHeight}\n minHeight={collapsedHeight}\n data-qa-collapsible=\"\"\n data-qa-collapsible-isopen={isOpen === true}\n {...rest}\n >\n <Box\n width=\"100%\"\n hidden={isHidden && collapsedHeight === 0}\n aria-hidden={!isOpen}\n id={id}\n ref={ref}\n >\n {children}\n </Box>\n </CollapsingBox>\n );\n};\n\nPanel.displayName = \"Collapsible.Panel\";\n\nCollapsible.Trigger = Trigger;\nCollapsible.Panel = Panel;\n\nexport default Collapsible;\n","import styled from \"styled-components\";\nimport Box from \"@sproutsocial/seeds-react-box\";\n\nexport const CollapsingBox = styled(Box)<{\n hasShadow?: boolean;\n scrollable?: boolean;\n}>`\n transition: max-height ${(p) => p.theme.duration.medium}\n ${(p) => p.theme.easing.ease_inout};\n will-change: max-height;\n position: relative;\n overflow: auto;\n ${({ hasShadow, scrollable }) =>\n hasShadow\n ? `background: /* Shadow covers */ linear-gradient(\n transparent 30%,\n rgba(255, 255, 255, 0)\n ),\n linear-gradient(rgba(255, 255, 255, 0), transparent 70%) 0 100%,\n /* Shadows */\n radial-gradient(\n farthest-side at 50% 0,\n rgb(39 51 51 / 5%),\n rgba(0, 0, 0, 0)\n ),\n radial-gradient(\n farthest-side at 50% 100%,\n rgb(39 51 51 / 5%),\n rgba(0, 0, 0, 0)\n )\n 0 100%;\n background-repeat: no-repeat;\n background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;\n background-attachment: local, local, scroll, scroll;\n ${scrollable ? `overflow: auto` : `overflow: hidden`};`\n : \"\"}\n`;\n","import * as React from \"react\";\nimport type { TypeBoxProps } from \"@sproutsocial/seeds-react-box\";\n\n// The flow type is inexact but the underlying component does not accept any other props.\n// It might be worth extending the box props here for the refactor, but allowing it would provide no functionality right now.\nexport interface TypeCollapsibleProps {\n isOpen: boolean;\n children: React.ReactNode;\n\n /** If the children of the collapsible panel have a top or bottom margin, it will throw off the calculations for the height of the content. The total amount of vertical margin (in pixels) can be supplied to this prop to correct this. */\n offset?: number;\n collapsedHeight?: number;\n openHeight?: number;\n}\n\nexport interface TypeCollapsibleTriggerProps\n extends Omit<TypeBoxProps, \"children\"> {\n // Children is required for the Trigger\n children: React.ReactElement;\n}\n\nexport interface TypeCollapsiblePanelProps extends TypeBoxProps {}\n"],"mappings":"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","names":["import_seeds_react_box","styled","Box","Box","React"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-collapsible",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Seeds React Collapsible",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
@@ -18,7 +18,8 @@
18
18
  "test:watch": "jest --watch --coverage=false"
19
19
  },
20
20
  "dependencies": {
21
- "@sproutsocial/seeds-react-box": "*"
21
+ "@sproutsocial/seeds-react-box": "^1.1.1",
22
+ "@sproutsocial/seeds-react-hooks": "^3.0.1"
22
23
  },
23
24
  "devDependencies": {
24
25
  "tsup": "^8.0.2",
@@ -30,7 +31,7 @@
30
31
  "@sproutsocial/seeds-tsconfig": "*",
31
32
  "@sproutsocial/seeds-testing": "*",
32
33
  "@sproutsocial/seeds-react-testing-library": "*",
33
- "@sproutsocial/seeds-react-button": "*"
34
+ "@sproutsocial/seeds-react-button": "^1.2.0"
34
35
  },
35
36
  "peerDependencies": {
36
37
  "styled-components": "^5.2.3"
@@ -3,7 +3,11 @@ import { useState, useRef, useContext, useEffect } from "react";
3
3
  import { useMeasure } from "@sproutsocial/seeds-react-hooks";
4
4
  import Box from "@sproutsocial/seeds-react-box";
5
5
  import { CollapsingBox } from "./styles";
6
- import type { TypeCollapsibleProps } from "./CollapsibleTypes";
6
+ import type {
7
+ TypeCollapsibleProps,
8
+ TypeCollapsiblePanelProps,
9
+ TypeCollapsibleTriggerProps,
10
+ } from "./CollapsibleTypes";
7
11
 
8
12
  let idCounter = 0;
9
13
 
@@ -56,7 +60,7 @@ const determineMaxHeight = (
56
60
  return computedHeight;
57
61
  };
58
62
 
59
- const Trigger = ({ children, ...rest }: { children: React.ReactElement }) => {
63
+ const Trigger = ({ children, ...rest }: TypeCollapsibleTriggerProps) => {
60
64
  const { isOpen, id } = useContext(CollapsibleContext);
61
65
  return (
62
66
  <React.Fragment>
@@ -71,7 +75,7 @@ const Trigger = ({ children, ...rest }: { children: React.ReactElement }) => {
71
75
 
72
76
  Trigger.displayName = "Collapsible.Trigger";
73
77
 
74
- const Panel = ({ children, ...rest }: { children: React.ReactNode }) => {
78
+ const Panel = ({ children, ...rest }: TypeCollapsiblePanelProps) => {
75
79
  const {
76
80
  isOpen,
77
81
  id,
@@ -1,4 +1,5 @@
1
1
  import * as React from "react";
2
+ import type { TypeBoxProps } from "@sproutsocial/seeds-react-box";
2
3
 
3
4
  // The flow type is inexact but the underlying component does not accept any other props.
4
5
  // It might be worth extending the box props here for the refactor, but allowing it would provide no functionality right now.
@@ -11,3 +12,11 @@ export interface TypeCollapsibleProps {
11
12
  collapsedHeight?: number;
12
13
  openHeight?: number;
13
14
  }
15
+
16
+ export interface TypeCollapsibleTriggerProps
17
+ extends Omit<TypeBoxProps, "children"> {
18
+ // Children is required for the Trigger
19
+ children: React.ReactElement;
20
+ }
21
+
22
+ export interface TypeCollapsiblePanelProps extends TypeBoxProps {}
@@ -7,7 +7,7 @@ import {
7
7
  } from "@sproutsocial/seeds-react-testing-library";
8
8
  import Box from "@sproutsocial/seeds-react-box";
9
9
  import Button from "@sproutsocial/seeds-react-button";
10
- import { Collapsible } from "../src";
10
+ import { Collapsible } from "../";
11
11
 
12
12
  export interface TypeStatefulCollapseTestProps {
13
13
  children: React.ReactNode;
@@ -2,7 +2,7 @@ import * as React from "react";
2
2
  import { render } from "@sproutsocial/seeds-react-testing-library";
3
3
  import Box from "@sproutsocial/seeds-react-box";
4
4
  import Button from "@sproutsocial/seeds-react-button";
5
- import { Collapsible } from "../src";
5
+ import { Collapsible } from "../";
6
6
 
7
7
  const toggle = jest.fn();
8
8