mirror of
https://github.com/penpot/penpot.git
synced 2025-05-22 07:16:10 +02:00
♻️ Create DS context notification component
This commit is contained in:
parent
a6c46ee55c
commit
26a2ef8fb7
10 changed files with 232 additions and 8 deletions
|
@ -21,6 +21,7 @@
|
||||||
[app.main.ui.ds.foundations.utilities.token.token-status :refer [token-status-icon* token-status-list]]
|
[app.main.ui.ds.foundations.utilities.token.token-status :refer [token-status-icon* token-status-list]]
|
||||||
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
|
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
|
||||||
[app.main.ui.ds.notifications.actionable :refer [actionable*]]
|
[app.main.ui.ds.notifications.actionable :refer [actionable*]]
|
||||||
|
[app.main.ui.ds.notifications.context-notification :refer [context-notification*]]
|
||||||
[app.main.ui.ds.notifications.shared.notification-pill :refer [notification-pill*]]
|
[app.main.ui.ds.notifications.shared.notification-pill :refer [notification-pill*]]
|
||||||
[app.main.ui.ds.notifications.toast :refer [toast*]]
|
[app.main.ui.ds.notifications.toast :refer [toast*]]
|
||||||
[app.main.ui.ds.product.autosaved-milestone :refer [autosaved-milestone*]]
|
[app.main.ui.ds.product.autosaved-milestone :refer [autosaved-milestone*]]
|
||||||
|
@ -55,6 +56,7 @@
|
||||||
:Text text*
|
:Text text*
|
||||||
:TabSwitcher tab-switcher*
|
:TabSwitcher tab-switcher*
|
||||||
:Toast toast*
|
:Toast toast*
|
||||||
|
:ContextNotification context-notification*
|
||||||
:NotificationPill notification-pill*
|
:NotificationPill notification-pill*
|
||||||
:Actionable actionable*
|
:Actionable actionable*
|
||||||
:TokenStatusIcon token-status-icon*
|
:TokenStatusIcon token-status-icon*
|
||||||
|
|
|
@ -27,4 +27,10 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: var(--actionable-padding);
|
padding: var(--actionable-padding);
|
||||||
padding-inline-start: var(--sp-l);
|
padding-inline-start: var(--sp-l);
|
||||||
|
|
||||||
|
// Targets the potential links included by the creator in the children props.
|
||||||
|
& a {
|
||||||
|
color: var(--color-accent-primary);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
// 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 { ContextNotification } = Components;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "Notifications/ContextNotification",
|
||||||
|
component: ContextNotification,
|
||||||
|
argTypes: {
|
||||||
|
children: {
|
||||||
|
control: { type: "text" },
|
||||||
|
},
|
||||||
|
appearance: {
|
||||||
|
options: ["neutral", "ghost"],
|
||||||
|
control: { type: "select" },
|
||||||
|
},
|
||||||
|
level: {
|
||||||
|
options: ["info", "error", "warning", "success"],
|
||||||
|
control: { type: "select" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
args: {
|
||||||
|
children: "Lorem ipsum",
|
||||||
|
isHtml: false,
|
||||||
|
type: "context",
|
||||||
|
appearance: "neutral",
|
||||||
|
level: "info",
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
controls: {
|
||||||
|
exclude: ["type", "isHtml"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
render: ({ ...args }) => <ContextNotification {...args} />,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Default = {};
|
||||||
|
|
||||||
|
export const WithLongerText = {
|
||||||
|
args: {
|
||||||
|
children:
|
||||||
|
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent lorem ante, bibendum sed ex.",
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
controls: { exclude: ["isHtml"] },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WithHTML = {
|
||||||
|
args: {
|
||||||
|
children:
|
||||||
|
"Lorem ipsum dolor sit amet, <marquee>consectetur adipiscing elit.</marquee> Praesent lorem ante, bibendum sed ex.",
|
||||||
|
isHtml: true,
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
controls: { exclude: ["isHtml"] },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Info = {
|
||||||
|
args: {
|
||||||
|
level: "info",
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
controls: { exclude: ["level", "isHtml"] },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Error = {
|
||||||
|
args: {
|
||||||
|
level: "error",
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
controls: { exclude: ["level", "isHtml"] },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Warning = {
|
||||||
|
args: {
|
||||||
|
level: "warning",
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
controls: { exclude: ["level", "isHtml"] },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Success = {
|
||||||
|
args: {
|
||||||
|
level: "success",
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
controls: { exclude: ["level", "isHtml"] },
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,53 @@
|
||||||
|
;; 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.context-notification
|
||||||
|
(:require-macros [app.main.style :as stl])
|
||||||
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.main.ui.ds.notifications.shared.notification-pill :refer [notification-pill*]]
|
||||||
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
(def ^:private schema:context-notification
|
||||||
|
[:map
|
||||||
|
[:class {:optional true} :string]
|
||||||
|
[:type {:optional true} [:maybe [:enum :toast :context]]]
|
||||||
|
[:appearance {:optional true} [:enum :neutral :ghost]]
|
||||||
|
[:level {:optional true} [:maybe [:enum :info :warning :error :success]]]
|
||||||
|
[:is-html {:optional true} :boolean]])
|
||||||
|
|
||||||
|
(mf/defc context-notification*
|
||||||
|
"Persistent notifications, they do not disappear.
|
||||||
|
These are contextual messages in specific areas of the tool, usually in modals and Dashboard area, and are mainly informative."
|
||||||
|
{::mf/props :obj
|
||||||
|
::mf/schema schema:context-notification}
|
||||||
|
[{:keys [class type appearance level is-html children] :rest props}]
|
||||||
|
(let [class (dm/str class " " (stl/css-case :contextual-notification true
|
||||||
|
:contain-html is-html
|
||||||
|
:level-warning (= level :warning)
|
||||||
|
:level-error (= level :error)
|
||||||
|
:level-success (= level :success)
|
||||||
|
:level-info (= level :info)))
|
||||||
|
level (if (string? level)
|
||||||
|
(keyword level)
|
||||||
|
(d/nilv level :info))
|
||||||
|
type (if (string? type)
|
||||||
|
(keyword type)
|
||||||
|
(d/nilv type :context))
|
||||||
|
appearance (if (string? appearance)
|
||||||
|
(keyword appearance)
|
||||||
|
(d/nilv appearance :neutral))
|
||||||
|
is-html (or is-html false)
|
||||||
|
props (mf/spread-props props {:class class
|
||||||
|
:role "alert"
|
||||||
|
:aria-live "polite"})]
|
||||||
|
[:> "aside" props
|
||||||
|
[:> notification-pill* {:level level
|
||||||
|
:type type
|
||||||
|
:is-html is-html
|
||||||
|
:appearance appearance} children]]))
|
||||||
|
|
|
@ -23,20 +23,31 @@
|
||||||
(def ^:private schema:notification-pill
|
(def ^:private schema:notification-pill
|
||||||
[:map
|
[:map
|
||||||
[:level [:enum :info :warning :error :success]]
|
[:level [:enum :info :warning :error :success]]
|
||||||
[:type [:enum :toast :context]]])
|
[:type [:enum :toast :context]]
|
||||||
|
[:appearance {:optional true} [:enum :neutral :ghost]]
|
||||||
|
[:is-html {:optional true} :boolean]])
|
||||||
|
|
||||||
(mf/defc notification-pill*
|
(mf/defc notification-pill*
|
||||||
{::mf/props :obj
|
{::mf/props :obj
|
||||||
::mf/schema schema:notification-pill}
|
::mf/schema schema:notification-pill}
|
||||||
[{:keys [level type children]}]
|
[{:keys [level type is-html appearance children]}]
|
||||||
(let [class (stl/css-case :notification-pill true
|
(let [class (stl/css-case :notification-pill true
|
||||||
|
:appearance-neutral (= appearance :neutral)
|
||||||
|
:appearance-ghost (= appearance :ghost)
|
||||||
:type-toast (= type :toast)
|
:type-toast (= type :toast)
|
||||||
:type-context (= type :context)
|
:type-context (= type :context)
|
||||||
:level-warning (= level :warning)
|
:level-warning (= level :warning)
|
||||||
:level-error (= level :error)
|
:level-error (= level :error)
|
||||||
:level-success (= level :success)
|
:level-success (= level :success)
|
||||||
:level-info (= level :info))
|
:level-info (= level :info))
|
||||||
|
is-html (or is-html false)
|
||||||
icon-id (icons-by-level level)]
|
icon-id (icons-by-level level)]
|
||||||
[:div {:class class}
|
[:div {:class class}
|
||||||
[:> i/icon* {:icon-id icon-id :class (stl/css :icon)}]
|
[:> i/icon* {:icon-id icon-id :class (stl/css :icon)}]
|
||||||
children]))
|
;; The content can arrive in markdown format, in these cases
|
||||||
|
;; we will use the prop is-html to true to indicate it and
|
||||||
|
;; that the html injection is performed and the necessary css classes are applied.
|
||||||
|
(if is-html
|
||||||
|
[:div {:class (stl/css :context-text)
|
||||||
|
:dangerouslySetInnerHTML #js {:__html children}}]
|
||||||
|
children)]))
|
||||||
|
|
|
@ -27,12 +27,22 @@
|
||||||
gap: var(--sp-s);
|
gap: var(--sp-s);
|
||||||
|
|
||||||
color: var(--notification-fg-color);
|
color: var(--notification-fg-color);
|
||||||
|
|
||||||
|
// Targets the potential links included by the creator in the children props.
|
||||||
|
& a {
|
||||||
|
color: var(--color-accent-primary);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.type-toast {
|
.type-toast {
|
||||||
padding-inline-end: var(--sp-xxxl);
|
padding-inline-end: var(--sp-xxxl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.appearance-ghost {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
.level-info {
|
.level-info {
|
||||||
--notification-bg-color: var(--color-background-info);
|
--notification-bg-color: var(--color-background-info);
|
||||||
--notification-fg-color: var(--color-foreground-primary);
|
--notification-fg-color: var(--color-foreground-primary);
|
||||||
|
|
|
@ -19,25 +19,40 @@
|
||||||
[:class {:optional true} :string]
|
[:class {:optional true} :string]
|
||||||
[:type {:optional true} [:maybe [:enum :toast :context]]]
|
[:type {:optional true} [:maybe [:enum :toast :context]]]
|
||||||
[:level {:optional true} [:maybe [:enum :info :warning :error :success]]]
|
[:level {:optional true} [:maybe [:enum :info :warning :error :success]]]
|
||||||
|
[:appearance {:optional true} [:enum :neutral :ghost]]
|
||||||
|
[:is-html {:optional true} :boolean]
|
||||||
[:on-close {:optional true} fn?]])
|
[:on-close {:optional true} fn?]])
|
||||||
|
|
||||||
(mf/defc toast*
|
(mf/defc toast*
|
||||||
{::mf/props :obj
|
{::mf/props :obj
|
||||||
::mf/schema schema:toast}
|
::mf/schema schema:toast}
|
||||||
[{:keys [class level type children on-close] :rest props}]
|
[{:keys [class level appearance type is-html children on-close] :rest props}]
|
||||||
(let [class (dm/str class " " (stl/css-case :toast true))
|
(let [class (dm/str class " " (stl/css :toast))
|
||||||
level (if (string? level)
|
level (if (string? level)
|
||||||
(keyword level)
|
(keyword level)
|
||||||
(d/nilv level :info))
|
(d/nilv level :info))
|
||||||
type (or type :context)
|
type (if (string? type)
|
||||||
|
(keyword type)
|
||||||
|
(d/nilv type :context))
|
||||||
|
appearance (if (string? appearance)
|
||||||
|
(keyword appearance)
|
||||||
|
(d/nilv appearance :neutral))
|
||||||
|
is-html (or is-html false)
|
||||||
props (mf/spread-props props {:class class
|
props (mf/spread-props props {:class class
|
||||||
:role "alert"
|
:role "alert"
|
||||||
:aria-live "polite"})]
|
:aria-live "polite"})]
|
||||||
[:> "aside" props
|
[:> "aside" props
|
||||||
[:> notification-pill* {:level level :type type} children]
|
[:> notification-pill* {:level level
|
||||||
|
:type type
|
||||||
|
:is-html is-html
|
||||||
|
:appearance appearance} children]
|
||||||
;; TODO: this should be a buttom from the DS, but this variant is not designed yet.
|
;; TODO: this should be a buttom from the DS, but this variant is not designed yet.
|
||||||
;; https://tree.taiga.io/project/penpot/task/8492
|
;; https://tree.taiga.io/project/penpot/task/8492
|
||||||
[:> "button" {:on-click on-close
|
[:> "button" {:on-click on-close
|
||||||
:aria-label "Close"
|
:aria-label "Close"
|
||||||
:class (stl/css :close-button)}
|
:class (stl/css-case :close-button true
|
||||||
|
:level-warning (= level :warning)
|
||||||
|
:level-error (= level :error)
|
||||||
|
:level-success (= level :success)
|
||||||
|
:level-info (= level :info))}
|
||||||
[:> i/icon* {:icon-id i/close}]]]))
|
[:> i/icon* {:icon-id i/close}]]]))
|
||||||
|
|
|
@ -26,6 +26,22 @@
|
||||||
z-index: var(--toast-vertical-index);
|
z-index: var(--toast-vertical-index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.level-info {
|
||||||
|
--toast-icon-color: var(--color-accent-info);
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-error {
|
||||||
|
--toast-icon-color: var(--color-accent-error);
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-warning {
|
||||||
|
--toast-icon-color: var(--color-accent-warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-success {
|
||||||
|
--toast-icon-color: var(--color-accent-success);
|
||||||
|
}
|
||||||
|
|
||||||
.close-button {
|
.close-button {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
width: $sz-16;
|
width: $sz-16;
|
||||||
|
|
|
@ -40,6 +40,17 @@ export const WithLongerText = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const WithHTML = {
|
||||||
|
args: {
|
||||||
|
children:
|
||||||
|
"Lorem ipsum dolor sit amet, <marquee>consectetur adipiscing elit.</marquee> Praesent lorem ante, bibendum sed ex.",
|
||||||
|
isHtml: true,
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
controls: { exclude: ["isHtml"] },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export const Info = {
|
export const Info = {
|
||||||
args: {
|
args: {
|
||||||
level: "info",
|
level: "info",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue