diff --git a/packages/components/src/components/Button/Button.module.scss b/packages/components/src/components/Button/Button.module.scss index 2902e840b..3da5afb77 100644 --- a/packages/components/src/components/Button/Button.module.scss +++ b/packages/components/src/components/Button/Button.module.scss @@ -1,5 +1,6 @@ @use "@/styles/mixins/ellipsis"; @use "@/styles/mixins/focus"; +@use "@/styles/mixins/avatarButton"; .button { position: relative; @@ -23,9 +24,7 @@ &:where(.outline) { border-width: var(--button--border-width); border-style: var(--button--border-style); - padding-block: calc( - var(--button--padding-y) - var(--button--border-width) - ); + padding-block: calc(var(--button--padding-y) - var(--button--border-width)); padding-inline: calc( var(--button--padding-x) - var(--button--border-width) ); @@ -54,16 +53,13 @@ justify-self: center; } - &:where(:has(.avatar)) { - padding: 0; - border-radius: var(--corner-radius--round); - } - &:where(:has(.icon):not(:has(.text))) { padding: var(--button--padding-icon-only); &:where(.outline) { - padding: calc(var(--button--padding-icon-only) - var(--button--border-width)); + padding: calc( + var(--button--padding-icon-only) - var(--button--border-width) + ); } } @@ -127,7 +123,9 @@ padding: var(--button--padding-s-icon-only); &:where(.outline) { - padding: calc(var(--button--padding-s-icon-only) - var(--button--border-width)); + padding: calc( + var(--button--padding-s-icon-only) - var(--button--border-width) + ); } } @@ -211,4 +209,6 @@ @include variant(secondary, outline); @include variant(dark, outline); @include variant(light, outline); + + @include avatarButton.avatarButton(); } diff --git a/packages/components/src/components/Button/stories/Default.stories.tsx b/packages/components/src/components/Button/stories/Default.stories.tsx index cd72dcd89..7d1434b4b 100644 --- a/packages/components/src/components/Button/stories/Default.stories.tsx +++ b/packages/components/src/components/Button/stories/Default.stories.tsx @@ -1,10 +1,15 @@ import type { Meta, StoryObj } from "@storybook/react"; import Button from "../Button"; import React from "react"; -import { IconPlus } from "@/components/Icon/components/icons"; +import { IconCamera, IconPlus } from "@/components/Icon/components/icons"; import { action } from "@storybook/addon-actions"; import { Text } from "@/components/Text"; import IconChevronDown from "@/components/Icon/components/icons/IconChevronDown"; +import { Avatar } from "@/components/Avatar"; +import { Tooltip } from "@/components/Tooltip"; +import TooltipTrigger from "@/components/Tooltip/components/TooltipTrigger"; +import { dummyText } from "@/lib/dev/dummyText"; +import { Image } from "@/components/Image"; const meta: Meta = { title: "Actions/Button", @@ -87,3 +92,17 @@ export const SmallWithTextAndIcon: Story = { size: "s", }, }; + +export const WithAvatar: Story = { + render: (props) => ( + + + Profilbild ändern + + ), +}; diff --git a/packages/components/src/components/MenuItem/MenuItemContent.tsx b/packages/components/src/components/MenuItem/MenuItemContent.tsx index da7dbcd8e..75420bc04 100644 --- a/packages/components/src/components/MenuItem/MenuItemContent.tsx +++ b/packages/components/src/components/MenuItem/MenuItemContent.tsx @@ -14,6 +14,7 @@ import { Text } from "@/components/Text"; import { deepHas } from "@/lib/react/deepHas"; import { Wrap } from "@/components/Wrap"; import clsx from "clsx"; +import { Avatar } from "@/components/Avatar"; interface Props extends Aria.MenuItemRenderProps, PropsWithChildren { selectionVariant?: "control" | "navigation"; @@ -34,6 +35,9 @@ export const MenuItemContent: FC = (props) => { Text: { className: styles.text, }, + Avatar: { + className: styles.avatar, + }, }; const controlIconPropsContext: PropsContext = { @@ -56,6 +60,7 @@ export const MenuItemContent: FC = (props) => { ); const hasText = deepHas(children, Text); + const hasAvatar = deepHas(children, Avatar); return ( <> @@ -63,7 +68,7 @@ export const MenuItemContent: FC = (props) => { {selectionIcon} - + {children} diff --git a/packages/components/src/styles/mixins/avatarButton.scss b/packages/components/src/styles/mixins/avatarButton.scss new file mode 100644 index 000000000..9974d9fd9 --- /dev/null +++ b/packages/components/src/styles/mixins/avatarButton.scss @@ -0,0 +1,39 @@ +@mixin avatarButton { + &:has(.avatar) { + padding: 0; + background: none; + width: fit-content; + position: relative; + border-radius: var(--corner-radius--round); + + .icon { + display: none; + position: absolute; + width: 70%; + height: 70%; + top: 15%; + left: 15%; + color: var(--image-button--hover-icon-color); + } + + &:hover { + .avatar { + filter: brightness(var(--image-button--brightness--hover)); + } + + .icon { + display: block; + } + } + + &[data-pressed] { + .avatar { + filter: brightness(var(--image-button--brightness--pressed)); + } + + .icon { + display: block; + } + } + } +} diff --git a/packages/components/src/styles/mixins/menuItem.scss b/packages/components/src/styles/mixins/menuItem.scss index dcc8d7e20..29e767336 100644 --- a/packages/components/src/styles/mixins/menuItem.scss +++ b/packages/components/src/styles/mixins/menuItem.scss @@ -1,4 +1,5 @@ @use "./focus"; +@use "./avatarButton"; @mixin menuItem { display: flex; @@ -65,4 +66,6 @@ background-color: var(--menu-item--disabled-background-color); color: var(--menu-item--disabled-color); } + + @include avatarButton.avatarButton(); } diff --git a/packages/design-tokens/src/actions/image-button.yml b/packages/design-tokens/src/actions/image-button.yml new file mode 100644 index 000000000..962c41c0d --- /dev/null +++ b/packages/design-tokens/src/actions/image-button.yml @@ -0,0 +1,8 @@ +image-button: + brightness: + hover: + value: 62.5% + pressed: + value: 50% + hover-icon-color: + value: "{color.gray.100}"