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,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
+ PrimeInputText,
10
+ PrimeInputTextProps,
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 './InputText.scss';
19
+
20
+ interface InputTextProps extends PrimeInputTextProps {
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 InputText = (props: InputTextProps) => {
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
+ <PrimeInputText
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
+ <PrimeInputText
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('input-text-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 "./InputText";
@@ -0,0 +1,126 @@
1
+ .input-textarea-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-inputtextarea) {
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-inputtextarea) {
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-inputtextarea) {
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-inputtextarea) {
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-inputtextarea) {
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-inputtextarea) {
88
+ border-radius: 0 var(--border-radius) var(--border-radius) 0;
89
+ }
90
+
91
+ &.addon-after :where(.p-inputtextarea) {
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,181 @@
1
+ import {ChangeEvent, ReactNode, useCallback, useRef, useState} from "react";
2
+ import {Addon, LabelPosition} from "@powell/models";
3
+ import {
4
+ primeClassNames,
5
+ PrimeFloatLabel,
6
+ PrimeIconField,
7
+ PrimeIconFieldProps,
8
+ PrimeInputIcon,
9
+ PrimeInputTextarea,
10
+ PrimeInputTextareaProps,
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 './InputTextarea.scss';
19
+
20
+ interface InputTextareaProps extends PrimeInputTextareaProps {
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
+ addon?: Addon;
33
+ iconPosition?: PrimeIconFieldProps["iconPosition"];
34
+ labelPosition?: LabelPosition;
35
+ }
36
+
37
+ export const InputTextarea = (props: InputTextareaProps) => {
38
+ props = useApplyConfig(props);
39
+ const {
40
+ parseError,
41
+ name,
42
+ transform = {},
43
+ iconPosition = 'left',
44
+ labelPosition,
45
+ addon,
46
+ icon,
47
+ rtl,
48
+ showRequiredStar,
49
+ variant,
50
+ ...rest
51
+ } = props;
52
+
53
+ const inputId = useRef(PrimeUniqueComponentId());
54
+
55
+ // Check if we're in Formik context
56
+ const formContext = useFormContext();
57
+ const withinForm = !!formContext && !!name;
58
+ const isRequired = withinForm && formContext.validationSchema?.fields?.[name].tests?.some((t: SafeAny) => t.OPTIONS.name === 'required');
59
+
60
+ // Internal state for non-Formik usage
61
+ const [internalValue, setInternalValue] = useState(rest.value || '');
62
+
63
+ const rootEl = useCallback(() => {
64
+ const commonProps = {
65
+ ...rest,
66
+ variant,
67
+ id: inputId.current,
68
+ name,
69
+ };
70
+
71
+ if (withinForm) {
72
+ // if in Formik context
73
+ return (
74
+ <Field name={name}>
75
+ {({field, meta}: FieldProps) => {
76
+ const {value, onChange} = transformer({
77
+ value: field.value,
78
+ onChange: (event: string) => formContext.setFieldValue(name, event),
79
+ transform: {
80
+ input: transform.input ?? (value => value),
81
+ output: transform.output ?? (event => event.target.value)
82
+ }
83
+ });
84
+
85
+ return (
86
+ <>
87
+ <PrimeInputTextarea
88
+ {...commonProps}
89
+ value={value}
90
+ onChange={(event) => {
91
+ onChange(event);
92
+ rest.onChange?.(event);
93
+ }}
94
+ onBlur={(event) => {
95
+ field.onBlur(event);
96
+ rest.onBlur?.(event);
97
+ }}
98
+ invalid={!!meta.error}
99
+ />
100
+ <ErrorMessage message={meta.error} parseError={parseError} hint={rest.hint}/>
101
+ </>
102
+ );
103
+ }}
104
+ </Field>
105
+ );
106
+ } else {
107
+ // if outside Formik context
108
+ const {value, onChange} = transformer({
109
+ value: internalValue,
110
+ onChange: (event: string) => setInternalValue(event),
111
+ transform: {
112
+ input: transform.input ?? (value => value),
113
+ output: transform.output ?? (event => event.target.value)
114
+ }
115
+ });
116
+
117
+ return (
118
+ <PrimeInputTextarea
119
+ {...commonProps}
120
+ value={value}
121
+ onChange={(event) => {
122
+ onChange(event);
123
+ rest.onChange?.(event);
124
+ }}
125
+ onBlur={rest.onBlur}
126
+ />
127
+ );
128
+ }
129
+ }, [internalValue, props]);
130
+
131
+ const labelEl = rest.label && (
132
+ <label htmlFor={inputId.current}>
133
+ {rest.label}
134
+ {isRequired && showRequiredStar ? '*' : ''}
135
+ </label>
136
+ );
137
+
138
+ const iconEl = icon && (
139
+ typeof icon === 'string'
140
+ ? <PrimeInputIcon className={icon}></PrimeInputIcon>
141
+ : <PrimeInputIcon>{icon}</PrimeInputIcon>
142
+ );
143
+
144
+ const withIcon = (
145
+ <PrimeIconField iconPosition={iconPosition}>
146
+ {iconEl}
147
+ {rootEl()}
148
+ </PrimeIconField>
149
+ );
150
+
151
+ return (
152
+ <div className={primeClassNames('input-textarea-wrapper',
153
+ `variant-${variant}`,
154
+ {
155
+ [`label-${labelPosition}`]: rest.label,
156
+ [`icon-${iconPosition}`]: iconEl,
157
+ 'is-rtl': rtl,
158
+ 'is-ltr': !rtl,
159
+ 'addon-before': addon?.before,
160
+ 'addon-after': addon?.after,
161
+ })}>
162
+ <div className="field">
163
+ {labelPosition !== 'float' && labelEl}
164
+ <div className={primeClassNames('field-inner', {"p-inputgroup": addon})}>
165
+ {getAddonTemplate(addon?.before)}
166
+ {
167
+ labelPosition === 'float' ? (
168
+ <PrimeFloatLabel>
169
+ {icon ? withIcon : rootEl()}
170
+ {labelEl}
171
+ </PrimeFloatLabel>
172
+ ) : (
173
+ icon ? withIcon : rootEl()
174
+ )
175
+ }
176
+ {getAddonTemplate(addon?.after)}
177
+ </div>
178
+ </div>
179
+ </div>
180
+ );
181
+ };
@@ -0,0 +1 @@
1
+ export * from "./InputTextarea";
package/hooks/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from "./useApplyConfig";
2
+ export * from "./useFormContext";
3
+ export * from "./usePowellConfig";
4
+ export * from "./useTransform";
@@ -0,0 +1,36 @@
1
+ import {usePowellConfig} from "@powell/hooks/usePowellConfig";
2
+ import {PowellConfig} from "@powell/models";
3
+
4
+ interface ApplyConfigOptions {
5
+ isFixLabel?: boolean;
6
+ sizable?: boolean;
7
+ }
8
+
9
+ interface CommonConfigProps {
10
+ rtl?: PowellConfig["rtl"];
11
+ showRequiredStar?: PowellConfig["showRequiredStar"];
12
+ labelPosition?: PowellConfig["labelPosition"];
13
+ inputSize?: PowellConfig["inputSize"];
14
+ }
15
+
16
+ export const useApplyConfig = <T extends CommonConfigProps>(props: T, options: ApplyConfigOptions = {}) => {
17
+ const [config] = usePowellConfig();
18
+ const {sizable = true, isFixLabel = false} = options;
19
+
20
+ const result = {
21
+ ...props,
22
+ rtl: props.rtl ?? config.rtl,
23
+ showRequiredStar: props.showRequiredStar ?? config.showRequiredStar,
24
+ labelPosition: props.labelPosition ?? config.labelPosition,
25
+ }
26
+
27
+ if (isFixLabel) {
28
+ result.labelPosition = config.fixLabelPosition;
29
+ }
30
+
31
+ if (sizable) {
32
+ result.inputSize = props.inputSize ?? config.inputSize;
33
+ }
34
+
35
+ return result;
36
+ }
@@ -0,0 +1,14 @@
1
+ import {useContext} from "react";
2
+ import {FormikConfig, FormikContextType, FormikValues, useFormikContext} from "formik";
3
+ import {FormContext} from "@powell/components/FormContainer";
4
+
5
+ export const useFormContext = () => {
6
+ const context = useContext(FormContext) as FormikConfig<FormikValues>;
7
+ const formikContext = useFormikContext();
8
+
9
+ if (!context || !formikContext) {
10
+ return null;
11
+ }
12
+
13
+ return {...context, ...formikContext} as FormikContextType<FormikValues>;
14
+ };
@@ -0,0 +1,64 @@
1
+ import {configService, PrimeContext, PrimeZIndexOptions} from "@powell/api";
2
+ import {useContext} from "react";
3
+ import {PowellConfig, SafeAny} from "@powell/models";
4
+
5
+ export const usePowellConfig = () => {
6
+ const [powellConfig, setPowellConfig] = configService.use();
7
+ const {
8
+ setPt,
9
+ setFilterMatchModeOptions,
10
+ setLocale,
11
+ setNonce,
12
+ setHideOverlaysOnDocumentScrolling,
13
+ setRipple,
14
+ setCssTransition,
15
+ setStyleContainer,
16
+ setInputStyle,
17
+ setNullSortOrder,
18
+ setZIndex,
19
+ setAutoZIndex,
20
+ setAppendTo,
21
+ changeTheme,
22
+ ...restPrimeConfig
23
+ } = useContext(PrimeContext);
24
+
25
+ const actions: Partial<Record<keyof PowellConfig, (c: PowellConfig) => SafeAny>> = {
26
+ pt: (v) => setPt?.(v.pt!),
27
+ filterMatchModeOptions: (v) => setFilterMatchModeOptions?.(v.filterMatchModeOptions!),
28
+ locale: (v) => setLocale?.(v.locale!),
29
+ nonce: (v) => setNonce?.(v.nonce!),
30
+ hideOverlaysOnDocumentScrolling: (v) => setHideOverlaysOnDocumentScrolling?.(v.hideOverlaysOnDocumentScrolling!),
31
+ ripple: (v) => {
32
+ setRipple?.(v.ripple!);
33
+ if (v.ripple) {
34
+ document.body.classList.remove('p-ripple-disabled');
35
+ } else {
36
+ document.body.classList.add('p-ripple-disabled');
37
+ }
38
+ },
39
+ cssTransition: (v) => setCssTransition?.(v.cssTransition!),
40
+ styleContainer: (v) => setStyleContainer?.(v.styleContainer!),
41
+ inputStyle: (v) => {
42
+ if (v.inputStyle === 'filled') {
43
+ document.body.classList.add('p-input-filled');
44
+ } else {
45
+ document.body.classList.remove('p-input-filled');
46
+ }
47
+ setInputStyle?.(v.inputStyle!);
48
+ },
49
+ nullSortOrder: (v) => setNullSortOrder?.(v.nullSortOrder!),
50
+ zIndex: (v) => setZIndex?.(v.zIndex! as PrimeZIndexOptions),
51
+ autoZIndex: (v) => setAutoZIndex?.(v.autoZIndex!),
52
+ appendTo: (v) => setAppendTo?.(v.appendTo!),
53
+ theme: (v) => changeTheme?.(powellConfig.theme, v.theme!, 'powell-theme-link')
54
+ }
55
+ const updateConfig = (c: Partial<PowellConfig>) => {
56
+ for (const key in c) {
57
+ if (key in actions) {
58
+ actions[key as keyof PowellConfig]?.(c);
59
+ }
60
+ setPowellConfig(prev => ({...prev, ...c}));
61
+ }
62
+ }
63
+ return [{...powellConfig, ...restPrimeConfig}, updateConfig] as [config: PowellConfig, (c: Partial<PowellConfig>) => any];
64
+ }
@@ -0,0 +1,27 @@
1
+ import {SafeAny} from "@powell/models/common";
2
+
3
+ export type UseTransformOptions = {
4
+ value: SafeAny;
5
+ onChange: (...event: SafeAny[]) => void;
6
+ transform?: {
7
+ input?: (value: SafeAny) => SafeAny;
8
+ output?: (...event: SafeAny[]) => SafeAny;
9
+ }
10
+ }
11
+
12
+ export const useTransform = (options: UseTransformOptions) => {
13
+ const value = options.transform?.input?.(options.value) || options.value;
14
+ const onChange = (...event: SafeAny[]) => {
15
+ if (typeof options.transform?.output === 'function') {
16
+ options.onChange(options.transform.output(...event));
17
+ } else {
18
+ options.onChange(...event);
19
+ }
20
+ }
21
+
22
+ return {
23
+ value,
24
+ onChange
25
+ }
26
+ }
27
+
package/index.js ADDED
@@ -0,0 +1 @@
1
+ export { default as Button } from './components/Button';
@@ -0,0 +1,7 @@
1
+ export type ButtonAppearance = 'default' | 'text' | 'outlined' | 'link';
2
+ export type Direction = 'rtl' | 'ltr';
3
+ export type Size = 'sm' | 'md' | 'lg';
4
+ export type Orientation = 'horizontal' | 'vertical';
5
+ export type Position = 'left' | 'right' | 'top' | 'bottom';
6
+ export type Nullable<T = void> = T | null | undefined;
7
+ export type SafeAny = any;