@agility/plenum-ui 2.0.0-rc3 → 2.0.0-rc5

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.
@@ -0,0 +1,10 @@
1
+ import { FC } from "react";
2
+ export interface IInputCounterProps {
3
+ /** Counter limit */
4
+ limit: number | undefined;
5
+ /** Counter current number */
6
+ current: number;
7
+ }
8
+ /** Primary UI component for user interaction */
9
+ declare const InputCounter: FC<IInputCounterProps>;
10
+ export default InputCounter;
@@ -0,0 +1,2 @@
1
+ export { default } from './InputCounter';
2
+ export * from './InputCounter';
@@ -23,6 +23,8 @@ export interface IInputFieldProps extends React.ComponentPropsWithoutRef<"input"
23
23
  required?: boolean;
24
24
  /** use input psuedo classes for :valid and :invalid styles. on by default */
25
25
  clientSideCheck?: boolean;
26
+ /**ref for input */
27
+ ref?: React.Ref<HTMLInputElement>;
26
28
  }
27
29
  declare const InputField: React.FC<IInputFieldProps>;
28
30
  export default InputField;
@@ -0,0 +1,39 @@
1
+ import React from "react";
2
+ import { AcceptedInputTypes } from "../InputField";
3
+ export interface ITextInputProps {
4
+ /** Input type*/
5
+ type: AcceptedInputTypes;
6
+ /** Input ID */
7
+ id?: string;
8
+ /** Input Name */
9
+ name?: string;
10
+ /** Label for the input */
11
+ label?: string;
12
+ /** Force the focus state on the input */
13
+ isFocused?: boolean;
14
+ /** Error state */
15
+ isError?: boolean;
16
+ /** If field is required */
17
+ isRequired?: boolean;
18
+ /** Disabled state */
19
+ isDisabled?: boolean;
20
+ /** Readonly state */
21
+ isReadonly?: boolean;
22
+ /** Set default value */
23
+ defaultValue?: string;
24
+ /** Message shown under the text field */
25
+ message?: string;
26
+ /** Input character counter */
27
+ isShowCounter?: boolean;
28
+ /** Max length of input character */
29
+ maxLength?: number;
30
+ /** Callback on change */
31
+ onChange(value: string): void;
32
+ /** input value */
33
+ value: string;
34
+ /**Placeholder input text*/
35
+ placeholder?: string;
36
+ className?: string;
37
+ }
38
+ declare const _TextInput: React.ForwardRefExoticComponent<ITextInputProps & React.RefAttributes<HTMLInputElement>>;
39
+ export default _TextInput;
@@ -0,0 +1,4 @@
1
+ import TextInput from "./TextInput";
2
+ import { ITextInputProps } from "./TextInput";
3
+ export type { ITextInputProps };
4
+ export default TextInput;
@@ -6,6 +6,7 @@ import NestedInputButton, { INestedInputButtonProps } from "./NestedInputButton"
6
6
  import Radio, { IRadioProps } from "./radio";
7
7
  import Select, { ISelectProps } from "./select";
8
8
  import TextAreaField, { ITextAreaFieldProps } from "./textArea";
9
+ import TextInput, { ITextInputProps } from "./TextInput";
9
10
  import ToggleSwitch, { IToggleSwitchProps } from "./toggleSwitch";
10
- export type { ICheckboxProps, IComboboxProps, IInputFieldProps, IInputLabelProps, INestedInputButtonProps, IRadioProps, ISelectProps, ITextAreaFieldProps, IToggleSwitchProps, AcceptedInputTypes };
11
- export { Checkbox, Combobox, InputField, InputLabel, NestedInputButton, Radio, Select, TextAreaField, ToggleSwitch };
11
+ export type { ICheckboxProps, IComboboxProps, IInputFieldProps, IInputLabelProps, INestedInputButtonProps, IRadioProps, ISelectProps, ITextAreaFieldProps, ITextInputProps, IToggleSwitchProps, AcceptedInputTypes };
12
+ export { Checkbox, Combobox, InputField, InputLabel, NestedInputButton, Radio, Select, TextAreaField, ToggleSwitch, TextInput };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agility/plenum-ui",
3
- "version": "2.0.0-rc3",
3
+ "version": "2.0.0-rc5",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -17,7 +17,7 @@
17
17
  "storybook:tw": "tailwindcss -o ./lib/tailwind.css -w ",
18
18
  "storybook": "npm-run-all -p \"storybook:*\" ",
19
19
  "dev": "yarn storybook",
20
- "build:tw": "tailwindcss -o ./lib/tailwind.css",
20
+ "build:tw": "tailwindcss -o ./dist/lib/tailwind.css",
21
21
  "build:tsc": "yarn node build.js",
22
22
  "prepare": "yarn build",
23
23
  "build": "npm run clean && npm-run-all -s \"build:*\" ",
@@ -143,7 +143,7 @@ In your app entry point (i.e. \`_app.tsx\`), import the \`globals.css\` file fro
143
143
 
144
144
  ```jsx
145
145
  import "<RELATIVE_PATH>/globals.css";
146
- import "@agility/plenum-ui/lib/tailwind.css";
146
+ import "@agility/plenum-ui/dist/lib/tailwind.css";
147
147
  ```
148
148
 
149
149
  Make sure to add any additional styles before these two import statements to prevent overwriting the Plenum styling.
@@ -0,0 +1,18 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+ import InputCounter, { IInputCounterProps } from "./InputCounter"
3
+
4
+ const meta: Meta<typeof InputCounter> = {
5
+ title: "Design System/molecules/inputs/InputCounter",
6
+ component: InputCounter,
7
+ tags: ["autodocs"],
8
+ argTypes: {}
9
+ }
10
+
11
+ export default meta
12
+ type Story = StoryObj<typeof InputCounter>
13
+ export const DefaultInputCounterStory: Story = {
14
+ args: {
15
+ limit: 100,
16
+ current: 0
17
+ } as IInputCounterProps
18
+ }
@@ -0,0 +1,24 @@
1
+ import React, { FC } from "react"
2
+
3
+ export interface IInputCounterProps {
4
+ /** Counter limit */
5
+ limit: number | undefined
6
+ /** Counter current number */
7
+ current: number
8
+ }
9
+
10
+ /** Primary UI component for user interaction */
11
+ const InputCounter: FC<IInputCounterProps> = ({ current = 0, limit }) => {
12
+ return (
13
+ <div className="mt-1 text-center text-sm text-gray-500 flex gap-1">
14
+ <div className="currentCount">{current}</div>
15
+ {(limit || 0) > 0 && (
16
+ <>
17
+ <div>/</div>
18
+ <div className="limitCount">{limit}</div>
19
+ </>
20
+ )}
21
+ </div>
22
+ )
23
+ }
24
+ export default InputCounter
@@ -0,0 +1,3 @@
1
+
2
+ export { default } from './InputCounter';
3
+ export * from './InputCounter';
@@ -37,7 +37,8 @@ export interface IInputFieldProps extends React.ComponentPropsWithoutRef<"input"
37
37
  required?: boolean
38
38
  /** use input psuedo classes for :valid and :invalid styles. on by default */
39
39
  clientSideCheck?: boolean
40
- /** use placeholder string */
40
+ /**ref for input */
41
+ ref?: React.Ref<HTMLInputElement>
41
42
  }
42
43
 
43
44
  const InputField: React.FC<IInputFieldProps> = ({
@@ -54,16 +55,20 @@ const InputField: React.FC<IInputFieldProps> = ({
54
55
  clientSideCheck = true,
55
56
  placeholder,
56
57
  className,
58
+ ref,
57
59
  ...rest
58
60
  }) => {
61
+
59
62
  return (
60
63
  <input
61
64
  {...{
62
65
  type,
63
66
  id,
67
+ ref,
64
68
  name,
65
69
  value,
66
70
  onChange: (e) => {
71
+ console.log(e)
67
72
  handleChange(e.target.value)
68
73
  },
69
74
  autoFocus: isFocused,
@@ -0,0 +1,32 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+ import TextInput, { ITextInputProps } from "./TextInput"
3
+ import React from "react"
4
+
5
+ const meta: Meta<typeof TextInput> = {
6
+ title: "Design System/molecules/inputs/TextInput",
7
+ component: TextInput,
8
+ tags: ["autodocs"],
9
+ argTypes: {}
10
+ }
11
+
12
+ export default meta
13
+ type Story = StoryObj<typeof TextInput>
14
+
15
+ export const DefaultTextInputStory: Story = {
16
+ args: {
17
+ type: "text",
18
+ label: "Label",
19
+ isFocused: true,
20
+ isError: false,
21
+ id: "id",
22
+ name: "name",
23
+ isRequired: true,
24
+
25
+ isDisabled: false,
26
+ isReadonly: false,
27
+ message: "message",
28
+ isShowCounter: true,
29
+ maxLength: 100,
30
+ placeholder: "placeholder"
31
+ }
32
+ }
@@ -0,0 +1,162 @@
1
+ import React, { forwardRef, useEffect, useId, useRef, useState } from "react"
2
+ import { default as cn } from "classnames"
3
+ import InputLabel from "../InputLabel"
4
+ import InputField, { AcceptedInputTypes } from "../InputField"
5
+ import InputCounter from "../InputCounter"
6
+
7
+ export interface ITextInputProps {
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
+ /** Force the focus state on the input */
17
+ isFocused?: boolean
18
+ /** Error state */
19
+ isError?: boolean
20
+ /** If field is required */
21
+ isRequired?: boolean
22
+ /** Disabled state */
23
+ isDisabled?: boolean
24
+ /** Readonly state */
25
+ isReadonly?: boolean
26
+ /** Set default value */
27
+ defaultValue?: string
28
+ /** Message shown under the text field */
29
+ message?: string
30
+ /** Input character counter */
31
+ isShowCounter?: boolean
32
+ /** Max length of input character */
33
+ maxLength?: number
34
+ /** Callback on change */
35
+ onChange(value: string): void
36
+ /** input value */
37
+ value: string
38
+ /**Placeholder input text*/
39
+ placeholder?: string
40
+
41
+ className?: string
42
+ }
43
+
44
+ const TextInput = (
45
+ {
46
+ label,
47
+ isFocused,
48
+ isError,
49
+ id,
50
+ name,
51
+ isRequired,
52
+ type,
53
+ defaultValue,
54
+ isDisabled,
55
+ isReadonly,
56
+ message,
57
+ isShowCounter,
58
+ maxLength,
59
+ onChange,
60
+ placeholder,
61
+ value: externalValue,
62
+ className,
63
+ ...props
64
+ }: ITextInputProps,
65
+ ref: React.Ref<HTMLInputElement>
66
+ ) => {
67
+ const uniqueID = useId()
68
+ const [isFocus, setIsFocus] = useState<boolean>(Boolean(isFocused))
69
+
70
+ const [value, setValue] = useState<string>(externalValue || defaultValue || "")
71
+ const inputRef = useRef<HTMLInputElement>(null)
72
+
73
+ useEffect(() => {
74
+ //if the external value is updated by the parent component, reset the value in here...
75
+ if (externalValue !== undefined && externalValue !== null) {
76
+ setValue(externalValue)
77
+ }
78
+ }, [externalValue])
79
+
80
+ // set force focus
81
+ useEffect(() => {
82
+ const input = inputRef.current
83
+ if (!input || isFocus === undefined || isDisabled) return
84
+ if (isFocus) {
85
+ input.focus()
86
+ } else {
87
+ input.blur()
88
+ }
89
+ }, [isFocus])
90
+
91
+ // set label as active if default value is set
92
+ useEffect(() => {
93
+ const input = inputRef.current
94
+ if (!input || defaultValue === undefined || defaultValue === "") return
95
+ }, [defaultValue])
96
+
97
+ const handleInputFocus = () => setIsFocus(true)
98
+ // add other focus effects here
99
+
100
+ const handleInputBlur = () => setIsFocus(false)
101
+
102
+ if (!id) id = `input-${uniqueID}`
103
+ if (!name) name = id
104
+
105
+ return (
106
+ <div className="relative">
107
+ <InputLabel
108
+ isPlaceholder={true}
109
+ label={label}
110
+ isRequired={isRequired}
111
+ id={id}
112
+ isError={isError}
113
+ isActive={true}
114
+ isDisabled={isDisabled}
115
+ />
116
+ <InputField
117
+ onFocus={handleInputFocus}
118
+ onBlur={handleInputBlur}
119
+ handleChange={(v) => setValue(v)}
120
+ ref={ref}
121
+ type={type}
122
+ name={name}
123
+ id={id}
124
+ className={cn(
125
+ "w-full rounded border py-2 px-3 text-sm font-normal leading-5",
126
+ { "border-gray-300": !isFocus && !isError },
127
+ {
128
+ "!border-purple-500 shadow-none outline-purple-500 focus:!ring-purple-500": isFocus && !isError
129
+ },
130
+ {
131
+ "!border-red-500 shadow-none focus:ring-red-500": isError
132
+ },
133
+ className
134
+ )}
135
+ isDisabled={isDisabled}
136
+ isReadonly={isReadonly}
137
+ value={value}
138
+ defaultValue={defaultValue}
139
+ maxLength={maxLength}
140
+ placeholder={placeholder}
141
+ {...props}
142
+ />
143
+ <div className="flex flex-row space-x-3">
144
+ <div className="grow">
145
+ {message && (
146
+ <span className={cn("mt-1 block text-sm", isError ? "text-red-500" : "text-gray-500")}>
147
+ {message}
148
+ </span>
149
+ )}
150
+ </div>
151
+ {isShowCounter && (
152
+ <div className="shrink-0">
153
+ <InputCounter current={Number(value?.length)} limit={maxLength} />
154
+ </div>
155
+ )}
156
+ </div>
157
+ </div>
158
+ )
159
+ }
160
+
161
+ const _TextInput = forwardRef<HTMLInputElement, ITextInputProps>(TextInput)
162
+ export default _TextInput
@@ -0,0 +1,5 @@
1
+ import TextInput from "./TextInput"
2
+ import { ITextInputProps } from "./TextInput"
3
+
4
+ export type { ITextInputProps }
5
+ export default TextInput
@@ -6,6 +6,7 @@ import NestedInputButton, { INestedInputButtonProps } from "./NestedInputButton"
6
6
  import Radio, { IRadioProps } from "./radio"
7
7
  import Select, { ISelectProps } from "./select"
8
8
  import TextAreaField, { ITextAreaFieldProps } from "./textArea"
9
+ import TextInput, { ITextInputProps } from "./TextInput"
9
10
  import ToggleSwitch, { IToggleSwitchProps } from "./toggleSwitch"
10
11
 
11
12
  export type {
@@ -17,8 +18,20 @@ export type {
17
18
  IRadioProps,
18
19
  ISelectProps,
19
20
  ITextAreaFieldProps,
21
+ ITextInputProps,
20
22
  IToggleSwitchProps,
21
23
  AcceptedInputTypes
22
24
  }
23
25
 
24
- export { Checkbox, Combobox, InputField, InputLabel, NestedInputButton, Radio, Select, TextAreaField, ToggleSwitch }
26
+ export {
27
+ Checkbox,
28
+ Combobox,
29
+ InputField,
30
+ InputLabel,
31
+ NestedInputButton,
32
+ Radio,
33
+ Select,
34
+ TextAreaField,
35
+ ToggleSwitch,
36
+ TextInput
37
+ }