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'