-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
826cb9a
commit 70dfb38
Showing
7 changed files
with
269 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
Copyright 2023 New Vector Ltd | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
.icon-button { | ||
--cpd-icon-button-indicator-border-size: calc( | ||
var(--cpd-icon-button-size) * 0.0625 | ||
); | ||
|
||
width: var(--cpd-icon-button-size); | ||
padding: calc(var(--cpd-icon-button-size) * 0.125); | ||
aspect-ratio: 1 / 1; | ||
color: var(--cpd-color-icon-tertiary); | ||
border: 0; | ||
appearance: none; | ||
cursor: pointer; | ||
border-radius: 50%; | ||
position: relative; | ||
background: transparent; | ||
line-height: 0; | ||
} | ||
|
||
.icon-button:disabled { | ||
color: var(--cpd-color-icon-disabled); | ||
cursor: not-allowed; | ||
} | ||
|
||
.icon-button svg { | ||
width: 100%; | ||
height: 100%; | ||
} | ||
|
||
.icon-button[data-indicator] svg { | ||
mask-image: url("./indicator-mask.svg"); | ||
mask-position: center center; | ||
mask-repeat: no-repeat; | ||
mask-size: calc(var(--cpd-icon-button-size) * 0.75); | ||
} | ||
|
||
.icon-button[data-indicator]::before { | ||
content: ""; | ||
position: absolute; | ||
top: var(--cpd-icon-button-indicator-border-size); | ||
right: var(--cpd-icon-button-indicator-border-size); | ||
width: calc(var(--cpd-icon-button-size) * 0.25); | ||
height: calc(var(--cpd-icon-button-size) * 0.25); | ||
border-radius: 50%; | ||
background: currentColor; | ||
} | ||
|
||
.icon-button[data-indicator="highlight"]::before { | ||
background: var(--cpd-color-icon-success-primary); | ||
} | ||
|
||
/** | ||
* Hover state | ||
*/ | ||
|
||
.icon-button:hover { | ||
color: var(--cpd-color-icon-primary); | ||
background: var(--cpd-color-bg-subtle-primary); | ||
} | ||
|
||
.icon-button[data-indicator]:is(:hover)::before { | ||
/* Same colour as the background */ | ||
border: var(--cpd-icon-button-indicator-border-size) solid | ||
var(--cpd-color-bg-subtle-primary); | ||
top: 0; | ||
right: 0; | ||
} |
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,58 @@ | ||
/* | ||
Copyright 2023 New Vector Ltd | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
import React from "react"; | ||
import { Meta, StoryFn } from "@storybook/react"; | ||
|
||
import { IconButton as IconButtonComponent } from "./IconButton"; | ||
|
||
import UserIcon from "@vector-im/compound-design-tokens/icons/user.svg"; | ||
|
||
export default { | ||
title: "IconButton", | ||
component: IconButtonComponent, | ||
argTypes: {}, | ||
args: {}, | ||
} as Meta<typeof IconButtonComponent>; | ||
|
||
const Template: StoryFn<typeof IconButtonComponent> = (args) => ( | ||
<> | ||
<IconButtonComponent {...args} size="32px"> | ||
<UserIcon /> | ||
</IconButtonComponent> | ||
|
||
<IconButtonComponent {...args} size="48px"> | ||
<UserIcon /> | ||
</IconButtonComponent> | ||
|
||
<IconButtonComponent {...args} size="64px"> | ||
<UserIcon /> | ||
</IconButtonComponent> | ||
</> | ||
); | ||
|
||
export const Normal = Template.bind({}); | ||
Normal.args = {}; | ||
|
||
export const WithIndicator = Template.bind({}); | ||
WithIndicator.args = { | ||
indicator: "default", | ||
}; | ||
|
||
export const WithHighlightIndicator = Template.bind({}); | ||
WithHighlightIndicator.args = { | ||
indicator: "highlight", | ||
}; |
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,34 @@ | ||
/* | ||
Copyright 2023 New Vector Ltd | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
import { describe, it, expect } from "vitest"; | ||
import { render } from "@testing-library/react"; | ||
import React from "react"; | ||
|
||
import { IconButton } from "./IconButton"; | ||
|
||
import UserIcon from "@vector-im/compound-design-tokens/icons/user.svg"; | ||
|
||
describe("IconButton", () => { | ||
it("renders", () => { | ||
const { asFragment } = render( | ||
<IconButton> | ||
<UserIcon /> | ||
</IconButton>, | ||
); | ||
expect(asFragment()).toMatchSnapshot(); | ||
}); | ||
}); |
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,65 @@ | ||
/* | ||
Copyright 2023 New Vector Ltd | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
import React, { PropsWithChildren, forwardRef } from "react"; | ||
import classnames from "classnames"; | ||
|
||
import styles from "./IconButton.module.css"; | ||
|
||
type IconButtonProps = JSX.IntrinsicElements["button"] & { | ||
/** | ||
* The CSS class name. | ||
*/ | ||
className?: string; | ||
/** | ||
* The avatar size in CSS units, e.g. `"24px"`. | ||
* @default 32px | ||
*/ | ||
size?: CSSStyleDeclaration["height"]; | ||
/** | ||
* The icon button indicator displayed on the top right | ||
*/ | ||
indicator?: "default" | "highlight"; | ||
}; | ||
|
||
/** | ||
* Display an icon as a button. Can render an indicator | ||
*/ | ||
export const IconButton = forwardRef< | ||
HTMLButtonElement, | ||
PropsWithChildren<IconButtonProps> | ||
>(function IconButton( | ||
{ children, className, indicator, size = "32px", style, ...props }, | ||
ref, | ||
) { | ||
const classes = classnames(styles["icon-button"], className); | ||
return ( | ||
<button | ||
ref={ref} | ||
className={classes} | ||
style={ | ||
{ | ||
"--cpd-icon-button-size": size, | ||
...style, | ||
} as React.CSSProperties | ||
} | ||
{...props} | ||
data-indicator={indicator} | ||
> | ||
{React.Children.only(children)} | ||
</button> | ||
); | ||
}); |
26 changes: 26 additions & 0 deletions
26
src/components/IconButton/__snapshots__/IconButton.test.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,26 @@ | ||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html | ||
|
||
exports[`IconButton > renders 1`] = ` | ||
<DocumentFragment> | ||
<button | ||
class="_icon-button_1d4528" | ||
style="--cpd-icon-button-size: 32px;" | ||
> | ||
<svg | ||
class="cpd-icon" | ||
fill="currentColor" | ||
height="1em" | ||
viewBox="0 0 24 24" | ||
width="1em" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path | ||
d="m5.84 17.108.008.01.01-.008a10.422 10.422 0 0 1 2.846-1.536A9.725 9.725 0 0 1 12 15.012c1.149 0 2.247.188 3.296.562a10.42 10.42 0 0 1 2.846 1.536l.01.007.008-.009a7.742 7.742 0 0 0 1.364-2.329A7.85 7.85 0 0 0 20.012 12c0-2.22-.78-4.11-2.34-5.671C16.11 4.768 14.22 3.988 12 3.988c-2.22 0-4.11.78-5.671 2.34C4.768 7.89 3.988 9.78 3.988 12c0 .985.162 1.911.488 2.78.325.867.78 1.644 1.364 2.328Zm6.16-4.12c-.98 0-1.806-.337-2.479-1.01-.672-.672-1.009-1.498-1.009-2.478 0-.98.337-1.806 1.01-2.479.672-.672 1.498-1.008 2.478-1.008.98 0 1.806.336 2.479 1.008.672.673 1.009 1.499 1.009 2.479s-.337 1.806-1.01 2.479c-.672.672-1.498 1.009-2.478 1.009Zm0 9a9.725 9.725 0 0 1-3.895-.787 10.087 10.087 0 0 1-3.171-2.135 10.087 10.087 0 0 1-2.135-3.171A9.725 9.725 0 0 1 2.013 12c0-1.382.262-2.68.786-3.895a10.086 10.086 0 0 1 2.135-3.171 10.086 10.086 0 0 1 3.171-2.135A9.725 9.725 0 0 1 12 2.013c1.382 0 2.68.262 3.895.786a10.087 10.087 0 0 1 3.171 2.135c.899.899 1.61 1.956 2.135 3.171A9.725 9.725 0 0 1 21.988 12a9.73 9.73 0 0 1-.787 3.895 10.087 10.087 0 0 1-2.135 3.171 10.087 10.087 0 0 1-3.171 2.135 9.725 9.725 0 0 1-3.895.787Z" | ||
fill="currentColor" | ||
stroke="currentColor" | ||
stroke-width="0.025" | ||
/> | ||
</svg> | ||
</button> | ||
</DocumentFragment> | ||
`; |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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