@agility/plenum-ui 2.0.0-rc7 → 2.0.0-rc8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -746,6 +746,10 @@ select {
746
746
  border-width: 0;
747
747
  }
748
748
 
749
+ .pointer-events-none {
750
+ pointer-events: none;
751
+ }
752
+
749
753
  .static {
750
754
  position: static;
751
755
  }
@@ -1015,6 +1019,10 @@ select {
1015
1019
  bottom: 24rem;
1016
1020
  }
1017
1021
 
1022
+ .left-0 {
1023
+ left: 0px;
1024
+ }
1025
+
1018
1026
  .left-1 {
1019
1027
  left: 0.25rem;
1020
1028
  }
@@ -27908,6 +27916,11 @@ select {
27908
27916
  border-left-color: rgb(76 29 149 / 0.95);
27909
27917
  }
27910
27918
 
27919
+ .border-l-white {
27920
+ --tw-border-opacity: 1;
27921
+ border-left-color: rgb(255 255 255 / var(--tw-border-opacity));
27922
+ }
27923
+
27911
27924
  .border-l-yellow-100 {
27912
27925
  --tw-border-opacity: 1;
27913
27926
  border-left-color: rgb(255 245 212 / var(--tw-border-opacity));
@@ -54349,6 +54362,10 @@ select {
54349
54362
  padding-left: 0.75rem;
54350
54363
  }
54351
54364
 
54365
+ .pl-7 {
54366
+ padding-left: 1.75rem;
54367
+ }
54368
+
54352
54369
  .pl-\[10px\] {
54353
54370
  padding-left: 10px;
54354
54371
  }
@@ -54365,6 +54382,10 @@ select {
54365
54382
  padding-right: 1rem;
54366
54383
  }
54367
54384
 
54385
+ .pr-7 {
54386
+ padding-right: 1.75rem;
54387
+ }
54388
+
54368
54389
  .pr-9 {
54369
54390
  padding-right: 2.25rem;
54370
54391
  }
@@ -63138,6 +63159,14 @@ select {
63138
63159
  transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
63139
63160
  }
63140
63161
 
63162
+ .focus-within\:z-10:focus-within {
63163
+ z-index: 10;
63164
+ }
63165
+
63166
+ .focus-within\:z-20:focus-within {
63167
+ z-index: 20;
63168
+ }
63169
+
63141
63170
  .focus-within\:\!border-gray-300:focus-within {
63142
63171
  --tw-border-opacity: 1 !important;
63143
63172
  border-color: rgb(209 213 219 / var(--tw-border-opacity)) !important;
@@ -1,5 +1,5 @@
1
1
  import { IAvatarProps, IBadgeProps, IButtonProps, ICapsuleProps, IDynamicIconProps, IIconWithShadowProps, ILoaderProps, IRadialProgressProps, UnifiedIconName, IconName, FAIconName, BTNActionType, Avatar, Badge, Button, Capsule, DynamicIcon, IconWithShadow, Loader, RadialProgress, isFAIcon, isHeroIcon, isTablerIcon, isUnifiedIconName } from "./atoms";
2
2
  import { ICheckboxProps, IComboboxProps, IInputFieldProps, IInputLabelProps, INestedInputButtonProps, IRadioProps, ISelectProps, ITextareaProps, IToggleSwitchProps, AcceptedInputTypes, Checkbox, Combobox, InputField, InputLabel, NestedInputButton, Radio, Select, Textarea, ToggleSwitch, TextInput, ITextInputProps } from "./molecules";
3
- import { IAnimatedLabelInputProps, IButtonDropdownProps, IDropdownClassnames, IDropdownProps, IEmptySectionPlaceholderProps, IItemProp, IFormInputWithAddonsProps, AnimatedLabelInput, ButtonDropdown, Dropdown, EmptySectionPlaceholder, FormInputWithAddons } from "./organisms";
4
- export type { IAvatarProps, IBadgeProps, IButtonProps, ICapsuleProps, IDynamicIconProps, IIconWithShadowProps, ILoaderProps, IRadialProgressProps, ICheckboxProps, IComboboxProps, IInputFieldProps, IInputLabelProps, INestedInputButtonProps, IRadioProps, ISelectProps, ITextareaProps, IToggleSwitchProps, AcceptedInputTypes, IAnimatedLabelInputProps, IButtonDropdownProps, IDropdownClassnames, IDropdownProps, IEmptySectionPlaceholderProps, IItemProp, IFormInputWithAddonsProps, UnifiedIconName, IconName, FAIconName, BTNActionType, ITextInputProps };
5
- export { Avatar, Checkbox, Combobox, InputField, InputLabel, NestedInputButton, Radio, Select, Textarea, ToggleSwitch, AnimatedLabelInput, ButtonDropdown, Dropdown, EmptySectionPlaceholder, FormInputWithAddons, Badge, Button, Capsule, DynamicIcon, IconWithShadow, Loader, RadialProgress, isFAIcon, isHeroIcon, isTablerIcon, isUnifiedIconName, TextInput };
3
+ import { IAnimatedLabelInputProps, IButtonDropdownProps, IDropdownClassnames, IDropdownProps, IEmptySectionPlaceholderProps, IItemProp, IFormInputWithAddonsProps, AnimatedLabelInput, ButtonDropdown, Dropdown, EmptySectionPlaceholder, FormInputWithAddons, TextInputSelect, ITextInputSelectProps } from "./organisms";
4
+ export type { IAvatarProps, IBadgeProps, IButtonProps, ICapsuleProps, ITextInputSelectProps, IDynamicIconProps, IIconWithShadowProps, ILoaderProps, IRadialProgressProps, ICheckboxProps, IComboboxProps, IInputFieldProps, IInputLabelProps, INestedInputButtonProps, IRadioProps, ISelectProps, ITextareaProps, IToggleSwitchProps, AcceptedInputTypes, IAnimatedLabelInputProps, IButtonDropdownProps, IDropdownClassnames, IDropdownProps, IEmptySectionPlaceholderProps, IItemProp, IFormInputWithAddonsProps, UnifiedIconName, IconName, FAIconName, BTNActionType, ITextInputProps };
5
+ export { Avatar, Checkbox, Combobox, InputField, InputLabel, NestedInputButton, Radio, Select, Textarea, ToggleSwitch, AnimatedLabelInput, ButtonDropdown, Dropdown, EmptySectionPlaceholder, FormInputWithAddons, Badge, Button, Capsule, DynamicIcon, IconWithShadow, Loader, RadialProgress, isFAIcon, isHeroIcon, isTablerIcon, isUnifiedIconName, TextInput, TextInputSelect };
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- export type AcceptedInputTypes = "date" | "datetime-local" | "email" | "month" | "number" | "password" | "search" | "submit" | "tel" | "text" | "url";
2
+ export type AcceptedInputTypes = "date" | "datetime-local" | "email" | "month" | "number" | "password" | "search" | "submit" | "tel" | "text" | "url" | "currency";
3
3
  export interface IInputFieldProps extends React.ComponentPropsWithoutRef<"input"> {
4
4
  /** Callback on change */
5
5
  handleChange: (value: string) => void;
@@ -0,0 +1,16 @@
1
+ import { FC } from "react";
2
+ export type SelectOptions = {
3
+ label: string;
4
+ value: string;
5
+ };
6
+ export interface InputSelectProps {
7
+ align: "left" | "right";
8
+ /** Show the CTA without Background color and a border seperator */
9
+ inputOptions: SelectOptions[];
10
+ /** Onclick callback */
11
+ onSelectOption?(value: string): void;
12
+ className?: string;
13
+ isDisabled?: boolean;
14
+ }
15
+ /** Comment */
16
+ export declare const InputSelect: FC<InputSelectProps>;
@@ -0,0 +1,48 @@
1
+ import { FC } from "react";
2
+ import { AcceptedInputTypes } from "@/stories/molecules";
3
+ export type SelectOptions = {
4
+ label: string;
5
+ value: string;
6
+ };
7
+ export interface ITextInputSelectProps {
8
+ /** Input type*/
9
+ type: AcceptedInputTypes;
10
+ /** Input ID */
11
+ id?: string;
12
+ /** Input Name */
13
+ name?: string;
14
+ /** Label for the input */
15
+ label?: string;
16
+ /** placeholder for the input */
17
+ placeholder?: string;
18
+ /** Force the focus state on the input */
19
+ isFocused?: boolean;
20
+ /** Error state */
21
+ isError?: boolean;
22
+ /** If field is required */
23
+ isRequired?: boolean;
24
+ /** Disabled state */
25
+ isDisabled?: boolean;
26
+ /** Set default value */
27
+ defaultValue?: string;
28
+ /** Set value */
29
+ value: string;
30
+ /** Message shown under the text field */
31
+ message?: string;
32
+ /** Input character counter */
33
+ isShowCounter?: boolean;
34
+ /** Max length of input character */
35
+ maxLength?: number;
36
+ /** Select input location */
37
+ selectLocation?: "left" | "right";
38
+ /** Prefix */
39
+ prefix?: string;
40
+ /** List of options to show on the select field */
41
+ inputOptions?: SelectOptions[];
42
+ /** Callback on base input */
43
+ onChange?(value: string): void;
44
+ /** Callback on input select field */
45
+ onSelectOption?(value: string): void;
46
+ }
47
+ declare const TextInputSelect: FC<ITextInputSelectProps>;
48
+ export default TextInputSelect;
@@ -0,0 +1,3 @@
1
+ import TextInputSelect, { ITextInputSelectProps } from "./TextInputSelect";
2
+ export type { ITextInputSelectProps };
3
+ export default TextInputSelect;
@@ -3,5 +3,6 @@ import ButtonDropdown, { IButtonDropdownProps } from "./ButtonDropdown";
3
3
  import Dropdown, { IDropdownClassnames, IDropdownProps, IItemProp } from "./DropdownComponent";
4
4
  import EmptySectionPlaceholder, { IEmptySectionPlaceholderProps } from "./EmptySectionPlaceholder";
5
5
  import FormInputWithAddons, { IFormInputWithAddonsProps } from "./FormInputWithAddons";
6
- export type { IAnimatedLabelInputProps, IButtonDropdownProps, IDropdownClassnames, IDropdownProps, IEmptySectionPlaceholderProps, IItemProp, IFormInputWithAddonsProps };
7
- export { AnimatedLabelInput, ButtonDropdown, Dropdown, EmptySectionPlaceholder, FormInputWithAddons };
6
+ import TextInputSelect, { ITextInputSelectProps } from "./TextInputSelect";
7
+ export type { IAnimatedLabelInputProps, IButtonDropdownProps, IDropdownClassnames, IDropdownProps, IEmptySectionPlaceholderProps, IItemProp, IFormInputWithAddonsProps, ITextInputSelectProps };
8
+ export { AnimatedLabelInput, ButtonDropdown, Dropdown, EmptySectionPlaceholder, FormInputWithAddons, TextInputSelect };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agility/plenum-ui",
3
- "version": "2.0.0-rc7",
3
+ "version": "2.0.0-rc8",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
package/stories/index.ts CHANGED
@@ -62,7 +62,9 @@ import {
62
62
  ButtonDropdown,
63
63
  Dropdown,
64
64
  EmptySectionPlaceholder,
65
- FormInputWithAddons
65
+ FormInputWithAddons,
66
+ TextInputSelect,
67
+ ITextInputSelectProps
66
68
  } from "./organisms"
67
69
 
68
70
  export type {
@@ -70,6 +72,7 @@ export type {
70
72
  IBadgeProps,
71
73
  IButtonProps,
72
74
  ICapsuleProps,
75
+ ITextInputSelectProps,
73
76
  IDynamicIconProps,
74
77
  IIconWithShadowProps,
75
78
  ILoaderProps,
@@ -124,5 +127,6 @@ export {
124
127
  isHeroIcon,
125
128
  isTablerIcon,
126
129
  isUnifiedIconName,
127
- TextInput
130
+ TextInput,
131
+ TextInputSelect
128
132
  }
@@ -13,6 +13,7 @@ export type AcceptedInputTypes =
13
13
  | "tel"
14
14
  | "text"
15
15
  | "url"
16
+ | "currency"
16
17
 
17
18
  export interface IInputFieldProps extends React.ComponentPropsWithoutRef<"input"> {
18
19
  /** Callback on change */
@@ -0,0 +1,59 @@
1
+ import React, { FC, useState } from "react"
2
+ import { default as cn } from "classnames"
3
+
4
+ export type SelectOptions = {
5
+ label: string
6
+ value: string
7
+ }
8
+ export interface InputSelectProps {
9
+ align: "left" | "right"
10
+ /** Show the CTA without Background color and a border seperator */
11
+ inputOptions: SelectOptions[]
12
+ /** Onclick callback */
13
+ onSelectOption?(value: string): void
14
+ className?: string
15
+ isDisabled?: boolean
16
+ }
17
+
18
+ /** Comment */
19
+ export const InputSelect: FC<InputSelectProps> = ({
20
+ inputOptions,
21
+ onSelectOption,
22
+ align = "right",
23
+ className,
24
+ isDisabled
25
+ }: InputSelectProps): JSX.Element | null => {
26
+ const [selectedOption, setSelectedOption] = useState<string>(inputOptions[0].value)
27
+
28
+ const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
29
+ const targetValue = e.target.value
30
+ onSelectOption && onSelectOption(targetValue)
31
+ setSelectedOption(targetValue)
32
+ }
33
+
34
+ if (!inputOptions?.length) return null
35
+ return (
36
+ <select
37
+ className={cn(
38
+ "relative z-10 inline-flex items-center space-x-2 border border-gray-300 bg-white px-4 py-2 pr-7 text-sm font-medium",
39
+ "focus:border-purple-500 focus:outline-none focus:ring-1 focus:ring-purple-500",
40
+ align === "right"
41
+ ? "-ml-px rounded-r border-l-white text-gray-700"
42
+ : align === "left"
43
+ ? "-mr-px rounded-l border-r-white text-gray-500 focus-within:z-10"
44
+ : "",
45
+ !onSelectOption ? "cursor-default" : "",
46
+ className
47
+ )}
48
+ onChange={handleChange}
49
+ value={selectedOption}
50
+ disabled={isDisabled}
51
+ >
52
+ {inputOptions.map((option) => (
53
+ <option key={option.value} value={option.value}>
54
+ {option.label}
55
+ </option>
56
+ ))}
57
+ </select>
58
+ )
59
+ }
@@ -0,0 +1,33 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+ import TextInputSelect from "."
3
+
4
+ const meta: Meta<typeof TextInputSelect> = {
5
+ title: "Design System/organisms/TextInputSelect",
6
+ component: TextInputSelect,
7
+ tags: ["autodocs"],
8
+ argTypes: {}
9
+ }
10
+
11
+ export default meta
12
+ type Story = StoryObj<typeof TextInputSelect>
13
+ export const DefaultTextInputSelectStory: Story = {
14
+ args: {
15
+ isFocused: false,
16
+ isError: false,
17
+ id: "input",
18
+ name: "input",
19
+ defaultValue: "",
20
+ isRequired: false,
21
+ isDisabled: false,
22
+ isShowCounter: false,
23
+ label: "Currency",
24
+ placeholder: "420.69",
25
+ type: "currency",
26
+ inputOptions: [
27
+ { label: "USD", value: "USD" },
28
+ { label: "CAD", value: "CAD" },
29
+ { label: "EUR", value: "EUR" }
30
+ ],
31
+ prefix: "$"
32
+ }
33
+ }
@@ -0,0 +1,186 @@
1
+ import React, { FC, useEffect, useId, useRef, useState } from "react"
2
+ import { default as cn } from "classnames"
3
+
4
+ import { InputSelect } from "./InputSelect"
5
+ import { AcceptedInputTypes, InputField } from "@/stories/molecules"
6
+ import InputCounter from "@/stories/molecules/inputs/InputCounter"
7
+
8
+ export type SelectOptions = {
9
+ label: string
10
+ value: string
11
+ }
12
+
13
+ export interface ITextInputSelectProps {
14
+ /** Input type*/
15
+ type: AcceptedInputTypes
16
+ /** Input ID */
17
+ id?: string
18
+ /** Input Name */
19
+ name?: string
20
+ /** Label for the input */
21
+ label?: string
22
+ /** placeholder for the input */
23
+ placeholder?: string
24
+ /** Force the focus state on the input */
25
+ isFocused?: boolean
26
+ /** Error state */
27
+ isError?: boolean
28
+ /** If field is required */
29
+ isRequired?: boolean
30
+ /** Disabled state */
31
+ isDisabled?: boolean
32
+ /** Set default value */
33
+ defaultValue?: string
34
+ /** Set value */
35
+ value: string
36
+ /** Message shown under the text field */
37
+ message?: string
38
+ /** Input character counter */
39
+ isShowCounter?: boolean
40
+ /** Max length of input character */
41
+ maxLength?: number
42
+ /** Select input location */
43
+ selectLocation?: "left" | "right"
44
+ /** Prefix */
45
+ prefix?: string
46
+ /** List of options to show on the select field */
47
+ inputOptions?: SelectOptions[]
48
+ /** Callback on base input */
49
+ onChange?(value: string): void
50
+ /** Callback on input select field */
51
+ onSelectOption?(value: string): void
52
+ }
53
+
54
+ const TextInputSelect: FC<ITextInputSelectProps> = ({
55
+ label,
56
+ isFocused,
57
+ isError,
58
+ id,
59
+ name,
60
+ isRequired,
61
+ type,
62
+ defaultValue,
63
+ isDisabled,
64
+ message,
65
+ isShowCounter,
66
+ maxLength,
67
+ placeholder,
68
+ inputOptions,
69
+ selectLocation = "right",
70
+ prefix,
71
+ onChange,
72
+ onSelectOption,
73
+ value: externalValue
74
+ }: ITextInputSelectProps) => {
75
+ const [isFocus, setIsFocus] = useState<boolean>(Boolean(isFocused))
76
+ const [value, setValue] = useState<string>(defaultValue || "")
77
+ const inputRef = useRef<HTMLInputElement>(null)
78
+
79
+ const uniqueID = useId()
80
+ if (!id) id = `select-${uniqueID}`
81
+ if (!name) name = id
82
+
83
+ useEffect(() => {
84
+ setValue(externalValue)
85
+ }, [externalValue])
86
+
87
+ // set force focus
88
+ useEffect(() => {
89
+ const input = inputRef.current
90
+ if (!input || isFocus === undefined || isFocused === undefined || isDisabled) return
91
+ if (isFocus || isFocused) {
92
+ input.focus()
93
+ } else {
94
+ input.blur()
95
+ }
96
+ }, [isFocus, isFocused])
97
+
98
+ // set label as active if default value is set
99
+ useEffect(() => {
100
+ const input = inputRef.current
101
+ if (!input || defaultValue === undefined || defaultValue === "") return
102
+ }, [defaultValue])
103
+
104
+ const handleInputFocus = (): void => {
105
+ setIsFocus(true)
106
+ // add other focus effects here
107
+ }
108
+
109
+ const handleInputBlur = (): void => {
110
+ setIsFocus(false)
111
+ // add other focus effects here
112
+ }
113
+ const labelStyles = cn("block inline-block font-medium transition-all text-sm text-gray-700 mb-1", {
114
+ "text-red-500 bg-white": isError
115
+ })
116
+
117
+ const discriptionStyles = cn("text-sm mt-1 block", { "text-gray-500": !isError }, { "text-red-500": isError })
118
+
119
+ return (
120
+ <div>
121
+ {label && (
122
+ <label htmlFor={id} className={labelStyles}>
123
+ {label}
124
+ {isRequired && <span className="text-red-500"> *</span>}
125
+ </label>
126
+ )}
127
+ <div className="flex">
128
+ {inputOptions?.length && selectLocation === "left" && (
129
+ <InputSelect
130
+ inputOptions={inputOptions}
131
+ align="left"
132
+ onSelectOption={onSelectOption}
133
+ className={cn(isError ? "border-red-500" : "")}
134
+ isDisabled={isDisabled}
135
+ />
136
+ )}
137
+ <div className="relative flex-grow focus-within:z-20">
138
+ {prefix && (
139
+ <div className="pointer-events-none pr-10 absolute inset-y-0 left-0 flex items-center pl-3">
140
+ <span className="text-gray-500 sm:text-sm">{prefix}</span>
141
+ </div>
142
+ )}
143
+ <InputField
144
+ onFocus={handleInputFocus}
145
+ onBlur={handleInputBlur}
146
+ handleChange={(v) => onChange && onChange(v)}
147
+ ref={inputRef}
148
+ type={type}
149
+ name={name}
150
+ id={id}
151
+ className={cn(
152
+ "w-full border border-gray-300 py-2 px-3 text-sm font-normal leading-5",
153
+ "focus:border-purple-500 focus:outline-none focus:ring-1 focus:ring-purple-500 sm:text-sm",
154
+ selectLocation === "right" ? `rounded-l` : `rounded-r`,
155
+ isError ? "border-red-500" : "",
156
+ prefix ? `pl-7` : ""
157
+ )}
158
+ isDisabled={isDisabled}
159
+ defaultValue={defaultValue}
160
+ value={value}
161
+ maxLength={maxLength}
162
+ placeholder={placeholder}
163
+ />
164
+ </div>
165
+ {inputOptions?.length && selectLocation === "right" && (
166
+ <InputSelect
167
+ inputOptions={inputOptions}
168
+ align={"right"}
169
+ onSelectOption={onSelectOption}
170
+ isDisabled={isDisabled}
171
+ className={cn(isError ? "border-red-500" : "")}
172
+ />
173
+ )}
174
+ </div>
175
+ <div className="flex flex-row space-x-3">
176
+ <div className="grow">{message && <span className={discriptionStyles}>{message}</span>}</div>
177
+ {isShowCounter && (
178
+ <div className="shrink-0">
179
+ <InputCounter current={Number(value?.length)} limit={maxLength} />
180
+ </div>
181
+ )}
182
+ </div>
183
+ </div>
184
+ )
185
+ }
186
+ export default TextInputSelect
@@ -0,0 +1,3 @@
1
+ import TextInputSelect, { ITextInputSelectProps } from "./TextInputSelect"
2
+ export type { ITextInputSelectProps }
3
+ export default TextInputSelect
@@ -3,6 +3,7 @@ import ButtonDropdown, { IButtonDropdownProps } from "./ButtonDropdown"
3
3
  import Dropdown, { IDropdownClassnames, IDropdownProps, IItemProp } from "./DropdownComponent"
4
4
  import EmptySectionPlaceholder, { IEmptySectionPlaceholderProps } from "./EmptySectionPlaceholder"
5
5
  import FormInputWithAddons, { IFormInputWithAddonsProps } from "./FormInputWithAddons"
6
+ import TextInputSelect, { ITextInputSelectProps } from "./TextInputSelect"
6
7
 
7
8
  export type {
8
9
  IAnimatedLabelInputProps,
@@ -11,6 +12,7 @@ export type {
11
12
  IDropdownProps,
12
13
  IEmptySectionPlaceholderProps,
13
14
  IItemProp,
14
- IFormInputWithAddonsProps
15
+ IFormInputWithAddonsProps,
16
+ ITextInputSelectProps
15
17
  }
16
- export { AnimatedLabelInput, ButtonDropdown, Dropdown, EmptySectionPlaceholder, FormInputWithAddons }
18
+ export { AnimatedLabelInput, ButtonDropdown, Dropdown, EmptySectionPlaceholder, FormInputWithAddons, TextInputSelect }