From 425a140a444b6191d6dcc6f26da3fc66662e5594 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 7 Apr 2026 20:40:42 +0000 Subject: [PATCH] :sparkles: Add IconButton component to @penpot/ui --- frontend/packages/ui/AGENTS.md | 7 +- frontend/packages/ui/src/index.ts | 5 + .../ui/src/lib/buttons/IconButton.module.scss | 50 ++++++++ .../ui/src/lib/buttons/IconButton.spec.tsx | 112 ++++++++++++++++++ .../ui/src/lib/buttons/IconButton.stories.tsx | 59 +++++++++ .../ui/src/lib/buttons/IconButton.tsx | 87 ++++++++++++++ 6 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 frontend/packages/ui/src/lib/buttons/IconButton.module.scss create mode 100644 frontend/packages/ui/src/lib/buttons/IconButton.spec.tsx create mode 100644 frontend/packages/ui/src/lib/buttons/IconButton.stories.tsx create mode 100644 frontend/packages/ui/src/lib/buttons/IconButton.tsx diff --git a/frontend/packages/ui/AGENTS.md b/frontend/packages/ui/AGENTS.md index b019c47ec4..529696d370 100644 --- a/frontend/packages/ui/AGENTS.md +++ b/frontend/packages/ui/AGENTS.md @@ -25,7 +25,11 @@ frontend/packages/ui/ │ │ ├── Button.tsx │ │ ├── Button.module.scss │ │ ├── Button.stories.tsx -│ │ └── Button.spec.tsx +│ │ ├── Button.spec.tsx +│ │ ├── IconButton.tsx +│ │ ├── IconButton.module.scss +│ │ ├── IconButton.stories.tsx +│ │ └── IconButton.spec.tsx │ ├── example/ # Example component (reference) │ ├── foundations/ │ │ ├── assets/ # Icon component @@ -54,6 +58,7 @@ Components are organised to mirror the CLJS source tree | `ds/foundations/assets/icon.cljs` | `src/lib/foundations/assets/Icon.tsx` | | `ds/product/cta.cljs` | `src/lib/product/Cta.tsx` | | `ds/buttons/button.cljs` | `src/lib/buttons/Button.tsx` | +| `ds/buttons/icon_button.cljs` | `src/lib/buttons/IconButton.tsx` | ### Known Tooling Notes diff --git a/frontend/packages/ui/src/index.ts b/frontend/packages/ui/src/index.ts index 065942d8dd..d483b274f1 100644 --- a/frontend/packages/ui/src/index.ts +++ b/frontend/packages/ui/src/index.ts @@ -15,3 +15,8 @@ export { Icon, iconIds } from "./lib/foundations/assets/Icon"; export type { IconId, IconProps } from "./lib/foundations/assets/Icon"; export { Button } from "./lib/buttons/Button"; export type { ButtonProps, ButtonVariant } from "./lib/buttons/Button"; +export { IconButton } from "./lib/buttons/IconButton"; +export type { + IconButtonProps, + IconButtonVariant, +} from "./lib/buttons/IconButton"; diff --git a/frontend/packages/ui/src/lib/buttons/IconButton.module.scss b/frontend/packages/ui/src/lib/buttons/IconButton.module.scss new file mode 100644 index 0000000000..baa78a1e83 --- /dev/null +++ b/frontend/packages/ui/src/lib/buttons/IconButton.module.scss @@ -0,0 +1,50 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) KALEIDOS INC + +@use "../_ds/_sizes.scss" as *; +@use "buttons" as *; + +.icon-button { + @extend %base-button; + + --button-width: #{$sz-32}; + --button-height: #{$sz-32}; + + display: grid; + place-content: center; +} + +.icon-button-primary { + @extend %base-button-primary; +} + +.icon-button-secondary { + @extend %base-button-secondary; +} + +.icon-button-ghost { + @extend %base-button-ghost; +} + +.icon-button-destructive { + @extend %base-button-destructive; +} + +.icon-button-action { + --button-bg-color: transparent; + --button-fg-color: var(--color-foreground-secondary); + --button-hover-bg-color: transparent; + --button-hover-fg-color: var(--color-accent-primary); + --button-active-bg-color: var(--color-background-quaternary); + --button-disabled-bg-color: transparent; + --button-disabled-fg-color: var(--color-accent-primary-muted); + --button-focus-bg-color: transparent; + --button-focus-fg-color: var(--color-accent-primary); + --button-focus-inner-ring-color: transparent; + --button-focus-outer-ring-color: var(--color-accent-primary); + --button-width: #{$sz-24}; + --button-height: #{$sz-24}; +} diff --git a/frontend/packages/ui/src/lib/buttons/IconButton.spec.tsx b/frontend/packages/ui/src/lib/buttons/IconButton.spec.tsx new file mode 100644 index 0000000000..cf1575af5c --- /dev/null +++ b/frontend/packages/ui/src/lib/buttons/IconButton.spec.tsx @@ -0,0 +1,112 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) KALEIDOS INC + +import { render, screen } from "@testing-library/react"; +import { IconButton } from "./IconButton"; + +describe("IconButton", () => { + it("should render successfully", () => { + const { baseElement } = render(); + expect(baseElement).toBeTruthy(); + }); + + it("renders a + ); +} + +export const IconButton = memo(IconButtonInner);