mirror of
https://github.com/penpot/penpot.git
synced 2025-05-29 09:16:11 +02:00
♻️ 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:
parent
3249fb43c3
commit
e62231cfed
7 changed files with 85 additions and 78 deletions
|
@ -11,7 +11,6 @@
|
||||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||||
[app.main.ui.ds.controls.combobox :refer [combobox*]]
|
[app.main.ui.ds.controls.combobox :refer [combobox*]]
|
||||||
[app.main.ui.ds.controls.input :refer [input*]]
|
[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.controls.select :refer [select*]]
|
||||||
[app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list]]
|
[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.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.avatar :refer [avatar*]]
|
||||||
[app.main.ui.ds.product.cta :refer [cta*]]
|
[app.main.ui.ds.product.cta :refer [cta*]]
|
||||||
[app.main.ui.ds.product.empty-placeholder :refer [empty-placeholder*]]
|
[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.loader :refer [loader*]]
|
||||||
[app.main.ui.ds.product.user-milestone :refer [user-milestone*]]
|
[app.main.ui.ds.product.user-milestone :refer [user-milestone*]]
|
||||||
[app.main.ui.ds.storybook :as sb]
|
[app.main.ui.ds.storybook :as sb]
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
:Icon icon*
|
:Icon icon*
|
||||||
:IconButton icon-button*
|
:IconButton icon-button*
|
||||||
:Input input*
|
:Input input*
|
||||||
:InputWithValues input-with-values*
|
:InputWithMeta input-with-meta*
|
||||||
:EmptyPlaceholder empty-placeholder*
|
:EmptyPlaceholder empty-placeholder*
|
||||||
:Loader loader*
|
:Loader loader*
|
||||||
:RawSvg raw-svg*
|
:RawSvg raw-svg*
|
||||||
|
|
|
@ -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.
|
|
|
@ -4,7 +4,7 @@
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) KALEIDOS INC
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
(ns app.main.ui.ds.controls.input-with-values
|
(ns app.main.ui.ds.product.input-with-meta
|
||||||
(:require-macros
|
(:require-macros
|
||||||
[app.main.style :as stl])
|
[app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
|
@ -13,23 +13,23 @@
|
||||||
[app.util.keyboard :as kbd]
|
[app.util.keyboard :as kbd]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def ^:private schema:input-with-values
|
(def ^:private schema:input-with-meta
|
||||||
[:map
|
[:map
|
||||||
[:name :string]
|
[:value :string]
|
||||||
[:values {:optional true} :string]
|
[:meta {:optional true} :string]
|
||||||
[:on-blur {:optional true} fn?]])
|
[:on-blur {:optional true} fn?]])
|
||||||
|
|
||||||
(mf/defc input-with-values*
|
(mf/defc input-with-meta*
|
||||||
{::mf/props :obj
|
{::mf/props :obj
|
||||||
::mf/schema schema:input-with-values}
|
::mf/schema schema:input-with-meta}
|
||||||
[{:keys [name values on-blur] :rest props}]
|
[{:keys [value meta on-blur] :rest props}]
|
||||||
(let [editing* (mf/use-state false)
|
(let [editing* (mf/use-state false)
|
||||||
editing? (deref editing*)
|
editing? (deref editing*)
|
||||||
|
|
||||||
input-ref (mf/use-ref)
|
input-ref (mf/use-ref)
|
||||||
input (mf/ref-val input-ref)
|
input (mf/ref-val input-ref)
|
||||||
|
|
||||||
title (if values (str name ": " values) name)
|
title (if meta (str value ": " meta) value)
|
||||||
|
|
||||||
on-edit
|
on-edit
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -63,19 +63,18 @@
|
||||||
(when ^boolean esc? (dom/blur! node)))))
|
(when ^boolean esc? (dom/blur! node)))))
|
||||||
|
|
||||||
props (mf/spread-props props {:ref input-ref
|
props (mf/spread-props props {:ref input-ref
|
||||||
:class (stl/css :input-with-values-editing)
|
:default-value value
|
||||||
:default-value name
|
|
||||||
:auto-focus true
|
:auto-focus true
|
||||||
:on-focus on-focus
|
:on-focus on-focus
|
||||||
:on-blur on-stop-edit
|
:on-blur on-stop-edit
|
||||||
:on-key-down handle-key-down})]
|
:on-key-down handle-key-down})]
|
||||||
|
|
||||||
(if editing?
|
(if editing?
|
||||||
[:div {:class (stl/css :input-with-values-edit-container)}
|
[:div {:class (stl/css :input-with-meta-edit-container)}
|
||||||
[:> input* props]]
|
[:> input* props]]
|
||||||
[:div {:class (stl/css :input-with-values-container :input-with-values-grid)
|
[:div {:class (stl/css :input-with-meta-container)
|
||||||
:title title
|
:title title
|
||||||
:on-click on-edit}
|
:on-click on-edit}
|
||||||
[:span {:class (stl/css :input-with-values-name)} name]
|
[:span {:class (stl/css :input-with-meta-value)} value]
|
||||||
(when values
|
(when meta
|
||||||
[:span {:class (stl/css :input-with-values-values)} values])])))
|
[:span {:class (stl/css :input-with-meta-data)} meta])])))
|
34
frontend/src/app/main/ui/ds/product/input_with_meta.mdx
Normal file
34
frontend/src/app/main/ui/ds/product/input_with_meta.mdx
Normal 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.
|
|
@ -9,10 +9,14 @@
|
||||||
@use "../_sizes.scss" as *;
|
@use "../_sizes.scss" as *;
|
||||||
@use "../typography.scss" as t;
|
@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");
|
@include t.use-typography("body-small");
|
||||||
border-radius: $br-8;
|
border-radius: $br-8;
|
||||||
background-color: var(--assets-item-background-color);
|
background-color: var(--input-meta-background);
|
||||||
padding: var(--sp-s);
|
padding: var(--sp-s);
|
||||||
width: 99%;
|
width: 99%;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
@ -21,27 +25,32 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
height: $sz-32;
|
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%;
|
width: 99%;
|
||||||
border-radius: $br-8;
|
border-radius: $br-8;
|
||||||
height: $sz-32;
|
height: $sz-32;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-with-values-name,
|
.input-with-meta-value,
|
||||||
.input-with-values-values {
|
.input-with-meta-data {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-with-values-name {
|
.input-with-meta-value {
|
||||||
color: var(--color-foreground-primary);
|
color: var(--input-meta-value);
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-with-values-values {
|
.input-with-meta-data {
|
||||||
color: var(--color-foreground-secondary);
|
color: var(--input-meta-data);
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
|
@ -7,24 +7,24 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import Components from "@target/components";
|
import Components from "@target/components";
|
||||||
|
|
||||||
const { InputWithValues } = Components;
|
const { InputWithMeta } = Components;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Controls/InputWithValues",
|
title: "Product/InputWithMeta",
|
||||||
component: Components.InputWithValues,
|
component: Components.InputWithMeta,
|
||||||
argTypes: {
|
argTypes: {
|
||||||
name: {
|
value: {
|
||||||
control: { type: "text" },
|
control: { type: "text" },
|
||||||
},
|
},
|
||||||
values: {
|
meta: {
|
||||||
control: { type: "text" },
|
control: { type: "text" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
args: {
|
args: {
|
||||||
name: "Property 1",
|
value: "Property 1",
|
||||||
values: "Value1, Value2",
|
meta: "Value1, Value2",
|
||||||
},
|
},
|
||||||
render: ({ ...args }) => <InputWithValues {...args} />,
|
render: ({ ...args }) => <InputWithMeta {...args} />,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Default = {};
|
export const Default = {};
|
|
@ -30,7 +30,7 @@
|
||||||
[app.main.ui.context :as ctx]
|
[app.main.ui.context :as ctx]
|
||||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||||
[app.main.ui.ds.controls.combobox :refer [combobox*]]
|
[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.hooks :as h]
|
||||||
[app.main.ui.icons :as i]
|
[app.main.ui.icons :as i]
|
||||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||||
|
@ -279,7 +279,7 @@
|
||||||
[:div {:key (str variant-id "-" pos) :class (stl/css :variant-property-container)}
|
[:div {:key (str variant-id "-" pos) :class (stl/css :variant-property-container)}
|
||||||
[:*
|
[:*
|
||||||
[:div {:class (stl/css :variant-property-name-wrapper)}
|
[:div {:class (stl/css :variant-property-name-wrapper)}
|
||||||
[:> input-with-values* {:name (:name prop)
|
[:> input-with-meta* {:value (:name prop)
|
||||||
:data-position pos
|
:data-position pos
|
||||||
:on-blur update-property-name}]]
|
:on-blur update-property-name}]]
|
||||||
|
|
||||||
|
@ -900,10 +900,10 @@
|
||||||
(when-not multi?
|
(when-not multi?
|
||||||
[:*
|
[:*
|
||||||
(for [[pos property] (map vector (range) properties)]
|
(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)}
|
[:div {:key (str (:id shape) pos) :class (stl/css :variant-property-row)}
|
||||||
[:> input-with-values* {:name (:name property)
|
[:> input-with-meta* {:value (:name property)
|
||||||
:values val
|
:meta meta
|
||||||
:data-position pos
|
:data-position pos
|
||||||
:on-blur update-property-name}]
|
:on-blur update-property-name}]
|
||||||
[:> icon-button* {:variant "ghost"
|
[:> icon-button* {:variant "ghost"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue