♻️ Rename, move and refactor the input-with-values component (#6387)

* 💄 Adapt behaviour when hovering

* ♻️ Rename, refactor and move component

* 📎 PR changes
This commit is contained in:
luisδμ 2025-05-06 11:19:18 +02:00 committed by GitHub
parent 3249fb43c3
commit e62231cfed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 85 additions and 78 deletions

View file

@ -11,7 +11,6 @@
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.combobox :refer [combobox*]]
[app.main.ui.ds.controls.input :refer [input*]]
[app.main.ui.ds.controls.input-with-values :refer [input-with-values*]]
[app.main.ui.ds.controls.select :refer [select*]]
[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]]
@ -29,6 +28,7 @@
[app.main.ui.ds.product.avatar :refer [avatar*]]
[app.main.ui.ds.product.cta :refer [cta*]]
[app.main.ui.ds.product.empty-placeholder :refer [empty-placeholder*]]
[app.main.ui.ds.product.input-with-meta :refer [input-with-meta*]]
[app.main.ui.ds.product.loader :refer [loader*]]
[app.main.ui.ds.product.user-milestone :refer [user-milestone*]]
[app.main.ui.ds.storybook :as sb]
@ -48,7 +48,7 @@
:Icon icon*
:IconButton icon-button*
:Input input*
:InputWithValues input-with-values*
:InputWithMeta input-with-meta*
:EmptyPlaceholder empty-placeholder*
:Loader loader*
:RawSvg raw-svg*

View file

@ -1,35 +0,0 @@
import { Canvas, Meta } from '@storybook/blocks';
import * as InputWithValuesStories from "./input_with_values.stories";
<Meta title="Controls/InputWithValues" />
# InputWithValues
The `input-with-values*` acts as an input with an optional addition of a series of values that are only indicators, and an event which is triggered when the focus is lost.
<Canvas of={InputWithValuesStories.Default} />
## Technical notes
* You need to pass the mandatory string property `name`.
* You can pass the optional string property `values`.
* You can pass a function property `on-blur` that will be called with the blur event when the component loses focus (including when the user presses enter or esc).
```clj
[:> input-with-values*
{:name name
:values values
:on-blur on-blur}]
```
## Usage guidelines (design)
### When to use
When we have an element that can be editable, but doesn't change its appearance on hover, and adds an extra set of values that aren't editable (they're just indicators).
### Interaction / Behavior
* The component starts on "display" mode, showing the name and the values.
* Once the user clicks on it, the input goes into "active" mode and the only thing that remains and can be editable is the name (the values are hidden).
* If the user presses enter or esc, the component goes back to "display" mode.

View file

@ -4,7 +4,7 @@
;;
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.ds.controls.input-with-values
(ns app.main.ui.ds.product.input-with-meta
(:require-macros
[app.main.style :as stl])
(:require
@ -13,23 +13,23 @@
[app.util.keyboard :as kbd]
[rumext.v2 :as mf]))
(def ^:private schema:input-with-values
(def ^:private schema:input-with-meta
[:map
[:name :string]
[:values {:optional true} :string]
[:value :string]
[:meta {:optional true} :string]
[:on-blur {:optional true} fn?]])
(mf/defc input-with-values*
(mf/defc input-with-meta*
{::mf/props :obj
::mf/schema schema:input-with-values}
[{:keys [name values on-blur] :rest props}]
::mf/schema schema:input-with-meta}
[{:keys [value meta on-blur] :rest props}]
(let [editing* (mf/use-state false)
editing? (deref editing*)
input-ref (mf/use-ref)
input (mf/ref-val input-ref)
title (if values (str name ": " values) name)
title (if meta (str value ": " meta) value)
on-edit
(mf/use-fn
@ -63,19 +63,18 @@
(when ^boolean esc? (dom/blur! node)))))
props (mf/spread-props props {:ref input-ref
:class (stl/css :input-with-values-editing)
:default-value name
:default-value value
:auto-focus true
:on-focus on-focus
:on-blur on-stop-edit
:on-key-down handle-key-down})]
(if editing?
[:div {:class (stl/css :input-with-values-edit-container)}
[:div {:class (stl/css :input-with-meta-edit-container)}
[:> input* props]]
[:div {:class (stl/css :input-with-values-container :input-with-values-grid)
[:div {:class (stl/css :input-with-meta-container)
:title title
:on-click on-edit}
[:span {:class (stl/css :input-with-values-name)} name]
(when values
[:span {:class (stl/css :input-with-values-values)} values])])))
[:span {:class (stl/css :input-with-meta-value)} value]
(when meta
[:span {:class (stl/css :input-with-meta-data)} meta])])))

View file

@ -0,0 +1,34 @@
import { Canvas, Meta } from '@storybook/blocks';
import * as InputWithMetaStories from "./input_with_meta.stories";
<Meta title="Product/InputWithMeta" />
# InputWithMeta
The `input-with-meta*` acts as an input with an optional addition of a meta text that is only an indicator, and an event which is triggered when the focus is lost.
<Canvas of={InputWithMetaStories.Default} />
## Technical notes
* You need to pass the mandatory string property `value`.
* You can pass the optional string property `meta`.
* You can pass a function property `on-blur` that will be called with the blur event when the component loses focus (including when the user presses enter or esc).
```clj
[:> input-with-meta* {:value value
:meta meta
:on-blur on-blur}]
```
## Usage guidelines (design)
### When to use
When we have an element that can be editable, but doesn't change its appearance on hover, and adds an extra meta text that isn't editable (it's just an indicator).
### Interaction / Behavior
* The component starts on "display" mode, showing the value and the meta text.
* Once the user clicks on it, the input goes into "active" mode and the only thing that remains and can be editable is the value (the meta text is hidden).
* If the user presses enter or esc, the component goes back to "display" mode.

View file

@ -9,10 +9,14 @@
@use "../_sizes.scss" as *;
@use "../typography.scss" as t;
.input-with-values-container {
.input-with-meta-container {
--input-meta-value: var(--color-foreground-primary);
--input-meta-data: var(--color-foreground-secondary);
--input-meta-background: var(--color-background-tertiary);
@include t.use-typography("body-small");
border-radius: $br-8;
background-color: var(--assets-item-background-color);
background-color: var(--input-meta-background);
padding: var(--sp-s);
width: 99%;
display: grid;
@ -21,27 +25,32 @@
overflow: hidden;
white-space: nowrap;
height: $sz-32;
&:hover {
--input-meta-background: var(--color-background-quaternary);
cursor: text;
}
}
.input-with-values-edit-container {
.input-with-meta-edit-container {
width: 99%;
border-radius: $br-8;
height: $sz-32;
}
.input-with-values-name,
.input-with-values-values {
.input-with-meta-value,
.input-with-meta-data {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.input-with-values-name {
color: var(--color-foreground-primary);
.input-with-meta-value {
color: var(--input-meta-value);
min-width: 0;
}
.input-with-values-values {
color: var(--color-foreground-secondary);
.input-with-meta-data {
color: var(--input-meta-data);
min-width: 0;
}

View file

@ -7,24 +7,24 @@
import * as React from "react";
import Components from "@target/components";
const { InputWithValues } = Components;
const { InputWithMeta } = Components;
export default {
title: "Controls/InputWithValues",
component: Components.InputWithValues,
title: "Product/InputWithMeta",
component: Components.InputWithMeta,
argTypes: {
name: {
value: {
control: { type: "text" },
},
values: {
meta: {
control: { type: "text" },
},
},
args: {
name: "Property 1",
values: "Value1, Value2",
value: "Property 1",
meta: "Value1, Value2",
},
render: ({ ...args }) => <InputWithValues {...args} />,
render: ({ ...args }) => <InputWithMeta {...args} />,
};
export const Default = {};

View file

@ -30,7 +30,7 @@
[app.main.ui.context :as ctx]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.combobox :refer [combobox*]]
[app.main.ui.ds.controls.input-with-values :refer [input-with-values*]]
[app.main.ui.ds.product.input-with-meta :refer [input-with-meta*]]
[app.main.ui.hooks :as h]
[app.main.ui.icons :as i]
[app.main.ui.workspace.sidebar.assets.common :as cmm]
@ -279,9 +279,9 @@
[:div {:key (str variant-id "-" pos) :class (stl/css :variant-property-container)}
[:*
[:div {:class (stl/css :variant-property-name-wrapper)}
[:> input-with-values* {:name (:name prop)
:data-position pos
:on-blur update-property-name}]]
[:> input-with-meta* {:value (:name prop)
:data-position pos
:on-blur update-property-name}]]
(let [mixed-value? (= (:value prop) false)
empty-value? (str/empty? (:value prop))]
@ -900,12 +900,12 @@
(when-not multi?
[:*
(for [[pos property] (map vector (range) properties)]
(let [val (str/join ", " (:value property))]
(let [meta (str/join ", " (:value property))]
[:div {:key (str (:id shape) pos) :class (stl/css :variant-property-row)}
[:> input-with-values* {:name (:name property)
:values val
:data-position pos
:on-blur update-property-name}]
[:> input-with-meta* {:value (:name property)
:meta meta
:data-position pos
:on-blur update-property-name}]
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.shape.menu.remove-variant-property")
:on-click remove-property