diff --git a/frontend/src/app/main/ui/ds.cljs b/frontend/src/app/main/ui/ds.cljs index 9ac05d4f8..85268cf8d 100644 --- a/frontend/src/app/main/ui/ds.cljs +++ b/frontend/src/app/main/ui/ds.cljs @@ -8,6 +8,7 @@ (:require [app.main.ui.ds.buttons.button :refer [button*]] [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] + [app.main.ui.ds.forms.input :refer [input*]] [app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list]] [app.main.ui.ds.foundations.assets.raw-svg :refer [raw-svg* raw-svg-list]] [app.main.ui.ds.foundations.typography :refer [typography-list]] @@ -22,6 +23,7 @@ :Heading heading* :Icon icon* :IconButton icon-button* + :Input input* :Loader loader* :RawSvg raw-svg* :Text text* diff --git a/frontend/src/app/main/ui/ds/_borders.scss b/frontend/src/app/main/ui/ds/_borders.scss index 165ade57d..a424603d1 100644 --- a/frontend/src/app/main/ui/ds/_borders.scss +++ b/frontend/src/app/main/ui/ds/_borders.scss @@ -8,3 +8,5 @@ // TODO: create actual tokens once we have them from design $br-8: px2rem(8); + +$b-1: px2rem(1); diff --git a/frontend/src/app/main/ui/ds/buttons/_buttons.scss b/frontend/src/app/main/ui/ds/buttons/_buttons.scss index 7d8c896ac..b489b4df9 100644 --- a/frontend/src/app/main/ui/ds/buttons/_buttons.scss +++ b/frontend/src/app/main/ui/ds/buttons/_buttons.scss @@ -27,7 +27,7 @@ background: var(--button-bg-color); color: var(--button-fg-color); - border: 1px solid var(--button-border-color); + border: $b-1 solid var(--button-border-color); &:hover { --button-bg-color: var(--button-hover-bg-color); diff --git a/frontend/src/app/main/ui/ds/forms/input.cljs b/frontend/src/app/main/ui/ds/forms/input.cljs new file mode 100644 index 000000000..6b97e5449 --- /dev/null +++ b/frontend/src/app/main/ui/ds/forms/input.cljs @@ -0,0 +1,32 @@ +;; 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.forms.input + (:require-macros + [app.common.data.macros :as dm] + [app.main.style :as stl]) + (:require + [app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list]] + [app.util.dom :as dom] + [rumext.v2 :as mf])) + +(mf/defc input* + {::mf/props :obj} + [{:keys [icon class type ref] :rest props}] + (assert (or (nil? icon) (contains? icon-list icon))) + (let [ref (or ref (mf/use-ref)) + type (or type "text") + icon-class (stl/css-case :input true + :input-with-icon (some? icon)) + props (mf/spread-props props {:class icon-class :ref ref :type type}) + handle-icon-click (mf/use-fn (mf/deps ref) + (fn [_] + (let [input-node (mf/ref-val ref)] + (dom/select-node input-node) + (dom/focus! input-node))))] + [:> "span" {:class (dm/str class " " (stl/css :container))} + (when icon [:> icon* {:id icon :class (stl/css :icon) :on-click handle-icon-click}]) + [:> "input" props]])) \ No newline at end of file diff --git a/frontend/src/app/main/ui/ds/forms/input.scss b/frontend/src/app/main/ui/ds/forms/input.scss new file mode 100644 index 000000000..027e79878 --- /dev/null +++ b/frontend/src/app/main/ui/ds/forms/input.scss @@ -0,0 +1,64 @@ +@use "../_borders.scss" as *; +@use "../_sizes.scss" as *; +@use "../typography.scss" as *; + +.container { + --input-bg-color: var(--color-background-tertiary); + --input-fg-color: var(--color-foreground-primary); + --input-icon-color: var(--color-foreground-secondary); + --input-outline-color: none; + + display: inline-flex; + column-gap: var(--sp-xs); + align-items: center; + position: relative; + + background: var(--input-bg-color); + border-radius: $br-8; + padding: 0 var(--sp-s); + outline-offset: #{$b-1}; + outline: $b-1 solid var(--input-outline-color); + + &:hover { + --input-bg-color: var(--color-background-quaternary); + } + + &:has(*:focus-visible) { + --input-bg-color: var(--color-background-primary); + --input-outline-color: var(--color-accent-primary); + } + + &:has(*:disabled) { + --input-bg-color: var(--color-background-primary); + --input-outline-color: var(--color-background-quaternary); + } +} + +.input { + margin: unset; // remove settings from global css + padding: 0; + appearance: none; + margin-inline-start: var(--sp-xxs); + height: $sz-32; + border: none; + background: none; + + @include use-typography("body-small"); + color: var(--input-fg-color); + + &:focus-visible { + outline: none; + } + + &::selection { + background: var(--color-accent-primary-muted); + } + + &::placeholder { + --input-fg-color: var(--color-foreground-secondary); + } +} + +.icon { + color: var(--color-foreground-secondary); +} diff --git a/frontend/src/app/main/ui/ds/forms/input.stories.jsx b/frontend/src/app/main/ui/ds/forms/input.stories.jsx new file mode 100644 index 000000000..2f0122283 --- /dev/null +++ b/frontend/src/app/main/ui/ds/forms/input.stories.jsx @@ -0,0 +1,47 @@ +// 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 { Input } = Components; +const { icons } = Components.meta; + +export default { + title: "Forms/Input", + component: Components.Input, + argTypes: { + icon: { + options: icons, + control: { type: "select" }, + }, + value: { + control: { type: "text" }, + }, + disabled: { control: "boolean" }, + }, + args: { + disabled: false, + value: "Lorem ipsum", + }, + render: ({ ...args }) => , +}; + +export const Default = {}; + +export const WithIcon = { + args: { + icon: "effects", + }, +}; + +export const WithPlaceholder = { + args: { + icon: "effects", + value: undefined, + placeholder: "Mixed", + }, +};