-
-
Notifications
You must be signed in to change notification settings - Fork 300
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(divider): Update useVerticalDividerHeight to support any HTMLEle…
…ment
- Loading branch information
Showing
6 changed files
with
155 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
packages/divider/src/__tests__/__snapshots__/VerticalDivider.tsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`VerticalDivider should render as a div with the vertical divider class names 1`] = ` | ||
<div> | ||
<div | ||
class="rmd-divider rmd-divider--vertical" | ||
role="separator" | ||
style="height: 0px;" | ||
/> | ||
</div> | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { act, renderHook } from "@testing-library/react-hooks"; | ||
|
||
import { useVerticalDividerHeight } from "../useVerticalDividerHeight"; | ||
|
||
describe("useVerticalDivider", () => { | ||
it("should update the height value after the ref is called with an element", () => { | ||
const div = document.createElement("div"); | ||
const parentDiv = document.createElement("div"); | ||
parentDiv.appendChild(div); | ||
Object.defineProperty(parentDiv, "offsetHeight", { value: 100 }); | ||
|
||
const { result } = renderHook(() => | ||
useVerticalDividerHeight({ maxHeight: 1 }) | ||
); | ||
expect(result.current.style?.height).toBeUndefined(); | ||
|
||
act(() => result.current.ref(div)); | ||
expect(result.current.style?.height).toBe(100); | ||
}); | ||
|
||
it("should use the maxHeight as a multiplier if it is less than 1", () => { | ||
const div = document.createElement("div"); | ||
const parentDiv = document.createElement("div"); | ||
parentDiv.appendChild(div); | ||
Object.defineProperty(parentDiv, "offsetHeight", { value: 100 }); | ||
|
||
const { result } = renderHook(() => | ||
useVerticalDividerHeight({ maxHeight: 0.6 }) | ||
); | ||
expect(result.current.style?.height).toBeUndefined(); | ||
|
||
act(() => result.current.ref(div)); | ||
expect(result.current.style?.height).toBe(60); | ||
}); | ||
|
||
it("should use the maxHeight as a pixel value if it is greater than 1", () => { | ||
const div = document.createElement("div"); | ||
const parentDiv = document.createElement("div"); | ||
parentDiv.appendChild(div); | ||
Object.defineProperty(parentDiv, "offsetHeight", { | ||
value: 100, | ||
writable: true, | ||
}); | ||
|
||
const { result } = renderHook(() => | ||
useVerticalDividerHeight({ maxHeight: 80 }) | ||
); | ||
expect(result.current.style?.height).toBeUndefined(); | ||
|
||
act(() => result.current.ref(div)); | ||
expect(result.current.style?.height).toBe(80); | ||
|
||
Object.defineProperty(parentDiv, "offsetHeight", { | ||
value: 40, | ||
writable: true, | ||
}); | ||
act(() => result.current.ref(div)); | ||
expect(result.current.style?.height).toBe(40); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { CSSProperties, Ref, RefCallback, useCallback, useState } from "react"; | ||
import { applyRef } from "@react-md/utils"; | ||
|
||
/** @remarks \@since 5.0.0 */ | ||
export interface VerticalDividerHookOptions<E extends HTMLElement> { | ||
/** | ||
* An optional ref to merge with the returned ref. | ||
*/ | ||
ref?: Ref<E>; | ||
|
||
/** | ||
* An optional style object to merge with the divider's height style. | ||
*/ | ||
style?: CSSProperties; | ||
|
||
/** | ||
* The max height for the vertical divider. When this is `<= 0`, the hook will | ||
* be disabled. | ||
* | ||
* When the value is between 0 and 1, it will be used as a multiplier with the | ||
* parent element's height. When the value is greater than 1, it will be used | ||
* in `Math.min(parentElementHeight, maxHeight)`. | ||
*/ | ||
maxHeight: number; | ||
} | ||
|
||
/** @remarks \@since 5.0.0 */ | ||
export interface VerticalDividerHeight<E extends HTMLElement> { | ||
ref: RefCallback<E>; | ||
style: CSSProperties | undefined; | ||
} | ||
|
||
/** | ||
* This is a small hook that is used to automatically create a vertical divider | ||
* based on the computed height of its parent element. | ||
* | ||
* @param maxHeight - The max height for the vertical divider. When the value is | ||
* between 0 and 1, it will be used as a percentage. Otherwise the smaller value | ||
* of parent element height and this will be used. | ||
* @remarks \@since 5.0.0 The hook accepts an object instead of using multiple | ||
* params and uses a generic for the HTMLElement type. | ||
*/ | ||
export function useVerticalDividerHeight<E extends HTMLElement>({ | ||
ref, | ||
style, | ||
maxHeight, | ||
}: VerticalDividerHookOptions<E>): VerticalDividerHeight<E> { | ||
const [height, setHeight] = useState<number | undefined>(undefined); | ||
const refCallback = useCallback( | ||
(instance: E | null) => { | ||
applyRef(instance, ref); | ||
if (!instance || !instance.parentElement || maxHeight === 0) { | ||
return; | ||
} | ||
|
||
const height = instance.parentElement.offsetHeight; | ||
if (maxHeight <= 1) { | ||
setHeight(height * maxHeight); | ||
} else { | ||
setHeight(Math.min(height, maxHeight)); | ||
} | ||
}, | ||
[maxHeight, ref] | ||
); | ||
|
||
return { | ||
ref: refCallback, | ||
style: maxHeight <= 0 ? style : { ...style, height }, | ||
}; | ||
} |
edd9287
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs: