diff --git a/frontend/.storybook/preview.js b/frontend/.storybook/preview.js index 132a20918..c8ce13857 100644 --- a/frontend/.storybook/preview.js +++ b/frontend/.storybook/preview.js @@ -19,6 +19,10 @@ const preview = { name: "light", value: "#fff", }, + { + name: "debug", + value: "#ccc", + }, ], }, }, diff --git a/frontend/resources/images/assets/brand-github.svg b/frontend/resources/images/assets/brand-github.svg new file mode 100644 index 000000000..cfb34953e --- /dev/null +++ b/frontend/resources/images/assets/brand-github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/resources/images/assets/brand-gitlab.svg b/frontend/resources/images/assets/brand-gitlab.svg new file mode 100644 index 000000000..591427ec6 --- /dev/null +++ b/frontend/resources/images/assets/brand-gitlab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/resources/images/assets/brand-google.svg b/frontend/resources/images/assets/brand-google.svg new file mode 100644 index 000000000..eb61aab34 --- /dev/null +++ b/frontend/resources/images/assets/brand-google.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/resources/images/assets/brand-openid.svg b/frontend/resources/images/assets/brand-openid.svg new file mode 100644 index 000000000..28dd05ed8 --- /dev/null +++ b/frontend/resources/images/assets/brand-openid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/resources/images/assets/loader.svg b/frontend/resources/images/assets/loader.svg new file mode 100644 index 000000000..ee1d9b96b --- /dev/null +++ b/frontend/resources/images/assets/loader.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/resources/images/assets/login-illustration.svg b/frontend/resources/images/assets/login-illustration.svg new file mode 100644 index 000000000..6e6b7394a --- /dev/null +++ b/frontend/resources/images/assets/login-illustration.svg @@ -0,0 +1,686 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/resources/images/assets/logo-error-screen.svg b/frontend/resources/images/assets/logo-error-screen.svg new file mode 100644 index 000000000..7e71215fa --- /dev/null +++ b/frontend/resources/images/assets/logo-error-screen.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/resources/images/assets/penpot-logo-icon.svg b/frontend/resources/images/assets/penpot-logo-icon.svg new file mode 100644 index 000000000..06adb5d44 --- /dev/null +++ b/frontend/resources/images/assets/penpot-logo-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/resources/images/assets/penpot-logo.svg b/frontend/resources/images/assets/penpot-logo.svg new file mode 100644 index 000000000..6439292bd --- /dev/null +++ b/frontend/resources/images/assets/penpot-logo.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/frontend/resources/images/assets/v2-icon-1.svg b/frontend/resources/images/assets/v2-icon-1.svg new file mode 100644 index 000000000..b39647eb1 --- /dev/null +++ b/frontend/resources/images/assets/v2-icon-1.svg @@ -0,0 +1 @@ + diff --git a/frontend/resources/images/assets/v2-icon-2.svg b/frontend/resources/images/assets/v2-icon-2.svg new file mode 100644 index 000000000..d384ee2ed --- /dev/null +++ b/frontend/resources/images/assets/v2-icon-2.svg @@ -0,0 +1 @@ + diff --git a/frontend/resources/images/assets/v2-icon-3.svg b/frontend/resources/images/assets/v2-icon-3.svg new file mode 100644 index 000000000..bfc88da6d --- /dev/null +++ b/frontend/resources/images/assets/v2-icon-3.svg @@ -0,0 +1 @@ + diff --git a/frontend/resources/images/assets/v2-icon-4.svg b/frontend/resources/images/assets/v2-icon-4.svg new file mode 100644 index 000000000..dc2443432 --- /dev/null +++ b/frontend/resources/images/assets/v2-icon-4.svg @@ -0,0 +1 @@ + diff --git a/frontend/resources/templates/index.mustache b/frontend/resources/templates/index.mustache index b5967f94d..7846bb111 100644 --- a/frontend/resources/templates/index.mustache +++ b/frontend/resources/templates/index.mustache @@ -41,6 +41,7 @@ {{> ../public/images/sprites/symbol/icons.svg }} {{> ../public/images/sprites/symbol/cursors.svg }} + {{> ../public/images/sprites/assets.svg }}
diff --git a/frontend/resources/templates/preview-body.mustache b/frontend/resources/templates/preview-body.mustache index 216552e61..4ade10b08 100644 --- a/frontend/resources/templates/preview-body.mustache +++ b/frontend/resources/templates/preview-body.mustache @@ -1 +1,3 @@ {{> ../public/images/sprites/symbol/icons.svg }} + +{{> ../public/images/sprites/assets.svg }} diff --git a/frontend/scripts/_helpers.js b/frontend/scripts/_helpers.js index 435531ca5..ce6397e47 100644 --- a/frontend/scripts/_helpers.js +++ b/frontend/scripts/_helpers.js @@ -307,11 +307,18 @@ async function generateSvgSprites() { ); const cursors = await findFiles("resources/images/cursors/", isSvgFile); - const cursorsSprite = await generateSvgSprite(icons, "cursor-"); + const cursorsSprite = await generateSvgSprite(cursors, "cursor-"); await fs.writeFile( "resources/public/images/sprites/symbol/cursors.svg", cursorsSprite, ); + + const assets = await findFiles("resources/images/assets/", isSvgFile); + const assetsSprite = await generateSvgSprite(assets, "asset-"); + await fs.writeFile( + "resources/public/images/sprites/assets.svg", + assetsSprite, + ); } async function generateTemplates() { @@ -330,9 +337,14 @@ async function generateTemplates() { "resources/public/images/sprites/symbol/cursors.svg", "utf8", ); + const assetsSprite = await fs.readFile( + "resources/public/images/sprites/assets.svg", + "utf-8", + ); const partials = { "../public/images/sprites/symbol/icons.svg": iconsSprite, "../public/images/sprites/symbol/cursors.svg": cursorsSprite, + "../public/images/sprites/assets.svg": assetsSprite, }; const pluginRuntimeUri = diff --git a/frontend/src/app/main/ui/ds.cljs b/frontend/src/app/main/ui/ds.cljs index a644e71f6..805f504ff 100644 --- a/frontend/src/app/main/ui/ds.cljs +++ b/frontend/src/app/main/ui/ds.cljs @@ -7,11 +7,16 @@ (ns app.main.ui.ds (:require [app.main.ui.ds.foundations.icon :refer [icon* icon-list]] + [app.main.ui.ds.foundations.raw-svg :refer [raw-svg* raw-svg-list]] [app.main.ui.ds.storybook :as sb])) (def default "A export used for storybook" #js {:Icon icon* + :RawSvg raw-svg* ;; meta / misc - :meta #js {:icons icon-list} - :storybook #js {:StoryWrapper sb/story-wrapper* :IconGrid sb/icon-grid*}}) + :meta #js {:icons icon-list :svgs raw-svg-list} + :storybook #js {:StoryGrid sb/story-grid* + :StoryGridCell sb/story-grid-cell* + :StoryHeader sb/story-header* + :StoryWrapper sb/story-wrapper*}}) diff --git a/frontend/src/app/main/ui/ds/foundations/icon.cljs b/frontend/src/app/main/ui/ds/foundations/icon.cljs index c325c065a..bf77f12b2 100644 --- a/frontend/src/app/main/ui/ds/foundations/icon.cljs +++ b/frontend/src/app/main/ui/ds/foundations/icon.cljs @@ -253,7 +253,7 @@ {::mf/props :obj} [{:keys [icon size class] :rest props}] (let [class (dm/str (or class "") " " (stl/css :icon)) - props (mf/spread props {:class class :width icon-size-m :height icon-size-m}) + props (mf/spread-props props {:class class :width icon-size-m :height icon-size-m}) size-px (cond (= size "s") icon-size-s :else icon-size-m) offset (/ (- icon-size-m size-px) 2)] [:> "svg" props diff --git a/frontend/src/app/main/ui/ds/foundations/icon.stories.jsx b/frontend/src/app/main/ui/ds/foundations/icon.stories.jsx index d143da7c3..52bb1076c 100644 --- a/frontend/src/app/main/ui/ds/foundations/icon.stories.jsx +++ b/frontend/src/app/main/ui/ds/foundations/icon.stories.jsx @@ -2,7 +2,8 @@ import * as React from "react"; import Components from "@target/components"; const { Icon } = Components; -const { StoryWrapper, IconGrid } = Components.storybook; +const { StoryWrapper, StoryGrid, StoryGridCell, StoryHeader } = + Components.storybook; const { icons } = Components.meta; export default { @@ -17,23 +18,32 @@ const iconList = Object.entries(icons) export const AllIcons = { render: () => ( -

All Icons

-

Hover on an icon to see its ID

- + +

All Icons

+

Hover on an icon to see its ID

+
+ {iconList.map((iconId) => ( -
+ -
+ ))} -
+
), + parameters: { + backgrounds: { disable: true }, + }, }; export const Default = { render: () => ( - + ), }; @@ -41,7 +51,7 @@ export const Default = { export const Small = { render: () => ( - + ), }; diff --git a/frontend/src/app/main/ui/ds/foundations/raw_svg.clj b/frontend/src/app/main/ui/ds/foundations/raw_svg.clj new file mode 100644 index 000000000..2ba5104ae --- /dev/null +++ b/frontend/src/app/main/ui/ds/foundations/raw_svg.clj @@ -0,0 +1,21 @@ +;; 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.foundations.raw-svg + (:require + [clojure.core :as c] + [cuerdas.core :as str] + [rumext.v2])) + +(defmacro collect-raw-svgs + [] + (let [ns-info (:ns &env)] + `(cljs.core/js-obj + ~@(->> (:defs ns-info) + (map val) + (filter (fn [entry] (-> entry :meta :svg-id))) + (mapcat (fn [{:keys [name]}] + [(-> name c/name str/camel str/capital) name])))))) diff --git a/frontend/src/app/main/ui/ds/foundations/raw_svg.cljs b/frontend/src/app/main/ui/ds/foundations/raw_svg.cljs new file mode 100644 index 000000000..0de183215 --- /dev/null +++ b/frontend/src/app/main/ui/ds/foundations/raw_svg.cljs @@ -0,0 +1,37 @@ +;; 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.foundations.raw-svg + (:refer-clojure :exclude [mask]) + (:require-macros + [app.common.data.macros :as dm] + [app.main.ui.ds.foundations.raw-svg :refer [collect-raw-svgs]]) + (:require + [rumext.v2 :as mf])) + +(def ^:svg-id brand-openid "brand-openid") +(def ^:svg-id brand-github "brand-github") +(def ^:svg-id brand-gitlab "brand-gitlab") +(def ^:svg-id brand-google "brand-google") + +(def ^:svg-id loader "loader") +(def ^:svg-id logo "penpot-logo") +(def ^:svg-id logo-icon "penpot-logo-icon") +(def ^:svg-id logo-error-screen "logo-error-screen") +(def ^:svg-id login-illustration "login-illustration") + +(def ^:svg-id v2-icon-1 "v2-icon-1") +(def ^:svg-id v2-icon-2 "v2-icon-2") +(def ^:svg-id v2-icon-3 "v2-icon-3") +(def ^:svg-id v2-icon-4 "v2-icon-4") + +(def raw-svg-list "A collection of all raw SVG assets" (collect-raw-svgs)) + +(mf/defc raw-svg* + {::mf/props :obj} + [{:keys [asset] :rest props}] + [:> "svg" props + [:use {:href (dm/str "#asset-" asset)}]]) diff --git a/frontend/src/app/main/ui/ds/foundations/raw_svg.mdx b/frontend/src/app/main/ui/ds/foundations/raw_svg.mdx new file mode 100644 index 000000000..0377ce51b --- /dev/null +++ b/frontend/src/app/main/ui/ds/foundations/raw_svg.mdx @@ -0,0 +1,28 @@ +import { Canvas, Meta } from "@storybook/blocks"; +import * as RawSvgStories from "./raw_svg.stories"; + + + +# SVG Assets + +## Technical notes + +There are some SVG assets that are not icons or cursors, and that are mostly +meant to be used as is (although depending on the context, some will be required +to be used with a specific color or size). + +The assets are located in the `frontend/resources/images/assets` folder. + +### Using asset IDs + +For convenience, asset IDs are available in the component namespace. + +```clj +(ns app.main.ui.foo + (:require + [app.main.ui.ds.foundations.raw-svg :as svg])) +``` + +```clj +[:> svg/svg-asset* {:asset svg/logo}] +``` diff --git a/frontend/src/app/main/ui/ds/foundations/raw_svg.stories.jsx b/frontend/src/app/main/ui/ds/foundations/raw_svg.stories.jsx new file mode 100644 index 000000000..b73e6b56e --- /dev/null +++ b/frontend/src/app/main/ui/ds/foundations/raw_svg.stories.jsx @@ -0,0 +1,46 @@ +import * as React from "react"; +import Components from "@target/components"; + +const { RawSvg } = Components; +const { StoryWrapper, StoryGrid, StoryGridCell, StoryHeader } = + Components.storybook; +const { svgs } = Components.meta; + +export default { + title: "Foundations/RawSvg", + component: Components.RawSvg, +}; + +const assetList = Object.entries(svgs) + .map(([_, value]) => value) + .sort(); + +export const AllAssets = { + render: () => ( + + +

All assets

+

Hover on a asset to see its id.

+
+ + + {assetList.map((x) => ( + + + + ))} + +
+ ), + parameters: { + backgrounds: { values: [{ name: "debug", value: "#ccc" }] }, + }, +}; + +export const Default = { + render: () => ( + + + + ), +}; diff --git a/frontend/src/app/main/ui/ds/storybook.cljs b/frontend/src/app/main/ui/ds/storybook.cljs index 6aa0498cc..322dbe822 100644 --- a/frontend/src/app/main/ui/ds/storybook.cljs +++ b/frontend/src/app/main/ui/ds/storybook.cljs @@ -6,7 +6,9 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.ds.storybook - (:require-macros [app.main.style :as stl]) + (:require-macros + [app.common.data.macros :as dm] + [app.main.style :as stl]) (:require [rumext.v2 :as mf])) @@ -20,7 +22,26 @@ [:section {:class "default"} children] [:section {:class "light"} children]])]) -(mf/defc icon-grid* +(mf/defc story-grid* {::mf/props :obj} - [{:keys [children]}] - [:article {:class (stl/css :icon-grid)} children]) \ No newline at end of file + [{:keys [children size style] :rest other}] + (let [class (stl/css :story-grid) + size (or size 16) + style (or style {}) + style (mf/spread style :--component-grid-size (dm/str size "px")) + props (mf/spread-props other {:class class :style style})] + [:> "article" props children])) + +(mf/defc story-grid-cell* + {::mf/props :obj} + [{:keys [children] :rest other}] + (let [class (stl/css :story-grid-cell) + props (mf/spread-props other {:class class})] + [:> "article" props children])) + +(mf/defc story-header* + {::mf/props :obj} + [{:keys [children] :rest other}] + (let [class (stl/css :story-header) + props (mf/spread-props other {:class class})] + [:> "header" props children])) diff --git a/frontend/src/app/main/ui/ds/storybook.scss b/frontend/src/app/main/ui/ds/storybook.scss index 05e1c8191..6d09f0167 100644 --- a/frontend/src/app/main/ui/ds/storybook.scss +++ b/frontend/src/app/main/ui/ds/storybook.scss @@ -5,9 +5,17 @@ row-gap: 1rem; } -.icon-grid { +.story-grid { display: grid; - grid-template-columns: repeat(auto-fit, 16px); + grid-template-columns: repeat(auto-fit, var(--component-grid-size, 16px)); gap: 1rem; color: var(--color-foreground-primary); } + +.story-grid-cell { + max-width: 100%; +} + +.story-header { + color: var(--color-foreground-primary); +}