diff --git a/frontend/src/app/main/ui/ds.cljs b/frontend/src/app/main/ui/ds.cljs
index b32891fcd..0fddb71e9 100644
--- a/frontend/src/app/main/ui/ds.cljs
+++ b/frontend/src/app/main/ui/ds.cljs
@@ -12,6 +12,9 @@
[app.main.ui.ds.controls.combobox :refer [combobox*]]
[app.main.ui.ds.controls.input :refer [input*]]
[app.main.ui.ds.controls.select :refer [select*]]
+ [app.main.ui.ds.controls.utilities.hint-message :refer [hint-message*]]
+ [app.main.ui.ds.controls.utilities.input-field :refer [input-field*]]
+ [app.main.ui.ds.controls.utilities.label :refer [label*]]
[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]]
@@ -49,6 +52,9 @@
:Icon icon*
:IconButton icon-button*
:Input input*
+ :Label label*
+ :InputField input-field*
+ :HintMessage hint-message*
:InputWithMeta input-with-meta*
:EmptyPlaceholder empty-placeholder*
:Loader loader*
diff --git a/frontend/src/app/main/ui/ds/controls/input.mdx b/frontend/src/app/main/ui/ds/controls/input.mdx
index 47e6b303c..c198f5144 100644
--- a/frontend/src/app/main/ui/ds/controls/input.mdx
+++ b/frontend/src/app/main/ui/ds/controls/input.mdx
@@ -26,6 +26,31 @@ These are available in the `app.main.ds.foundations.assets.icon` namespace.
[:> input* {:icon i/effects}]
```
+## Destructuring the component
+
+The `input*` component is composed of `label*`, `input-field*`, and `hint-message*` components. If you only need some of these components or require them to be broken down, you can build them as a group of components.
+
+```clj
+[:> label* {:for id :is-optional true} label]
+[:> input-field* {:id id}]
+[:> hint-message* {:id id :message message :type "warning}]
+```
+
+
+
+#### `input-field*` slots
+
+The `input-field*` offers two slots where developers can include external components as properties.
+
+- **slot-start**: adds a component to the beginning of the input
+- **slot-end**: adds a component to the end of the input
+
+```clj
+[:> input-field* {:id id :slot-start component-one :slot-end component-two}]
+```
+
+
+
## Usage guidelines (design)
### Where to use
diff --git a/frontend/src/app/main/ui/ds/controls/input.stories.jsx b/frontend/src/app/main/ui/ds/controls/input.stories.jsx
index c172c073b..e45e78e74 100644
--- a/frontend/src/app/main/ui/ds/controls/input.stories.jsx
+++ b/frontend/src/app/main/ui/ds/controls/input.stories.jsx
@@ -8,6 +8,10 @@ import * as React from "react";
import Components from "@target/components";
const { Input } = Components;
+const { Label } = Components;
+const { InputField } = Components;
+const { HintMessage } = Components;
+const { IconButton } = Components;
const { icons } = Components.meta;
export default {
@@ -85,3 +89,77 @@ export const Seamless = {
variant: "seamless",
},
};
+
+export const Composable = {
+ argTypes: {
+ label: { control: "text" },
+ labelArgs: { control: "object" },
+ inputArgs: { control: "object" },
+ hintArgs: { control: "object" },
+ },
+ args: {
+ label: "Label",
+ labelArgs: {
+ htmlFor: "input",
+ isOptional: false,
+ },
+ inputArgs: {
+ id: "input",
+ variant: "comfortable",
+ type: "text",
+ placeholder: "Placeholder",
+ },
+ hintArgs: {
+ id: "input",
+ message: "This is a hint text to help user.",
+ type: "hint",
+ },
+ },
+ render: ({ ...args }) => {
+ return (
+ <>
+
+
+
+ >
+ );
+ },
+};
+
+export const Slots = {
+ argTypes: {
+ label: { control: "text" },
+ labelArgs: { control: "object" },
+ inputArgs: { control: "object" },
+ hintArgs: { control: "object" },
+ },
+ args: {
+ inputArgs: {
+ id: "input",
+ variant: "comfortable",
+ type: "text",
+ placeholder: "Placeholder",
+ slotStart: (
+
+ ),
+ slotEnd: (
+
+ ),
+ },
+ },
+ render: ({ ...args }) => {
+ return (
+ <>
+
+ >
+ );
+ },
+};
diff --git a/frontend/src/app/main/ui/ds/controls/utilities/input_field.scss b/frontend/src/app/main/ui/ds/controls/utilities/input_field.scss
index 64034c909..ca2eb2778 100644
--- a/frontend/src/app/main/ui/ds/controls/utilities/input_field.scss
+++ b/frontend/src/app/main/ui/ds/controls/utilities/input_field.scss
@@ -13,7 +13,6 @@
--input-bg-color: var(--color-background-tertiary);
--input-fg-color: var(--color-foreground-primary);
--input-icon-color: var(--color-foreground-secondary);
- --input-text-indent: 0;
--input-outline-color: none;
--input-height: #{$sz-32};
--input-margin: unset;
@@ -81,7 +80,6 @@
border: none;
background: none;
inline-size: 100%;
- text-indent: var(--input-text-indent, 0);
font-family: inherit;
font-size: inherit;
diff --git a/frontend/src/app/main/ui/workspace/tokens/components/controls/input_tokens_value.cljs b/frontend/src/app/main/ui/workspace/tokens/components/controls/input_tokens_value.cljs
index 62f6b7f1e..d06971efe 100644
--- a/frontend/src/app/main/ui/workspace/tokens/components/controls/input_tokens_value.cljs
+++ b/frontend/src/app/main/ui/workspace/tokens/components/controls/input_tokens_value.cljs
@@ -32,11 +32,10 @@
(let [id (mf/use-id)
input-ref (mf/use-ref)
swatch
- (when color
- (mf/html [:> input-token-color-bullet*
- {:color color
- :class (stl/css :slot-start)
- :on-click display-colorpicker}]))
+ (mf/html [:> input-token-color-bullet*
+ {:color color
+ :class (stl/css :slot-start)
+ :on-click display-colorpicker}])
props (mf/spread-props props {:id id
:type "text"
diff --git a/frontend/src/app/main/ui/workspace/tokens/form.cljs b/frontend/src/app/main/ui/workspace/tokens/form.cljs
index 371bd78b6..ee74ce5e4 100644
--- a/frontend/src/app/main/ui/workspace/tokens/form.cljs
+++ b/frontend/src/app/main/ui/workspace/tokens/form.cljs
@@ -238,7 +238,7 @@
(let [create? (not (instance? ctob/Token token))
token (or token {:type token-type})
token-properties (dwta/get-token-properties token)
- color? (cft/color-token? token)
+ is-color-token (cft/color-token? token)
selected-set-tokens (mf/deref refs/workspace-selected-token-set-tokens)
active-theme-tokens (cond-> (mf/deref refs/workspace-active-theme-sets-tokens)
@@ -321,7 +321,7 @@
(valid-name? @token-name-ref))
;; Value
- color* (mf/use-state (when color? (:value token)))
+ color* (mf/use-state (when is-color-token (:value token)))
color (deref color*)
color-ramp-open* (mf/use-state false)
color-ramp-open? (deref color-ramp-open*)
@@ -345,7 +345,7 @@
:else
(:resolved-value token-or-err))]
- (when color? (reset! color* (if error? nil v)))
+ (when is-color-token (reset! color* (if error? nil v)))
(reset! token-resolve-result* v))))
on-update-value-debounced (use-debonced-resolve-callback token-name-ref token active-theme-tokens set-resolve-value)
@@ -354,7 +354,7 @@
(fn [e]
(let [value (dom/get-target-val e)
;; Automatically add # for hex values
- value' (if (and color? (tinycolor/hex-without-hash-prefix? value))
+ value' (if (and is-color-token (tinycolor/hex-without-hash-prefix? value))
(let [hex (dm/str "#" value)]
(dom/set-value! (mf/ref-val value-input-ref) hex)
hex)
@@ -560,7 +560,7 @@
:label (tr "workspace.tokens.token-value")
:default-value (mf/ref-val value-ref)
:ref value-input-ref
- :color color
+ :color (when is-color-token color)
:on-change on-update-value
:error (not (nil? (:errors token-resolve-result)))
:display-colorpicker on-display-colorpicker'