@foi/design-system 0.0.15 → 0.0.17
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.
- package/README.md +135 -19
- package/dist/RadioGroup-DzEJw4WJ.js +456 -0
- package/dist/RadioGroup-DzEJw4WJ.js.map +1 -0
- package/dist/{RadioGroup.context-BBa8PDLt.js → RadioGroup.context-Bu218uUX.js} +159 -3
- package/dist/RadioGroup.context-Bu218uUX.js.map +1 -0
- package/dist/{Switch-BNFdKefE.js → Switch-oAVuMb0V.js} +906 -1062
- package/dist/Switch-oAVuMb0V.js.map +1 -0
- package/dist/atoms.mjs +3 -3
- package/dist/components/atoms/TextField/TextField.interface.d.ts +1 -1
- package/dist/components/organisms/DataGrid/DataGrid.interface.d.ts +4 -2
- package/dist/hocs/ThemeProvider/components/index.d.ts +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.mjs +128 -128
- package/dist/index.mjs.map +1 -1
- package/dist/molecules.d.ts +2 -0
- package/dist/molecules.mjs +2 -2
- package/dist/theme-D01EcUA9.js.map +1 -1
- package/package.json +1 -1
- package/dist/RadioGroup-BdWsLUz-.js +0 -324
- package/dist/RadioGroup-BdWsLUz-.js.map +0 -1
- package/dist/RadioGroup.context-BBa8PDLt.js.map +0 -1
- package/dist/Switch-BNFdKefE.js.map +0 -1
- /package/dist/hocs/ThemeProvider/components/{Input.d.ts → TextField.d.ts} +0 -0
- /package/dist/theme/dark/components/{Input.d.ts → TextField.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -42,20 +42,21 @@ npm publish --access public
|
|
|
42
42
|
|
|
43
43
|
### Atoms
|
|
44
44
|
|
|
45
|
-
| Component
|
|
46
|
-
|
|
|
47
|
-
| `Button`
|
|
48
|
-
| `Checkbox`
|
|
49
|
-
| `DatePicker`
|
|
50
|
-
| `Icon`
|
|
51
|
-
| `IconButton`
|
|
52
|
-
| `
|
|
53
|
-
| `Pagination`
|
|
54
|
-
| `Radio`
|
|
55
|
-
| `Select`
|
|
56
|
-
| `Skeleton`
|
|
57
|
-
| `Slider`
|
|
58
|
-
| `Switch`
|
|
45
|
+
| Component | Description |
|
|
46
|
+
| ------------- | ------------------------------------------------------------------------------------------ |
|
|
47
|
+
| `Button` | Primary action button with variant/size/color support |
|
|
48
|
+
| `Checkbox` | Single checkbox — standalone, RHF, or inside a group |
|
|
49
|
+
| `DatePicker` | Date input with calendar menu, integrates with RHF |
|
|
50
|
+
| `Icon` | Font-based icon using Material Symbols Rounded — pass a `name` prop |
|
|
51
|
+
| `IconButton` | Clickable icon with button semantics |
|
|
52
|
+
| `NumberField` | Numeric input with increment/decrement buttons, min/max/step support, and two layout modes |
|
|
53
|
+
| `Pagination` | Page navigation bar with first/prev/next/last buttons and optional rows-per-page selector |
|
|
54
|
+
| `Radio` | Single radio button — used inside `RadioGroup` |
|
|
55
|
+
| `Select` | Dropdown select with RHF integration |
|
|
56
|
+
| `Skeleton` | Animated placeholder shown while content is loading — rectangular or circular |
|
|
57
|
+
| `Slider` | Range slider with RHF integration |
|
|
58
|
+
| `Switch` | Toggle switch — boolean RHF field |
|
|
59
|
+
| `TextField` | Text input (text, password, email) with label, helper text, and error state |
|
|
59
60
|
|
|
60
61
|
### Molecules
|
|
61
62
|
|
|
@@ -80,12 +81,13 @@ All field components share the same integration pattern. Define a Zod schema, pa
|
|
|
80
81
|
import { useForm } from 'react-hook-form';
|
|
81
82
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
82
83
|
import { z } from 'zod';
|
|
83
|
-
import
|
|
84
|
+
import TextField from '@components/atoms/TextField';
|
|
85
|
+
import NumberField from '@components/atoms/NumberField';
|
|
84
86
|
import Button from '@components/atoms/Button';
|
|
85
87
|
|
|
86
88
|
const schema = z.object({
|
|
87
89
|
email: z.string().email('Invalid email'),
|
|
88
|
-
age: z.number().min(18, 'Must be 18 or older'),
|
|
90
|
+
age: z.number({ message: 'Required' }).min(18, 'Must be 18 or older'),
|
|
89
91
|
});
|
|
90
92
|
|
|
91
93
|
type FormValues = z.infer<typeof schema>;
|
|
@@ -97,8 +99,8 @@ const MyForm = () => {
|
|
|
97
99
|
|
|
98
100
|
return (
|
|
99
101
|
<form onSubmit={handleSubmit(console.log)}>
|
|
100
|
-
<
|
|
101
|
-
<
|
|
102
|
+
<TextField name='email' control={control} label='Email' />
|
|
103
|
+
<NumberField name='age' control={control} label='Age' min={18} />
|
|
102
104
|
<Button type='submit' label='Submit' />
|
|
103
105
|
</form>
|
|
104
106
|
);
|
|
@@ -131,6 +133,103 @@ const [agreed, setAgreed] = useState(false);
|
|
|
131
133
|
<Checkbox checked={agreed} onChecked={setAgreed} label='I agree to the terms' />;
|
|
132
134
|
```
|
|
133
135
|
|
|
136
|
+
## TextField
|
|
137
|
+
|
|
138
|
+
A text input field with a floating label, helper text, and full error state integration. Only accepts `text`, `password`, and `email` as input types. For numeric input use `NumberField`.
|
|
139
|
+
|
|
140
|
+
### Props
|
|
141
|
+
|
|
142
|
+
| Prop | Type | Default | Description |
|
|
143
|
+
| --------------- | ----------------------------------------- | ---------- | ---------------------------------------------------- |
|
|
144
|
+
| `name` | `string` | — | Field name, used by RHF |
|
|
145
|
+
| `label` | `string` | — | Floating label text |
|
|
146
|
+
| `control` | `Control` | — | RHF control object; omit for uncontrolled mode |
|
|
147
|
+
| `value` | `string` | — | Value in uncontrolled mode |
|
|
148
|
+
| `onValueChange` | `(value: string) => void` | — | Change handler in uncontrolled mode |
|
|
149
|
+
| `type` | `'text' \| 'password' \| 'email'` | `'text'` | HTML input type |
|
|
150
|
+
| `width` | `'small' \| 'medium' \| 'large' \| 'full'` | — | Preset width |
|
|
151
|
+
| `helperText` | `string` | — | Hint text shown below the field when there is no error |
|
|
152
|
+
| `showErrorText` | `boolean` | `true` | Show the validation error message below the field |
|
|
153
|
+
| `hasPadding` | `boolean` | `false` | Add bottom padding to reserve space for helper/error text |
|
|
154
|
+
| `startAdornment`| `JSX.Element` | — | Element rendered to the left of the input |
|
|
155
|
+
| `endAdornment` | `JSX.Element` | — | Element rendered to the right of the input |
|
|
156
|
+
| `regex` | `RegExp` | — | Block keystrokes that don't match the pattern |
|
|
157
|
+
| `format` | `(value: string) => string` | — | Transform the value before it is stored |
|
|
158
|
+
| `disabled` | `boolean` | `false` | Disable the field |
|
|
159
|
+
| `theme` | `EVENTS` | — | One-off token override for this instance |
|
|
160
|
+
| `variant` | `string` | `'default'`| Theme variant name |
|
|
161
|
+
|
|
162
|
+
### Example
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
import TextField from '@components/atoms/TextField';
|
|
166
|
+
import Icon from '@components/atoms/Icon';
|
|
167
|
+
|
|
168
|
+
<TextField
|
|
169
|
+
name='email'
|
|
170
|
+
control={control}
|
|
171
|
+
label='Email'
|
|
172
|
+
type='email'
|
|
173
|
+
startAdornment={<Icon name='mail' />}
|
|
174
|
+
helperText='We will never share your email'
|
|
175
|
+
/>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## NumberField
|
|
179
|
+
|
|
180
|
+
A numeric input that stores a `number` in RHF (or `undefined` when empty). The field always renders increment/decrement buttons; their position depends on the `display` prop.
|
|
181
|
+
|
|
182
|
+
### Props
|
|
183
|
+
|
|
184
|
+
All `TextField` props apply except `type`, `endAdornment`, and `startAdornment` (in `spinner` mode). The following props are specific to `NumberField`:
|
|
185
|
+
|
|
186
|
+
| Prop | Type | Default | Description |
|
|
187
|
+
| --------- | ----------------------------- | ------------ | ------------------------------------------------------------------------ |
|
|
188
|
+
| `min` | `number` | — | Minimum allowed value; decrement button disables at this bound |
|
|
189
|
+
| `max` | `number` | — | Maximum allowed value; increment button disables at this bound |
|
|
190
|
+
| `step` | `number` | `1` | Amount added or subtracted on each button click |
|
|
191
|
+
| `display` | `'standard' \| 'spinner'` | `'standard'` | `standard`: both buttons on the right; `spinner`: remove left, input centre, add right |
|
|
192
|
+
|
|
193
|
+
### Display modes
|
|
194
|
+
|
|
195
|
+
**`standard`** (default) — both buttons grouped on the right:
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
[startAdornment?] [ input ] [− +]
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**`spinner`** — decrement on the left, input centred, increment on the right:
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
[−] [ input ] [+]
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Example
|
|
208
|
+
|
|
209
|
+
```tsx
|
|
210
|
+
import NumberField from '@components/atoms/NumberField';
|
|
211
|
+
|
|
212
|
+
// Standard — quantity picker with bounds
|
|
213
|
+
<NumberField
|
|
214
|
+
name='quantity'
|
|
215
|
+
control={control}
|
|
216
|
+
label='Quantity'
|
|
217
|
+
min={1}
|
|
218
|
+
max={99}
|
|
219
|
+
step={1}
|
|
220
|
+
/>
|
|
221
|
+
|
|
222
|
+
// Spinner layout
|
|
223
|
+
<NumberField
|
|
224
|
+
name='quantity'
|
|
225
|
+
control={control}
|
|
226
|
+
label='Quantity'
|
|
227
|
+
display='spinner'
|
|
228
|
+
min={0}
|
|
229
|
+
max={100}
|
|
230
|
+
/>
|
|
231
|
+
```
|
|
232
|
+
|
|
134
233
|
## Theming
|
|
135
234
|
|
|
136
235
|
Wrap your app in `ThemeProvider` and pass one or more named themes. The active theme is selected by the `theme` prop and its tokens are injected as CSS custom properties that every component consumes.
|
|
@@ -230,7 +329,7 @@ interface Product { id: number; name: string; price: number; }
|
|
|
230
329
|
const columns: DataGridColumn<Product>[] = [
|
|
231
330
|
{
|
|
232
331
|
key: 'name',
|
|
233
|
-
label: 'Product',
|
|
332
|
+
label: 'Product', // string → wrapped in the themed --DATAGRID-thLabel span
|
|
234
333
|
type: 'text',
|
|
235
334
|
filter: { type: 'search' },
|
|
236
335
|
},
|
|
@@ -243,6 +342,23 @@ const columns: DataGridColumn<Product>[] = [
|
|
|
243
342
|
];
|
|
244
343
|
```
|
|
245
344
|
|
|
345
|
+
`label` accepts any `ReactNode`. A plain string is automatically wrapped in the themed `--DATAGRID-thLabel` span so it inherits the header typography. Pass a custom node to render icons, badges, or anything else without that wrapper:
|
|
346
|
+
|
|
347
|
+
```tsx
|
|
348
|
+
import Icon from '@components/atoms/Icon';
|
|
349
|
+
|
|
350
|
+
{
|
|
351
|
+
key: 'price',
|
|
352
|
+
label: (
|
|
353
|
+
<span style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>
|
|
354
|
+
<Icon name='payments' size='sm' />
|
|
355
|
+
Price
|
|
356
|
+
</span>
|
|
357
|
+
),
|
|
358
|
+
type: 'number',
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
246
362
|
### The `onFetch` contract
|
|
247
363
|
|
|
248
364
|
`onFetch` receives `{ page, pageSize, sort?, filters? }` and must return `{ data, total }`. It is called automatically whenever the page, sort, or any filter changes.
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
import { i as e, n as t, r as n } from "./emotion-react-jsx-runtime.browser.esm-Ch-DwUYg.js";
|
|
2
|
+
import { r } from "./theme-D01EcUA9.js";
|
|
3
|
+
import { a as i, i as a, n as o, o as s, r as c, s as l, t as u } from "./RadioGroup.context-Bu218uUX.js";
|
|
4
|
+
import d, { useEffect as f, useMemo as p, useRef as m } from "react";
|
|
5
|
+
import { css as h } from "@emotion/react";
|
|
6
|
+
import { useController as g } from "react-hook-form";
|
|
7
|
+
import { createPortal as _ } from "react-dom";
|
|
8
|
+
//#region src/components/molecules/CheckboxGroup/CheckboxGroup.emotion.ts
|
|
9
|
+
var v = (e, t) => `
|
|
10
|
+
.--CHECKBOXGROUP-label {
|
|
11
|
+
${r(e, "color", `--CHECKBOXGROUP-EVENTS-${t}-COLOR-PRIMARY`)}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.--CHECKBOXGROUP-helperText {
|
|
15
|
+
${r(e, "color", `--CHECKBOXGROUP-EVENTS-${t}-COLOR-SECONDARY`)}
|
|
16
|
+
}
|
|
17
|
+
`, y = (e) => h`
|
|
18
|
+
&.--CHECKBOXGROUP {
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
gap: 8px;
|
|
22
|
+
width: fit-content;
|
|
23
|
+
|
|
24
|
+
// ENABLED
|
|
25
|
+
${v(e, "ENABLED")};
|
|
26
|
+
|
|
27
|
+
// ERROR
|
|
28
|
+
&.--CHECKBOXGROUP-error {
|
|
29
|
+
${v(e, "ERROR")};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// DISABLED
|
|
33
|
+
&.--CHECKBOXGROUP-disabled {
|
|
34
|
+
${v(e, "DISABLED")};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.--CHECKBOXGROUP-items {
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
gap: 16px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&.--CHECKBOXGROUP--horizontal .--CHECKBOXGROUP-items {
|
|
44
|
+
flex-direction: row;
|
|
45
|
+
flex-wrap: wrap;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.--CHECKBOXGROUP-label {
|
|
49
|
+
// FONT
|
|
50
|
+
font-family: ${e["--FONTFAMILY-PRIMARY"]};
|
|
51
|
+
font-size: 0.875rem;
|
|
52
|
+
font-weight: 500;
|
|
53
|
+
line-height: 1;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.--CHECKBOXGROUP-helperText {
|
|
57
|
+
// FONT
|
|
58
|
+
font-family: ${e["--FONTFAMILY-PRIMARY"]};
|
|
59
|
+
font-size: 13px;
|
|
60
|
+
line-height: 16px;
|
|
61
|
+
margin-left: 14px;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
`, b = "--CHECKBOXGROUP", x = ({ name: e, control: r, children: a, label: o, helperText: s, showErrorText: c = !0, disabled: l, direction: u = "vertical", style: d, className: f }) => {
|
|
65
|
+
let { field: p, fieldState: m } = g({
|
|
66
|
+
control: r,
|
|
67
|
+
name: e
|
|
68
|
+
}), h = Array.isArray(p.value) ? p.value : [], _ = m.error;
|
|
69
|
+
return /* @__PURE__ */ t(i.Provider, {
|
|
70
|
+
value: {
|
|
71
|
+
checkedValues: h,
|
|
72
|
+
onChange: (e, t) => {
|
|
73
|
+
let n = t ? [...h, e] : h.filter((t) => t !== e);
|
|
74
|
+
p.onChange(n), p.onBlur();
|
|
75
|
+
},
|
|
76
|
+
disabled: l,
|
|
77
|
+
error: _
|
|
78
|
+
},
|
|
79
|
+
children: /* @__PURE__ */ n("div", {
|
|
80
|
+
className: [
|
|
81
|
+
b,
|
|
82
|
+
`${b}--${u}`,
|
|
83
|
+
c && _?.message && `${b}-error`,
|
|
84
|
+
l && `${b}-disabled`,
|
|
85
|
+
f || ""
|
|
86
|
+
].join(" "),
|
|
87
|
+
css: y(d),
|
|
88
|
+
"data-testid": b,
|
|
89
|
+
children: [
|
|
90
|
+
o && /* @__PURE__ */ t("span", {
|
|
91
|
+
className: `${b}-label`,
|
|
92
|
+
"data-testid": `${b}-label`,
|
|
93
|
+
children: o
|
|
94
|
+
}),
|
|
95
|
+
/* @__PURE__ */ t("div", {
|
|
96
|
+
className: `${b}-items`,
|
|
97
|
+
"data-testid": `${b}-items`,
|
|
98
|
+
children: a
|
|
99
|
+
}),
|
|
100
|
+
/* @__PURE__ */ n("span", {
|
|
101
|
+
className: `${b}-helperText`,
|
|
102
|
+
"data-testid": `${b}-helperText`,
|
|
103
|
+
children: [s && (!_ || !c) && s, c && _ && _.message]
|
|
104
|
+
})
|
|
105
|
+
]
|
|
106
|
+
})
|
|
107
|
+
});
|
|
108
|
+
}, S = ({ theme: n, variant: r = "default", ...i }) => {
|
|
109
|
+
let { componentStyles: a } = e([l.CHECKBOXGROUP], n, r.toUpperCase());
|
|
110
|
+
return /* @__PURE__ */ t(x, {
|
|
111
|
+
...i,
|
|
112
|
+
style: a
|
|
113
|
+
});
|
|
114
|
+
}, C = (e) => h`
|
|
115
|
+
&.--CHECKBOXTREE {
|
|
116
|
+
display: flex;
|
|
117
|
+
flex-direction: column;
|
|
118
|
+
gap: 8px;
|
|
119
|
+
width: fit-content;
|
|
120
|
+
|
|
121
|
+
.--CHECKBOXTREE-children {
|
|
122
|
+
display: flex;
|
|
123
|
+
flex-direction: column;
|
|
124
|
+
padding-left: 36px;
|
|
125
|
+
gap: 16px;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.--CHECKBOXTREE-helperText {
|
|
129
|
+
font-family: ${e["--FONTFAMILY-PRIMARY"]};
|
|
130
|
+
font-size: 13px;
|
|
131
|
+
line-height: 16px;
|
|
132
|
+
margin-left: 14px;
|
|
133
|
+
${r(e, "color", "--CHECKBOXTREE-EVENTS-ENABLED-COLOR-SECONDARY")}
|
|
134
|
+
|
|
135
|
+
&:empty {
|
|
136
|
+
display: none;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
&.--CHECKBOXTREE-error {
|
|
141
|
+
.--CHECKBOXTREE-helperText {
|
|
142
|
+
${r(e, "color", "--CHECKBOXTREE-EVENTS-ERROR-COLOR-SECONDARY")}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
&.--CHECKBOXTREE-disabled {
|
|
147
|
+
.--CHECKBOXTREE-helperText {
|
|
148
|
+
${r(e, "color", "--CHECKBOXTREE-EVENTS-DISABLED-COLOR-SECONDARY")}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
`, w = "--CHECKBOXTREE", T = ({ name: e, control: r, children: i, label: o, iconChecked: l = /* @__PURE__ */ t(s, { name: "check" }), iconIndeterminate: u = /* @__PURE__ */ t(s, { name: "remove" }), helperText: h, showErrorText: _ = !0, disabled: v, style: y, className: b }) => {
|
|
153
|
+
let { field: x, fieldState: S } = g({
|
|
154
|
+
control: r,
|
|
155
|
+
name: e
|
|
156
|
+
}), T = Array.isArray(x.value) ? x.value : [], E = S.error, D = p(() => d.Children.toArray(i).map((e) => {
|
|
157
|
+
let t = e;
|
|
158
|
+
return t.props?.value ?? t.props?.name ?? "";
|
|
159
|
+
}).filter(Boolean), [i]), O = D.length > 0 && D.every((e) => T.includes(e)), k = !O && D.some((e) => T.includes(e)), A = m(null);
|
|
160
|
+
return f(() => {
|
|
161
|
+
let e = A.current?.querySelectorAll("input[type=\"checkbox\"]")[0];
|
|
162
|
+
e && (e.indeterminate = k);
|
|
163
|
+
}, [k]), /* @__PURE__ */ n("div", {
|
|
164
|
+
ref: A,
|
|
165
|
+
className: [
|
|
166
|
+
w,
|
|
167
|
+
_ && E?.message ? `${w}-error` : "",
|
|
168
|
+
v ? `${w}-disabled` : "",
|
|
169
|
+
b || ""
|
|
170
|
+
].join(" "),
|
|
171
|
+
css: C(y),
|
|
172
|
+
"data-testid": w,
|
|
173
|
+
children: [
|
|
174
|
+
/* @__PURE__ */ t(c, {
|
|
175
|
+
checked: O || k,
|
|
176
|
+
onChecked: (e) => {
|
|
177
|
+
let t = e ? [...D] : [];
|
|
178
|
+
x.onChange(t), x.onBlur();
|
|
179
|
+
},
|
|
180
|
+
label: o,
|
|
181
|
+
icon: k ? u : l,
|
|
182
|
+
disabled: v,
|
|
183
|
+
showErrorText: !1,
|
|
184
|
+
helperText: void 0
|
|
185
|
+
}),
|
|
186
|
+
/* @__PURE__ */ t(a.Provider, {
|
|
187
|
+
value: {
|
|
188
|
+
checkedValues: T,
|
|
189
|
+
onChange: (e, t) => {
|
|
190
|
+
let n = t ? [...T, e] : T.filter((t) => t !== e);
|
|
191
|
+
x.onChange(n), x.onBlur();
|
|
192
|
+
},
|
|
193
|
+
disabled: v,
|
|
194
|
+
error: E
|
|
195
|
+
},
|
|
196
|
+
children: /* @__PURE__ */ t("div", {
|
|
197
|
+
className: `${w}-children`,
|
|
198
|
+
"data-testid": `${w}-children`,
|
|
199
|
+
children: i
|
|
200
|
+
})
|
|
201
|
+
}),
|
|
202
|
+
/* @__PURE__ */ n("span", {
|
|
203
|
+
className: `${w}-helperText`,
|
|
204
|
+
"data-testid": `${w}-helperText`,
|
|
205
|
+
children: [h && (!E || !_) && h, _ && E && E.message]
|
|
206
|
+
})
|
|
207
|
+
]
|
|
208
|
+
});
|
|
209
|
+
}, E = ({ theme: n, variant: r = "default", ...i }) => {
|
|
210
|
+
let { componentStyles: a } = e([l.CHECKBOXTREE], n, r.toUpperCase());
|
|
211
|
+
return /* @__PURE__ */ t(T, {
|
|
212
|
+
...i,
|
|
213
|
+
style: a
|
|
214
|
+
});
|
|
215
|
+
}, D = (e, t) => `
|
|
216
|
+
// BACKGROUNDS
|
|
217
|
+
${r(e, "background-color", `--MODAL-${t}-BACKGROUND-COLOR`)}
|
|
218
|
+
|
|
219
|
+
// BORDERS
|
|
220
|
+
${r(e, "border-color", `--MODAL-${t}-BORDER-COLOR`)}
|
|
221
|
+
${r(e, "border-width", `--MODAL-${t}-BORDER-WIDTH`)}
|
|
222
|
+
${r(e, "border-style", `--MODAL-${t}-BORDER-STYLE`)}
|
|
223
|
+
${r(e, "border-radius", `--MODAL-${t}-BORDER-RADIUS`)}
|
|
224
|
+
`, O = (e) => h`
|
|
225
|
+
&.--MODAL-scrim {
|
|
226
|
+
position: fixed;
|
|
227
|
+
inset: 0;
|
|
228
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
229
|
+
display: flex;
|
|
230
|
+
align-items: center;
|
|
231
|
+
justify-content: center;
|
|
232
|
+
z-index: 1000;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.--MODAL {
|
|
236
|
+
display: flex;
|
|
237
|
+
flex-direction: column;
|
|
238
|
+
width: 480px;
|
|
239
|
+
max-width: calc(100vw - 48px);
|
|
240
|
+
max-height: calc(100vh - 64px);
|
|
241
|
+
overflow: hidden;
|
|
242
|
+
box-shadow:
|
|
243
|
+
rgba(0, 0, 0, 0.2) 0px 5px 5px -3px,
|
|
244
|
+
rgba(0, 0, 0, 0.14) 0px 8px 10px 1px,
|
|
245
|
+
rgba(0, 0, 0, 0.12) 0px 3px 14px 2px;
|
|
246
|
+
|
|
247
|
+
${D(e, "ROOT")}
|
|
248
|
+
|
|
249
|
+
&.--MODAL-lg {
|
|
250
|
+
width: 720px;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.--MODAL-header {
|
|
254
|
+
display: flex;
|
|
255
|
+
align-items: center;
|
|
256
|
+
gap: 8px;
|
|
257
|
+
padding: 16px 20px;
|
|
258
|
+
flex-shrink: 0;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.--MODAL-title {
|
|
262
|
+
flex: 1;
|
|
263
|
+
margin: 0;
|
|
264
|
+
|
|
265
|
+
${r(e, "color", "--MODAL-EVENTS-ENABLED-COLOR-PRIMARY")};
|
|
266
|
+
|
|
267
|
+
font-family: ${e["--FONTFAMILY-PRIMARY"]};
|
|
268
|
+
font-size: 1rem;
|
|
269
|
+
font-weight: 600;
|
|
270
|
+
line-height: 1.25;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.--MODAL-body {
|
|
274
|
+
flex: 1;
|
|
275
|
+
padding: 20px;
|
|
276
|
+
overflow-y: auto;
|
|
277
|
+
|
|
278
|
+
${r(e, "color", "--MODAL-EVENTS-ENABLED-COLOR-SECONDARY")};
|
|
279
|
+
|
|
280
|
+
font-family: ${e["--FONTFAMILY-PRIMARY"]};
|
|
281
|
+
font-size: 0.875rem;
|
|
282
|
+
line-height: 1.5;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.--MODAL-footer {
|
|
286
|
+
display: flex;
|
|
287
|
+
justify-content: flex-end;
|
|
288
|
+
gap: 8px;
|
|
289
|
+
padding: 16px 20px;
|
|
290
|
+
flex-shrink: 0;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
`, k = "--MODAL", A = ({ open: e, onClose: r, header: i, showCloseButton: a = !0, size: c = "md", children: l, footer: u, staticBackdrop: d = !1, className: p, style: m }) => (f(() => {
|
|
294
|
+
if (!e || d) return;
|
|
295
|
+
let t = (e) => {
|
|
296
|
+
e.key === "Escape" && r();
|
|
297
|
+
};
|
|
298
|
+
return document.addEventListener("keydown", t), () => document.removeEventListener("keydown", t);
|
|
299
|
+
}, [
|
|
300
|
+
e,
|
|
301
|
+
r,
|
|
302
|
+
d
|
|
303
|
+
]), e ? _(/* @__PURE__ */ t("div", {
|
|
304
|
+
className: `${k}-scrim`,
|
|
305
|
+
css: O(m),
|
|
306
|
+
role: "dialog",
|
|
307
|
+
"aria-modal": "true",
|
|
308
|
+
onClick: (e) => {
|
|
309
|
+
!d && e.target === e.currentTarget && r();
|
|
310
|
+
},
|
|
311
|
+
children: /* @__PURE__ */ n("div", {
|
|
312
|
+
className: [
|
|
313
|
+
k,
|
|
314
|
+
c === "lg" ? `${k}-lg` : "",
|
|
315
|
+
p || ""
|
|
316
|
+
].filter(Boolean).join(" "),
|
|
317
|
+
children: [
|
|
318
|
+
(i !== void 0 || a) && /* @__PURE__ */ n("header", {
|
|
319
|
+
className: `${k}-header`,
|
|
320
|
+
children: [i, a && /* @__PURE__ */ t(o, {
|
|
321
|
+
icon: /* @__PURE__ */ t(s, { name: "close" }),
|
|
322
|
+
onClick: r,
|
|
323
|
+
"aria-label": "Cerrar modal"
|
|
324
|
+
})]
|
|
325
|
+
}),
|
|
326
|
+
l !== void 0 && /* @__PURE__ */ t("div", {
|
|
327
|
+
className: `${k}-body`,
|
|
328
|
+
children: l
|
|
329
|
+
}),
|
|
330
|
+
u && /* @__PURE__ */ t("footer", {
|
|
331
|
+
className: `${k}-footer`,
|
|
332
|
+
children: u
|
|
333
|
+
})
|
|
334
|
+
]
|
|
335
|
+
})
|
|
336
|
+
}), document.body) : null);
|
|
337
|
+
A.displayName = "Modal";
|
|
338
|
+
//#endregion
|
|
339
|
+
//#region src/components/molecules/Modal/index.tsx
|
|
340
|
+
var j = ({ theme: n, variant: r = "default", ...i }) => {
|
|
341
|
+
let { componentStyles: a } = e([l.MODAL], n, r.toUpperCase());
|
|
342
|
+
return /* @__PURE__ */ t(A, {
|
|
343
|
+
...i,
|
|
344
|
+
style: a
|
|
345
|
+
});
|
|
346
|
+
}, M = (e, t) => `
|
|
347
|
+
.--RADIOGROUP-label {
|
|
348
|
+
${r(e, "color", `--RADIOGROUP-EVENTS-${t}-COLOR-PRIMARY`)}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
.--RADIOGROUP-helperText {
|
|
352
|
+
${r(e, "color", `--RADIOGROUP-EVENTS-${t}-COLOR-SECONDARY`)}
|
|
353
|
+
}
|
|
354
|
+
`, N = (e) => h`
|
|
355
|
+
&.--RADIOGROUP {
|
|
356
|
+
display: flex;
|
|
357
|
+
flex-direction: column;
|
|
358
|
+
gap: 8px;
|
|
359
|
+
width: fit-content;
|
|
360
|
+
|
|
361
|
+
// ENABLED
|
|
362
|
+
${M(e, "ENABLED")};
|
|
363
|
+
|
|
364
|
+
// ERROR
|
|
365
|
+
&.--RADIOGROUP-error {
|
|
366
|
+
${M(e, "ERROR")};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// DISABLED
|
|
370
|
+
&.--RADIOGROUP-disabled {
|
|
371
|
+
${M(e, "DISABLED")};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.--RADIOGROUP-items {
|
|
375
|
+
display: flex;
|
|
376
|
+
flex-direction: column;
|
|
377
|
+
gap: 16px;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
&.--RADIOGROUP--horizontal .--RADIOGROUP-items {
|
|
381
|
+
flex-direction: row;
|
|
382
|
+
flex-wrap: wrap;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.--RADIOGROUP-label {
|
|
386
|
+
// FONT
|
|
387
|
+
font-family: ${e["--FONTFAMILY-PRIMARY"]};
|
|
388
|
+
font-size: 0.875rem;
|
|
389
|
+
font-weight: 500;
|
|
390
|
+
line-height: 1;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.--RADIOGROUP-helperText {
|
|
394
|
+
// FONT
|
|
395
|
+
font-family: ${e["--FONTFAMILY-PRIMARY"]};
|
|
396
|
+
font-size: 13px;
|
|
397
|
+
line-height: 16px;
|
|
398
|
+
margin-left: 14px;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
`, P = "--RADIOGROUP", F = ({ name: e, control: r, children: i, label: a, helperText: o, showErrorText: s = !0, disabled: c, direction: l = "vertical", style: f, className: p }) => {
|
|
402
|
+
let { field: m, fieldState: h } = g({
|
|
403
|
+
control: r,
|
|
404
|
+
name: e
|
|
405
|
+
}), _ = typeof m.value == "string" ? m.value : "", v = h.error, y = (e) => {
|
|
406
|
+
m.onChange(e), m.onBlur();
|
|
407
|
+
}, b = d.Children.toArray(i).find((e) => d.isValidElement(e) && !e.props.disabled)?.props.value ?? "";
|
|
408
|
+
return /* @__PURE__ */ t(u.Provider, {
|
|
409
|
+
value: {
|
|
410
|
+
name: e,
|
|
411
|
+
selectedValue: _,
|
|
412
|
+
onChange: y,
|
|
413
|
+
disabled: c,
|
|
414
|
+
error: v,
|
|
415
|
+
firstValue: b
|
|
416
|
+
},
|
|
417
|
+
children: /* @__PURE__ */ n("div", {
|
|
418
|
+
className: [
|
|
419
|
+
P,
|
|
420
|
+
`${P}--${l}`,
|
|
421
|
+
s && v?.message && `${P}-error`,
|
|
422
|
+
c && `${P}-disabled`,
|
|
423
|
+
p || ""
|
|
424
|
+
].join(" "),
|
|
425
|
+
css: N(f),
|
|
426
|
+
"data-testid": P,
|
|
427
|
+
children: [
|
|
428
|
+
a && /* @__PURE__ */ t("span", {
|
|
429
|
+
className: `${P}-label`,
|
|
430
|
+
"data-testid": `${P}-label`,
|
|
431
|
+
children: a
|
|
432
|
+
}),
|
|
433
|
+
/* @__PURE__ */ t("div", {
|
|
434
|
+
className: `${P}-items`,
|
|
435
|
+
"data-testid": `${P}-items`,
|
|
436
|
+
children: i
|
|
437
|
+
}),
|
|
438
|
+
/* @__PURE__ */ n("span", {
|
|
439
|
+
className: `${P}-helperText`,
|
|
440
|
+
"data-testid": `${P}-helperText`,
|
|
441
|
+
children: [o && (!v || !s) && o, s && v && v.message]
|
|
442
|
+
})
|
|
443
|
+
]
|
|
444
|
+
})
|
|
445
|
+
});
|
|
446
|
+
}, I = ({ theme: n, variant: r = "default", ...i }) => {
|
|
447
|
+
let { componentStyles: a } = e([l.RADIOGROUP], n, r.toUpperCase());
|
|
448
|
+
return /* @__PURE__ */ t(F, {
|
|
449
|
+
...i,
|
|
450
|
+
style: a
|
|
451
|
+
});
|
|
452
|
+
};
|
|
453
|
+
//#endregion
|
|
454
|
+
export { S as i, j as n, E as r, I as t };
|
|
455
|
+
|
|
456
|
+
//# sourceMappingURL=RadioGroup-DzEJw4WJ.js.map
|