diff --git a/frontend/src/app/main/ui/ds.cljs b/frontend/src/app/main/ui/ds.cljs index 85268cf8d..c9848fb71 100644 --- a/frontend/src/app/main/ui/ds.cljs +++ b/frontend/src/app/main/ui/ds.cljs @@ -14,6 +14,7 @@ [app.main.ui.ds.foundations.typography :refer [typography-list]] [app.main.ui.ds.foundations.typography.heading :refer [heading*]] [app.main.ui.ds.foundations.typography.text :refer [text*]] + [app.main.ui.ds.notifications.toast :refer [toast*]] [app.main.ui.ds.product.loader :refer [loader*]] [app.main.ui.ds.storybook :as sb])) @@ -27,6 +28,7 @@ :Loader loader* :RawSvg raw-svg* :Text text* + :Toast toast* ;; meta / misc :meta #js {:icons (clj->js (sort icon-list)) :svgs (clj->js (sort raw-svg-list)) diff --git a/frontend/src/app/main/ui/ds/_borders.scss b/frontend/src/app/main/ui/ds/_borders.scss index a424603d1..e8a856074 100644 --- a/frontend/src/app/main/ui/ds/_borders.scss +++ b/frontend/src/app/main/ui/ds/_borders.scss @@ -8,5 +8,6 @@ // TODO: create actual tokens once we have them from design $br-8: px2rem(8); +$br-circle: 50%; $b-1: px2rem(1); diff --git a/frontend/src/app/main/ui/ds/_sizes.scss b/frontend/src/app/main/ui/ds/_sizes.scss index f27838b6a..5752bc10c 100644 --- a/frontend/src/app/main/ui/ds/_sizes.scss +++ b/frontend/src/app/main/ui/ds/_sizes.scss @@ -7,4 +7,6 @@ @use "./utils.scss" as *; // TODO: create actual tokens once we have them from design +$sz-16: px2rem(16); $sz-32: px2rem(32); +$sz-224: px2rem(224); diff --git a/frontend/src/app/main/ui/ds/notifications/toast.cljs b/frontend/src/app/main/ui/ds/notifications/toast.cljs new file mode 100644 index 000000000..343ec6fc5 --- /dev/null +++ b/frontend/src/app/main/ui/ds/notifications/toast.cljs @@ -0,0 +1,41 @@ +;; 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 + +(ns app.main.ui.ds.notifications.toast + (:require-macros + [app.common.data.macros :as dm] + [app.main.style :as stl]) + (:require + [app.main.ui.ds.foundations.assets.icon :as i] + [rumext.v2 :as mf])) + +(def levels (set '("info" "warning" "error" "success"))) + +(def ^:private icons-by-level + {"info" i/help + "warning" i/msg-neutral + "error" i/delete-text + "success" i/status-tick}) + +(mf/defc toast* + {::mf/props :obj} + [{:keys [class level children on-close] :rest props}] + (assert (or (nil? level) (contains? levels level)) "expected valid level or nil") + (assert (or (nil? on-close) (fn? on-close))) + (let [class (dm/str (stl/css-case :toast true + :toast-info (= level "info") + :toast-warning (= level "warning") + :toast-error (= level "error") + :toast-success (= level "success")) " " class) + icon-id (or (get icons-by-level level) i/msg-neutral) + props (mf/spread-props props {:class class})] + [:> "aside" props + [:* + [:> i/icon* {:id icon-id :class (stl/css :icon)}] + children + ;; TODO: this should be a buttom from the DS, but this variant is not designed yet. + ;; https://tree.taiga.io/project/penpot/task/8492 + [:> "button" {:on-click on-close :aria-label "Close" :class (stl/css :close-button)} [:> i/icon* {:id i/close}]]]])) \ No newline at end of file diff --git a/frontend/src/app/main/ui/ds/notifications/toast.scss b/frontend/src/app/main/ui/ds/notifications/toast.scss new file mode 100644 index 000000000..8aec8b198 --- /dev/null +++ b/frontend/src/app/main/ui/ds/notifications/toast.scss @@ -0,0 +1,75 @@ +// 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 "../_sizes.scss" as *; +@use "../_borders.scss" as *; +@use "../typography.scss" as *; + +.toast { + @include use-typography("body-small"); + + --toast-bg-color: var(--color-background-primary); + --toast-fg-color: var(--color-foreground-primary); + --toast-border-color: var(--color-background-quaternary); + --toast-icon-color: var(--color-foreground-secondary); + + min-width: $sz-224; + height: $sz-32; + background-color: var(--toast-bg-color); + border: $b-1 solid var(--toast-border-color); + border-radius: $br-8; + padding: 0 var(--sp-s); + + display: inline-grid; + grid-template-columns: auto 1fr auto; + column-gap: var(--sp-s); + align-items: center; + + color: var(--toast-fg-color); +} + +.toast-info { + --toast-bg-color: var(--color-background-info); + --toast-fg-color: var(--color-foreground-primary); + --toast-border-color: var(--color-accent-info); + --toast-icon-color: var(--color-accent-info); +} + +.toast-error { + --toast-bg-color: var(--color-background-error); + --toast-fg-color: var(--color-foreground-primary); + --toast-border-color: var(--color-accent-error); + --toast-icon-color: var(--color-accent-error); +} + +.toast-warning { + --toast-bg-color: var(--color-background-warning); + --toast-fg-color: var(--color-foreground-primary); + --toast-border-color: var(--color-accent-warning); + --toast-icon-color: var(--color-accent-warning); +} + +.toast-success { + --toast-bg-color: var(--color-background-success); + --toast-fg-color: var(--color-foreground-primary); + --toast-border-color: var(--color-accent-success); + --toast-icon-color: var(--color-accent-success); +} + +.icon { + color: var(--toast-icon-color); +} + +.close-button { + appearance: none; + width: $sz-16; + height: $sz-16; + display: inline-grid; + place-content: center; + border: none; + background: var(--toast-bg-color); + color: var(--toast-icon-color); +} diff --git a/frontend/src/app/main/ui/ds/notifications/toast.stories.jsx b/frontend/src/app/main/ui/ds/notifications/toast.stories.jsx new file mode 100644 index 000000000..34e835b9a --- /dev/null +++ b/frontend/src/app/main/ui/ds/notifications/toast.stories.jsx @@ -0,0 +1,78 @@ +// 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 * as React from "react"; +import Components from "@target/components"; + +const { Toast } = Components; +const { icons } = Components.meta; + +export default { + title: "Notifications/Toast", + component: Toast, + argTypes: { + children: { + control: { type: "text" }, + }, + }, + args: { + children: "Lorem ipsum", + onClose: () => { + alert("Close callback"); + }, + }, + parameters: { + controls: { + exclude: ["onClose"], + }, + }, + render: ({ ...args }) => , +}; + +export const Default = {}; + +export const WithLongerText = { + args: { + children: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent lorem ante, bibendum sed ex.", + }, +}; + +export const Info = { + args: { + level: "info", + }, + parameters: { + controls: { exclude: ["level", "onClose"] }, + }, +}; + +export const Error = { + args: { + level: "error", + }, + parameters: { + controls: { exclude: ["level", "onClose"] }, + }, +}; + +export const Warning = { + args: { + level: "warning", + }, + parameters: { + controls: { exclude: ["level", "onClose"] }, + }, +}; + +export const Success = { + args: { + level: "success", + }, + parameters: { + controls: { exclude: ["level", "onClose"] }, + }, +};