powell-react 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. package/api/PowellProvider.tsx +37 -0
  2. package/api/api.ts +126 -0
  3. package/api/configService.ts +4 -0
  4. package/api/index.ts +4 -0
  5. package/api/powellDefaults.ts +11 -0
  6. package/components/AutoComplete/AutoComplete.scss +126 -0
  7. package/components/AutoComplete/AutoComplete.tsx +184 -0
  8. package/components/AutoComplete/index.ts +1 -0
  9. package/components/Button/Button.tsx +85 -0
  10. package/components/Button/index.ts +1 -0
  11. package/components/Checkbox/Checkbox.scss +35 -0
  12. package/components/Checkbox/Checkbox.tsx +136 -0
  13. package/components/Checkbox/index.ts +1 -0
  14. package/components/Dropdown/Dropdown.scss +126 -0
  15. package/components/Dropdown/Dropdown.tsx +184 -0
  16. package/components/Dropdown/index.ts +1 -0
  17. package/components/ErrorMessage/ErrorMessage.scss +7 -0
  18. package/components/ErrorMessage/ErrorMessage.tsx +23 -0
  19. package/components/ErrorMessage/index.ts +1 -0
  20. package/components/FormContainer/FormContainer.tsx +49 -0
  21. package/components/FormContainer/FormContext.tsx +17 -0
  22. package/components/FormContainer/index.ts +2 -0
  23. package/components/InputText/InputText.scss +126 -0
  24. package/components/InputText/InputText.tsx +184 -0
  25. package/components/InputText/index.ts +1 -0
  26. package/components/InputTextarea/InputTextarea.scss +126 -0
  27. package/components/InputTextarea/InputTextarea.tsx +181 -0
  28. package/components/InputTextarea/index.ts +1 -0
  29. package/hooks/index.ts +4 -0
  30. package/hooks/useApplyConfig.ts +36 -0
  31. package/hooks/useFormContext.ts +14 -0
  32. package/hooks/usePowellConfig.ts +64 -0
  33. package/hooks/useTransform.ts +27 -0
  34. package/index.js +1 -0
  35. package/models/common.ts +7 -0
  36. package/models/config.ts +86 -0
  37. package/models/forms.ts +23 -0
  38. package/models/index.ts +3 -0
  39. package/package.json +16 -0
  40. package/themes/arya-blue.css +1 -0
  41. package/themes/arya-green.css +1 -0
  42. package/themes/arya-orange.css +1 -0
  43. package/themes/arya-purple.css +1 -0
  44. package/themes/bootstrap4-dark-blue.css +1 -0
  45. package/themes/bootstrap4-dark-purple.css +1 -0
  46. package/themes/bootstrap4-light-blue.css +1 -0
  47. package/themes/bootstrap4-light-purple.css +1 -0
  48. package/themes/fluent-light.css +1 -0
  49. package/themes/lara-dark-amber.css +1 -0
  50. package/themes/lara-dark-blue.css +1 -0
  51. package/themes/lara-dark-cyan.css +1 -0
  52. package/themes/lara-dark-green.css +1 -0
  53. package/themes/lara-dark-indigo.css +1 -0
  54. package/themes/lara-dark-pink.css +1 -0
  55. package/themes/lara-dark-purple.css +1 -0
  56. package/themes/lara-dark-teal.css +1 -0
  57. package/themes/lara-light-amber.css +1 -0
  58. package/themes/lara-light-blue.css +1 -0
  59. package/themes/lara-light-cyan.css +1 -0
  60. package/themes/lara-light-green.css +1 -0
  61. package/themes/lara-light-indigo.css +1 -0
  62. package/themes/lara-light-pink.css +1 -0
  63. package/themes/lara-light-purple.css +1 -0
  64. package/themes/lara-light-teal.css +1 -0
  65. package/themes/luna-amber.css +1 -0
  66. package/themes/luna-blue.css +1 -0
  67. package/themes/luna-green.css +1 -0
  68. package/themes/luna-pink.css +1 -0
  69. package/themes/md-dark-deeppurple.css +1 -0
  70. package/themes/md-dark-indigo.css +1 -0
  71. package/themes/md-light-deeppurple.css +1 -0
  72. package/themes/md-light-indigo.css +1 -0
  73. package/themes/mdc-dark-deeppurple.css +1 -0
  74. package/themes/mdc-dark-indigo.css +1 -0
  75. package/themes/mdc-light-deeppurple.css +1 -0
  76. package/themes/mdc-light-indigo.css +1 -0
  77. package/themes/mira.css +1 -0
  78. package/themes/nano.css +1 -0
  79. package/themes/nova-accent.css +1 -0
  80. package/themes/nova-alt.css +1 -0
  81. package/themes/nova.css +1 -0
  82. package/themes/rhea.css +1 -0
  83. package/themes/saga-blue.css +1 -0
  84. package/themes/saga-green.css +1 -0
  85. package/themes/saga-orange.css +1 -0
  86. package/themes/saga-purple.css +1 -0
  87. package/themes/soho-dark.css +1 -0
  88. package/themes/soho-light.css +1 -0
  89. package/themes/tailwind-light.css +1 -0
  90. package/themes/vela-blue.css +1 -0
  91. package/themes/vela-green.css +1 -0
  92. package/themes/vela-orange.css +1 -0
  93. package/themes/vela-purple.css +1 -0
  94. package/themes/viva-dark.css +1 -0
  95. package/themes/viva-light.css +1 -0
  96. package/utils/globalState.ts +96 -0
  97. package/utils/index.ts +2 -0
  98. package/utils/utilsService.tsx +39 -0
@@ -0,0 +1,136 @@
1
+ import {ChangeEvent, ReactNode, useCallback, useRef, useState} from "react";
2
+ import {FixLabelPosition} from "@powell/models";
3
+ import {PrimeCheckbox, PrimeCheckboxProps, primeClassNames, PrimeUniqueComponentId} from "@powell/api";
4
+ import {transformer} from "@powell/utils";
5
+ import {Field, FieldProps} from "formik";
6
+ import {useApplyConfig, useFormContext} from "@powell/hooks";
7
+ import {SafeAny} from "@powell/models/common";
8
+ import {ErrorMessage} from "@powell/components/ErrorMessage";
9
+ import './Checkbox.scss';
10
+
11
+ interface CheckboxProps extends Omit<PrimeCheckboxProps, 'checked'> {
12
+ checked?: boolean;
13
+ name?: string;
14
+ parseError?: (error: string) => ReactNode;
15
+ transform?: {
16
+ input?: (value: SafeAny) => string;
17
+ output?: (event: ChangeEvent<HTMLInputElement>) => SafeAny;
18
+ };
19
+ showRequiredStar?: boolean;
20
+ rtl?: boolean;
21
+ label?: string;
22
+ hint?: string;
23
+ labelPosition?: FixLabelPosition;
24
+ }
25
+
26
+ export const Checkbox = (props: CheckboxProps) => {
27
+ props = useApplyConfig(props, {sizable: false, isFixLabel: true});
28
+ const {
29
+ parseError,
30
+ name,
31
+ transform = {},
32
+ labelPosition,
33
+ rtl,
34
+ showRequiredStar,
35
+ variant,
36
+ ...rest
37
+ } = props;
38
+
39
+ const inputId = useRef(PrimeUniqueComponentId());
40
+
41
+ // Check if we're in Formik context
42
+ const formContext = useFormContext();
43
+ const withinForm = !!formContext && !!name;
44
+ const isRequired = withinForm && formContext.validationSchema?.fields?.[name].tests?.some((t: SafeAny) => t.OPTIONS.name === 'required');
45
+
46
+ // Internal state for non-Formik usage
47
+ const [internalValue, setInternalValue] = useState(rest.checked);
48
+
49
+ const rootEl = useCallback(() => {
50
+ const commonProps = {
51
+ ...rest,
52
+ variant,
53
+ inputId: inputId.current,
54
+ name,
55
+ };
56
+
57
+ if (withinForm) {
58
+ // if in Formik context
59
+ return (
60
+ <Field name={name}>
61
+ {({field, meta}: FieldProps) => {
62
+ const {value, onChange} = transformer({
63
+ value: field.value,
64
+ onChange: (event: boolean) => formContext.setFieldValue(name, event),
65
+ transform: {
66
+ input: transform.input ?? (value => value),
67
+ output: transform.output ?? (event => event.target.checked)
68
+ }
69
+ });
70
+
71
+ return (
72
+ <>
73
+ <PrimeCheckbox
74
+ {...commonProps}
75
+ checked={value}
76
+ onChange={(event) => {
77
+ onChange(event);
78
+ rest.onChange?.(event);
79
+ }}
80
+ invalid={!!meta.error}
81
+ />
82
+ <ErrorMessage message={meta.error} parseError={parseError} hint={rest.hint}/>
83
+ </>
84
+ );
85
+ }}
86
+ </Field>
87
+ );
88
+ } else {
89
+ // if outside Formik context
90
+ const {value, onChange} = transformer({
91
+ value: internalValue,
92
+ onChange: (event: boolean) => setInternalValue(event),
93
+ transform: {
94
+ input: transform.input ?? (value => value),
95
+ output: transform.output ?? (event => event.target.checked)
96
+ }
97
+ });
98
+
99
+ return (
100
+ <PrimeCheckbox
101
+ {...commonProps}
102
+ checked={value}
103
+ onChange={(event) => {
104
+ onChange(event);
105
+ rest.onChange?.(event);
106
+ }}
107
+ onBlur={rest.onBlur}
108
+ />
109
+ );
110
+ }
111
+ }, [internalValue, props]);
112
+
113
+ const labelEl = rest.label && (
114
+ <label htmlFor={inputId.current}>
115
+ {rest.label}
116
+ {isRequired && showRequiredStar ? '*' : ''}
117
+ </label>
118
+ );
119
+
120
+ return (
121
+ <div className={primeClassNames('checkbox-wrapper',
122
+ `variant-${variant}`,
123
+ {
124
+ [`label-${labelPosition}`]: rest.label,
125
+ 'is-rtl': rtl,
126
+ 'is-ltr': !rtl,
127
+ })}>
128
+ <div className="field">
129
+ {labelEl}
130
+ <div className={primeClassNames('field-inner')}>
131
+ {rootEl()}
132
+ </div>
133
+ </div>
134
+ </div>
135
+ );
136
+ };
@@ -0,0 +1 @@
1
+ export * from "./Checkbox";
@@ -0,0 +1,126 @@
1
+ .dropdown-wrapper {
2
+ .field {
3
+ display: flex;
4
+ gap: 0.25rem 1rem;
5
+
6
+ > div {
7
+ flex-grow: 1;
8
+ }
9
+ }
10
+
11
+ :where(.p-inputtext, .p-dropdown) {
12
+ width: 100%;
13
+ }
14
+
15
+ .p-icon-field {
16
+ .p-input-icon {
17
+ z-index: 5;
18
+ color: var(--text-color-secondary);
19
+ }
20
+
21
+ &.p-icon-field-right {
22
+ :where(.p-dropdown) {
23
+ padding-right: 2.5rem;
24
+ }
25
+
26
+ .p-input-icon {
27
+ right: 0.75rem;
28
+ left: auto;
29
+ }
30
+ }
31
+
32
+ &.p-icon-field-left {
33
+ :where(.p-dropdown) {
34
+ padding-left: 2.5rem;
35
+ }
36
+
37
+ .p-input-icon {
38
+ left: 0.75rem;
39
+ right: auto;
40
+ }
41
+ }
42
+ }
43
+
44
+ &.label-fix-side .field {
45
+ flex-direction: row;
46
+ align-items: center;
47
+ }
48
+
49
+ &.label-fix-top .field {
50
+ flex-direction: column;
51
+
52
+ label {
53
+ margin-bottom: 0.25rem;
54
+ }
55
+ }
56
+
57
+ &.addon-before {
58
+ [class*="icon-"] {
59
+ :where(.p-inputtext, .p-dropdown) {
60
+ border-radius: 0 var(--border-radius) var(--border-radius) 0;
61
+ }
62
+ }
63
+ }
64
+
65
+ &.addon-after {
66
+ &.label-float {
67
+ .p-inputgroup-addon {
68
+ border-left: 0;
69
+ }
70
+ }
71
+
72
+ [class*="icon-"] {
73
+ :where(.p-inputtext, .p-dropdown) {
74
+ border-radius: var(--border-radius) 0 0 var(--border-radius);
75
+ }
76
+ }
77
+ }
78
+
79
+ &[class*="addon-"] {
80
+ .p-inputgroup {
81
+ .p-icon-field,
82
+ .p-float-label {
83
+ flex-grow: 1;
84
+ }
85
+ }
86
+
87
+ &.addon-before :where(.p-inputtext, .p-dropdown) {
88
+ border-radius: 0 var(--border-radius) var(--border-radius) 0;
89
+ }
90
+
91
+ &.addon-after :where(.p-inputtext, .p-dropdown) {
92
+ border-radius: var(--border-radius) 0 0 var(--border-radius);
93
+ }
94
+ }
95
+
96
+ &.is-ltr {
97
+ direction: ltr;
98
+
99
+ &.label-float {
100
+ &.icon-left .field label {
101
+ left: 2.5rem;
102
+ }
103
+ }
104
+ }
105
+
106
+ &.is-rtl {
107
+ direction: rtl;
108
+
109
+ &.label-float {
110
+ label {
111
+ left: auto;
112
+ right: 0.75rem;
113
+ }
114
+
115
+ &.icon-right .field label {
116
+ right: 2.5rem;
117
+ }
118
+ }
119
+
120
+ &[class*="addon-"] {
121
+ .p-inputgroup {
122
+ flex-direction: row-reverse;
123
+ }
124
+ }
125
+ }
126
+ }
@@ -0,0 +1,184 @@
1
+ import {ChangeEvent, ReactNode, useCallback, useRef, useState} from "react";
2
+ import {Addon, LabelPosition, Size} from "@powell/models";
3
+ import {
4
+ primeClassNames,
5
+ PrimeFloatLabel,
6
+ PrimeIconField,
7
+ PrimeIconFieldProps,
8
+ PrimeInputIcon,
9
+ PrimeDropdown,
10
+ PrimeDropdownProps,
11
+ PrimeUniqueComponentId
12
+ } from "@powell/api";
13
+ import {getAddonTemplate, transformer} from "@powell/utils";
14
+ import {Field, FieldProps} from "formik";
15
+ import {useApplyConfig, useFormContext} from "@powell/hooks";
16
+ import {SafeAny} from "@powell/models/common";
17
+ import {ErrorMessage} from "@powell/components/ErrorMessage";
18
+ import './Dropdown.scss';
19
+
20
+ interface DropdownProps extends PrimeDropdownProps {
21
+ name?: string;
22
+ parseError?: (error: string) => ReactNode;
23
+ transform?: {
24
+ input?: (value: SafeAny) => string;
25
+ output?: (event: ChangeEvent<HTMLInputElement>) => SafeAny;
26
+ };
27
+ showRequiredStar?: boolean;
28
+ rtl?: boolean;
29
+ label?: string;
30
+ icon?: string | ReactNode;
31
+ hint?: string;
32
+ inputSize?: Size;
33
+ addon?: Addon;
34
+ iconPosition?: PrimeIconFieldProps["iconPosition"];
35
+ labelPosition?: LabelPosition;
36
+ }
37
+
38
+ export const Dropdown = (props: DropdownProps) => {
39
+ props = useApplyConfig(props);
40
+ const {
41
+ parseError,
42
+ name,
43
+ transform = {},
44
+ iconPosition = 'left',
45
+ labelPosition,
46
+ addon,
47
+ icon,
48
+ rtl,
49
+ showRequiredStar,
50
+ variant,
51
+ inputSize,
52
+ ...rest
53
+ } = props;
54
+
55
+ const inputId = useRef(PrimeUniqueComponentId());
56
+
57
+ // Check if we're in Formik context
58
+ const formContext = useFormContext();
59
+ const withinForm = !!formContext && !!name;
60
+ const isRequired = withinForm && formContext.validationSchema?.fields?.[name].tests?.some((t: SafeAny) => t.OPTIONS.name === 'required');
61
+
62
+ // Internal state for non-Formik usage
63
+ const [internalValue, setInternalValue] = useState(rest.value || '');
64
+
65
+ const rootEl = useCallback(() => {
66
+ const commonProps = {
67
+ ...rest,
68
+ variant,
69
+ id: inputId.current,
70
+ name,
71
+ };
72
+
73
+ if (withinForm) {
74
+ // if in Formik context
75
+ return (
76
+ <Field name={name}>
77
+ {({field, meta}: FieldProps) => {
78
+ const {value, onChange} = transformer({
79
+ value: field.value,
80
+ onChange: (event: string) => formContext.setFieldValue(name, event),
81
+ transform: {
82
+ input: transform.input ?? (value => value),
83
+ output: transform.output ?? (event => event.target.value)
84
+ }
85
+ });
86
+
87
+ return (
88
+ <>
89
+ <PrimeDropdown
90
+ {...commonProps}
91
+ value={value}
92
+ onChange={(event) => {
93
+ onChange(event);
94
+ rest.onChange?.(event);
95
+ }}
96
+ onBlur={(event) => {
97
+ field.onBlur(event);
98
+ rest.onBlur?.(event);
99
+ }}
100
+ invalid={!!meta.error}
101
+ />
102
+ <ErrorMessage message={meta.error} parseError={parseError} hint={rest.hint}/>
103
+ </>
104
+ );
105
+ }}
106
+ </Field>
107
+ );
108
+ } else {
109
+ // if outside Formik context
110
+ const {value, onChange} = transformer({
111
+ value: internalValue,
112
+ onChange: (event: string) => setInternalValue(event),
113
+ transform: {
114
+ input: transform.input ?? (value => value),
115
+ output: transform.output ?? (event => event.target.value)
116
+ }
117
+ });
118
+
119
+ return (
120
+ <PrimeDropdown
121
+ {...commonProps}
122
+ value={value}
123
+ onChange={(event) => {
124
+ onChange(event);
125
+ rest.onChange?.(event);
126
+ }}
127
+ onBlur={rest.onBlur}
128
+ />
129
+ );
130
+ }
131
+ }, [internalValue, props]);
132
+
133
+ const labelEl = rest.label && (
134
+ <label htmlFor={inputId.current}>
135
+ {rest.label}
136
+ {isRequired && showRequiredStar ? '*' : ''}
137
+ </label>
138
+ );
139
+
140
+ const iconEl = icon && (
141
+ typeof icon === 'string'
142
+ ? <PrimeInputIcon className={icon}></PrimeInputIcon>
143
+ : <PrimeInputIcon>{icon}</PrimeInputIcon>
144
+ );
145
+
146
+ const withIcon = (
147
+ <PrimeIconField iconPosition={iconPosition}>
148
+ {iconEl}
149
+ {rootEl()}
150
+ </PrimeIconField>
151
+ );
152
+
153
+ return (
154
+ <div className={primeClassNames('dropdown-wrapper',
155
+ `variant-${variant}`,
156
+ `p-inputtext-${inputSize}`,
157
+ {
158
+ [`label-${labelPosition}`]: rest.label,
159
+ [`icon-${iconPosition}`]: iconEl,
160
+ 'is-rtl': rtl,
161
+ 'is-ltr': !rtl,
162
+ 'addon-before': addon?.before,
163
+ 'addon-after': addon?.after,
164
+ })}>
165
+ <div className="field">
166
+ {labelPosition !== 'float' && labelEl}
167
+ <div className={primeClassNames('field-inner', {"p-inputgroup": addon})}>
168
+ {getAddonTemplate(addon?.before)}
169
+ {
170
+ labelPosition === 'float' ? (
171
+ <PrimeFloatLabel>
172
+ {icon ? withIcon : rootEl()}
173
+ {labelEl}
174
+ </PrimeFloatLabel>
175
+ ) : (
176
+ icon ? withIcon : rootEl()
177
+ )
178
+ }
179
+ {getAddonTemplate(addon?.after)}
180
+ </div>
181
+ </div>
182
+ </div>
183
+ );
184
+ };
@@ -0,0 +1 @@
1
+ export * from "./Dropdown";
@@ -0,0 +1,7 @@
1
+ .error {
2
+ color: rgb(185, 28, 28);
3
+ }
4
+
5
+ .hint {
6
+ color: rgb(156, 163, 175);
7
+ }
@@ -0,0 +1,23 @@
1
+ import {ReactNode} from "react";
2
+ import "./ErrorMessage.scss";
3
+
4
+ interface ErrorMessageProps {
5
+ message?: string;
6
+ parseError?: (message: string) => ReactNode;
7
+ hint?: string;
8
+ }
9
+
10
+ export const ErrorMessage = (props: ErrorMessageProps) => {
11
+ const {parseError, message, hint} = props;
12
+ return (
13
+ <>
14
+ {
15
+ message
16
+ ?
17
+ parseError?.(message) || <small className="error">{message}</small>
18
+ :
19
+ <small className="hint">{hint}</small>
20
+ }
21
+ </>
22
+ )
23
+ }
@@ -0,0 +1 @@
1
+ export * from "./ErrorMessage";
@@ -0,0 +1,49 @@
1
+ import {Form, Formik, FormikConfig, FormikContextType, FormikValues, useFormikContext} from "formik";
2
+ import {ForwardedRef, forwardRef, PropsWithChildren, useEffect, useRef} from "react";
3
+ import {FormProvider} from "@powell/components/FormContainer";
4
+
5
+ interface FormContainerProps<T extends FormikValues> extends FormikConfig<T> {
6
+ onInit?: (context: FormikContextType<T>) => void;
7
+ className?: string;
8
+ }
9
+
10
+ const FormContent = <T extends FormikValues>(props: PropsWithChildren<{onInit: FormContainerProps<T>['onInit']}>) => {
11
+ const {children, onInit} = props;
12
+ const formikContext: FormikContextType<T> = useFormikContext();
13
+ const initialized = useRef(false);
14
+
15
+ useEffect(() => {
16
+ if (!initialized.current) {
17
+ onInit?.(formikContext);
18
+ initialized.current = true;
19
+ }
20
+ }, [formikContext, onInit]);
21
+
22
+ return (
23
+ <>
24
+ {children}
25
+ </>
26
+ );
27
+ }
28
+
29
+ export const FormContainer = forwardRef(<T extends FormikValues>(props: FormContainerProps<T>, ref: ForwardedRef<HTMLFormElement>) => {
30
+ const {children, onInit, className, ...rest} = props;
31
+
32
+ return (
33
+ <Formik {...rest}>
34
+ {
35
+ (context) => (
36
+ <FormProvider {...rest}>
37
+ <Form ref={ref} className={className}>
38
+ {
39
+ <FormContent<T> onInit={onInit}>
40
+ {typeof children === 'function' ? children(context) : children}
41
+ </FormContent>
42
+ }
43
+ </Form>
44
+ </FormProvider>
45
+ )
46
+ }
47
+ </Formik>
48
+ )
49
+ })
@@ -0,0 +1,17 @@
1
+ import {createContext, PropsWithChildren} from "react";
2
+ import {FormikConfig, FormikValues} from "formik";
3
+
4
+ export const FormContext = createContext<FormikConfig<FormikValues> | undefined>(undefined);
5
+
6
+ export const FormProvider = <T extends FormikValues>(props: PropsWithChildren<FormikConfig<T>>) => {
7
+ const {children, ...rest} = props;
8
+
9
+ return (
10
+ <FormContext.Provider value={rest}>
11
+ <>
12
+ {children}
13
+ </>
14
+ </FormContext.Provider>
15
+ );
16
+ };
17
+
@@ -0,0 +1,2 @@
1
+ export * from "./FormContainer";
2
+ export * from "./FormContext";
@@ -0,0 +1,126 @@
1
+ .input-text-wrapper {
2
+ .field {
3
+ display: flex;
4
+ gap: 0.25rem 1rem;
5
+
6
+ > .field-inner {
7
+ flex-grow: 1;
8
+ }
9
+ }
10
+
11
+ :where(.p-inputtext) {
12
+ width: 100%;
13
+ }
14
+
15
+ .p-icon-field {
16
+ .p-input-icon {
17
+ z-index: 5;
18
+ color: var(--text-color-secondary);
19
+ }
20
+
21
+ &.p-icon-field-right {
22
+ :where(.p-inputtext) {
23
+ padding-right: 2.5rem;
24
+ }
25
+
26
+ .p-input-icon {
27
+ right: 0.75rem;
28
+ left: auto;
29
+ }
30
+ }
31
+
32
+ &.p-icon-field-left {
33
+ :where(.p-inputtext) {
34
+ padding-left: 2.5rem;
35
+ }
36
+
37
+ .p-input-icon {
38
+ left: 0.75rem;
39
+ right: auto;
40
+ }
41
+ }
42
+ }
43
+
44
+ &.label-fix-side .field {
45
+ flex-direction: row;
46
+ align-items: center;
47
+ }
48
+
49
+ &.label-fix-top .field {
50
+ flex-direction: column;
51
+
52
+ label {
53
+ margin-bottom: 0.25rem;
54
+ }
55
+ }
56
+
57
+ &.addon-before {
58
+ [class*="icon-"] {
59
+ :where(.p-inputtext) {
60
+ border-radius: 0 var(--border-radius) var(--border-radius) 0;
61
+ }
62
+ }
63
+ }
64
+
65
+ &.addon-after {
66
+ &.label-float {
67
+ .p-inputgroup-addon {
68
+ border-left: 0;
69
+ }
70
+ }
71
+
72
+ [class*="icon-"] {
73
+ :where(.p-inputtext) {
74
+ border-radius: var(--border-radius) 0 0 var(--border-radius);
75
+ }
76
+ }
77
+ }
78
+
79
+ &[class*="addon-"] {
80
+ .p-inputgroup {
81
+ .p-icon-field,
82
+ .p-float-label {
83
+ flex-grow: 1;
84
+ }
85
+ }
86
+
87
+ &.addon-before :where(.p-inputtext) {
88
+ border-radius: 0 var(--border-radius) var(--border-radius) 0;
89
+ }
90
+
91
+ &.addon-after :where(.p-inputtext) {
92
+ border-radius: var(--border-radius) 0 0 var(--border-radius);
93
+ }
94
+ }
95
+
96
+ &.is-ltr {
97
+ direction: ltr;
98
+
99
+ &.label-float {
100
+ &.icon-left .field label {
101
+ left: 2.5rem;
102
+ }
103
+ }
104
+ }
105
+
106
+ &.is-rtl {
107
+ direction: rtl;
108
+
109
+ &.label-float {
110
+ label {
111
+ left: auto;
112
+ right: 0.75rem;
113
+ }
114
+
115
+ &.icon-right .field label {
116
+ right: 2.5rem;
117
+ }
118
+ }
119
+
120
+ &[class*="addon-"] {
121
+ .p-inputgroup {
122
+ flex-direction: row-reverse;
123
+ }
124
+ }
125
+ }
126
+ }