lkd-web-kit 0.10.5 → 0.10.7
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/package.json +2 -2
- package/scripts/install-agent-skills.mjs +2 -2
- package/src/distributed-skills/create-modal-component/SKILL.md +168 -0
- package/src/distributed-skills/create-modal-component/agents/openai.yaml +4 -0
- package/src/distributed-skills/create-nextjs-page/SKILL.md +104 -0
- package/src/distributed-skills/create-nextjs-page/agents/openai.yaml +3 -0
- package/src/distributed-skills/create-svg-icon/SKILL.md +41 -0
- package/src/distributed-skills/create-svg-icon/agents/openai.yaml +3 -0
- package/src/distributed-skills/create-table-component/SKILL.md +189 -0
- package/src/distributed-skills/create-table-component/agents/openai.yaml +3 -0
- package/src/distributed-skills/rhf-lkd-forms/SKILL.md +186 -0
- package/.agents/skills/mantine-combobox/SKILL.md +0 -73
- package/.agents/skills/mantine-combobox/references/api.md +0 -199
- package/.agents/skills/mantine-combobox/references/patterns.md +0 -279
- package/.agents/skills/mantine-custom-components/SKILL.md +0 -112
- package/.agents/skills/mantine-custom-components/references/api.md +0 -407
- package/.agents/skills/mantine-custom-components/references/patterns.md +0 -431
- package/.agents/skills/publish-lkd-web-kit/SKILL.md +0 -165
- package/.agents/skills/publish-lkd-web-kit/agents/openai.yaml +0 -4
- package/.agents/skills/publish-lkd-web-kit/references/npm-trusted-publishing.md +0 -82
- package/.agents/skills/update-lkd-dependencies/SKILL.md +0 -88
- package/.agents/skills/update-lkd-dependencies/agents/openai.yaml +0 -4
- package/.agents/skills/update-lkd-dependencies/scripts/collect-npm-metadata.mjs +0 -73
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rhf-lkd-forms
|
|
3
|
+
description: Crear y revisar formularios, filtros, campos controlados, integraciones con React Hook Form, validaciones Zod, reglas superRefine, botones de submit y patrones Form* de lkd-web-kit. Usar cuando Codex trabaje en interfaces de formularios, filtros, wrappers de campos, schemas, valores iniciales, mapeo de payloads, flujos de submit o comportamiento de validación en proyectos que usan React Hook Form, Zod y lkd-web-kit.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Formularios RHF + lkd-web-kit
|
|
7
|
+
|
|
8
|
+
Usar este skill para formularios, filtros y campos controlados construidos con React Hook Form, Zod y `lkd-web-kit`.
|
|
9
|
+
|
|
10
|
+
## Workflow obligatorio
|
|
11
|
+
|
|
12
|
+
1. Leer primero la documentación de formularios del proyecto: `docs/lkd-web-kit.md` o el equivalente local.
|
|
13
|
+
2. Reutilizar la familia `Form*` existente antes de crear algo nuevo:
|
|
14
|
+
`Form`, `FormTextInput`, `FormSelect`, `FormMultiSelect`, `FormTextarea`,
|
|
15
|
+
`FormNumberInput`, `FormMonthPickerInput`, `FormCheckbox`,
|
|
16
|
+
`FormRadioGroup`, `FormSubmitButton` y wrappers cercanos del proyecto.
|
|
17
|
+
3. Importar primero desde `lkd-web-kit`. Usar wrappers locales solo cuando el proyecto ya los tenga y agreguen estilos o comportamiento propio.
|
|
18
|
+
4. No crear un wrapper nuevo si el kit o el proyecto ya tienen un campo equivalente.
|
|
19
|
+
5. Para formularios con validación, usar `useForm` con `zodResolver(schema)`.
|
|
20
|
+
6. Pasar `mode` solo cuando la API del componente lo soporte. No inventar props.
|
|
21
|
+
|
|
22
|
+
## Estructura recomendada
|
|
23
|
+
|
|
24
|
+
- Mantener formularios triviales inline.
|
|
25
|
+
- Cuando un formulario mapea datos de API o construye un payload, separar lo repetitivo:
|
|
26
|
+
- `schema`: objeto Zod y tipo inferido.
|
|
27
|
+
- `createDefaultValues`: datos de API/dominio a valores del formulario.
|
|
28
|
+
- `createPayload`: valores del formulario a payload de API.
|
|
29
|
+
- Usar `z.input<typeof schema>` para defaults cuando haya transforms o preprocess.
|
|
30
|
+
- Usar `z.infer<typeof schema>` para datos ya validados en submit.
|
|
31
|
+
- Colocar el código privado junto a la ruta o feature, salvo que sea realmente compartido.
|
|
32
|
+
|
|
33
|
+
## Validaciones con Zod
|
|
34
|
+
|
|
35
|
+
- Poner reglas de campo en el schema base.
|
|
36
|
+
- No poner mensajes textuales en reglas base de Zod como `min(1, "Texto")`; usar la configuración global de errores o la capa de traducciones del proyecto.
|
|
37
|
+
- Usar `superRefine` para reglas cruzadas entre campos y reglas de negocio.
|
|
38
|
+
- En `superRefine`, asociar el issue al campo que el usuario puede corregir usando `path`.
|
|
39
|
+
- Permitir mensajes custom en `superRefine` cuando el proyecto no tenga un mapeo de códigos para esa regla de negocio.
|
|
40
|
+
- Preferir `ctx.addIssue(...)`; usar `ctx.issues.push(...)` solo si ya es el patrón local.
|
|
41
|
+
|
|
42
|
+
## Campos y filtros
|
|
43
|
+
|
|
44
|
+
- Todo input que modifique estado de React Hook Form debe ser un componente `Form*`.
|
|
45
|
+
- Usar `My*` o inputs Mantine solo para UI standalone fuera de React Hook Form.
|
|
46
|
+
- Preferir componentes de campo del proyecto, como `NameField` o `StatusField`, cuando ya provean `name`, labels, opciones traducidas o carga de datos.
|
|
47
|
+
- Los filtros siguen el mismo patrón: `useForm` + `Form` + `Form*`.
|
|
48
|
+
- El submit de filtros puede actualizar query params, estado local o estado del padre según el proyecto; no agregar una librería de estado solo por un filtro.
|
|
49
|
+
- Si un campo client lee catálogos o datos cacheados, verificar que la página o el padre carguen esos datos según la convención del proyecto.
|
|
50
|
+
|
|
51
|
+
## Submit y errores
|
|
52
|
+
|
|
53
|
+
- Usar `FormSubmitButton` para acciones de submit. No usar aliases como `FormButtonSubmit` salvo que el proyecto realmente los exporte.
|
|
54
|
+
- Dejar que `FormSubmitButton` maneje el loading de submit mediante React Hook Form.
|
|
55
|
+
- En submits async, mostrar la notificación de éxito o error esperada por el proyecto.
|
|
56
|
+
- En `catch`, mostrar la notificación de error y luego hacer `throw error` para que el wrapper del formulario pueda reaccionar visualmente.
|
|
57
|
+
- Recortar o normalizar valores en el límite donde se arma el payload de API, no en handlers sueltos de campos.
|
|
58
|
+
|
|
59
|
+
## Antipatrones
|
|
60
|
+
|
|
61
|
+
- No usar `register` directamente para campos ya cubiertos por `Form*`.
|
|
62
|
+
- No duplicar wrappers tipo `FormTextInput` o `FormSelect`.
|
|
63
|
+
- No usar `any`; tipar valores del formulario desde el schema.
|
|
64
|
+
- No agregar helpers custom de validación cuando Zod ya cubre la regla.
|
|
65
|
+
- No mezclar campos Mantine no controlados dentro de un formulario de React Hook Form.
|
|
66
|
+
- No agregar dependencias nuevas para estado de formulario, validación de campos o filtros comunes.
|
|
67
|
+
|
|
68
|
+
## Ejemplos mínimos
|
|
69
|
+
|
|
70
|
+
Formulario de edición:
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
"use client";
|
|
74
|
+
|
|
75
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
76
|
+
import {
|
|
77
|
+
FormSelect,
|
|
78
|
+
FormSubmitButton,
|
|
79
|
+
FormTextInput,
|
|
80
|
+
} from "lkd-web-kit";
|
|
81
|
+
import { useForm } from "react-hook-form";
|
|
82
|
+
import z from "zod";
|
|
83
|
+
import Form from "src/components/form/Form";
|
|
84
|
+
|
|
85
|
+
const editSchema = z.object({
|
|
86
|
+
name: z.string().min(1),
|
|
87
|
+
status: z.string().nullable(),
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
type EditValues = z.infer<typeof editSchema>;
|
|
91
|
+
|
|
92
|
+
const createDefaultValues = (item: { name: string; status: string | null }): EditValues => ({
|
|
93
|
+
name: item.name,
|
|
94
|
+
status: item.status,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const createPayload = (data: EditValues) => ({
|
|
98
|
+
name: data.name.trim(),
|
|
99
|
+
status: data.status || undefined,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
export function EditItemForm({ item }: { item: { name: string; status: string | null } }) {
|
|
103
|
+
const methods = useForm<EditValues>({
|
|
104
|
+
defaultValues: createDefaultValues(item),
|
|
105
|
+
resolver: zodResolver(
|
|
106
|
+
editSchema.superRefine((data, ctx) => {
|
|
107
|
+
if (data.status === "published" && data.name.trim().length < 3) {
|
|
108
|
+
ctx.addIssue({
|
|
109
|
+
code: "custom",
|
|
110
|
+
message: "El nombre es demasiado corto para publicar",
|
|
111
|
+
path: ["name"],
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}),
|
|
115
|
+
),
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<Form
|
|
120
|
+
methods={methods}
|
|
121
|
+
onSubmit={async (data) => {
|
|
122
|
+
try {
|
|
123
|
+
await updateItem(createPayload(data));
|
|
124
|
+
} catch (error) {
|
|
125
|
+
showErrorNotification();
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}}
|
|
129
|
+
>
|
|
130
|
+
<FormTextInput name="name" label="Nombre" />
|
|
131
|
+
<FormSelect
|
|
132
|
+
name="status"
|
|
133
|
+
label="Estado"
|
|
134
|
+
data={[
|
|
135
|
+
{ value: "draft", label: "Borrador" },
|
|
136
|
+
{ value: "published", label: "Publicado" },
|
|
137
|
+
]}
|
|
138
|
+
/>
|
|
139
|
+
<FormSubmitButton>Guardar</FormSubmitButton>
|
|
140
|
+
</Form>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Filtro:
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
"use client";
|
|
149
|
+
|
|
150
|
+
import { FormSelect, FormSubmitButton, FormTextInput } from "lkd-web-kit";
|
|
151
|
+
import { useForm } from "react-hook-form";
|
|
152
|
+
import Form from "src/components/form/Form";
|
|
153
|
+
|
|
154
|
+
type FilterValues = {
|
|
155
|
+
search: string;
|
|
156
|
+
status: string | null;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export function ItemFilters({
|
|
160
|
+
onApply,
|
|
161
|
+
}: {
|
|
162
|
+
onApply: (values: FilterValues) => void;
|
|
163
|
+
}) {
|
|
164
|
+
const methods = useForm<FilterValues>({
|
|
165
|
+
defaultValues: {
|
|
166
|
+
search: "",
|
|
167
|
+
status: null,
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
<Form methods={methods} onSubmit={onApply}>
|
|
173
|
+
<FormTextInput name="search" label="Buscar" />
|
|
174
|
+
<FormSelect
|
|
175
|
+
name="status"
|
|
176
|
+
label="Estado"
|
|
177
|
+
data={[
|
|
178
|
+
{ value: "draft", label: "Borrador" },
|
|
179
|
+
{ value: "published", label: "Publicado" },
|
|
180
|
+
]}
|
|
181
|
+
/>
|
|
182
|
+
<FormSubmitButton>Aplicar</FormSubmitButton>
|
|
183
|
+
</Form>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
```
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: mantine-combobox
|
|
3
|
-
description: >
|
|
4
|
-
Build custom dropdown/select/autocomplete/multiselect components using Mantine's Combobox
|
|
5
|
-
primitives. Use this skill when: (1) creating a new custom select-like component with
|
|
6
|
-
Combobox primitives, (2) building a searchable dropdown, (3) implementing a multi-select
|
|
7
|
-
or tags input variant, (4) customizing option rendering, (5) adding custom filtering logic,
|
|
8
|
-
or (6) any task involving useCombobox, Combobox.Target, Combobox.Option, or Combobox.Dropdown.
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Mantine Combobox Skill
|
|
12
|
-
|
|
13
|
-
## Overview
|
|
14
|
-
|
|
15
|
-
`Combobox` provides low-level primitives for building any select-like UI. The built-in
|
|
16
|
-
`Select`, `Autocomplete`, and `TagsInput` components are all built on top of it.
|
|
17
|
-
|
|
18
|
-
## Core Workflow
|
|
19
|
-
|
|
20
|
-
### 1. Create the store
|
|
21
|
-
|
|
22
|
-
```tsx
|
|
23
|
-
const combobox = useCombobox({
|
|
24
|
-
onDropdownClose: () => combobox.resetSelectedOption(),
|
|
25
|
-
onDropdownOpen: () => combobox.selectFirstOption(),
|
|
26
|
-
});
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### 2. Render structure
|
|
30
|
-
|
|
31
|
-
```tsx
|
|
32
|
-
<Combobox store={combobox} onOptionSubmit={handleSubmit}>
|
|
33
|
-
<Combobox.Target>
|
|
34
|
-
<InputBase
|
|
35
|
-
component="button"
|
|
36
|
-
pointer
|
|
37
|
-
rightSection={<Combobox.Chevron />}
|
|
38
|
-
onClick={() => combobox.toggleDropdown()}
|
|
39
|
-
>
|
|
40
|
-
{value || <Input.Placeholder>Pick value</Input.Placeholder>}
|
|
41
|
-
</InputBase>
|
|
42
|
-
</Combobox.Target>
|
|
43
|
-
<Combobox.Dropdown>
|
|
44
|
-
<Combobox.Options>
|
|
45
|
-
{options.map((item) => (
|
|
46
|
-
<Combobox.Option value={item} key={item}>{item}</Combobox.Option>
|
|
47
|
-
))}
|
|
48
|
-
</Combobox.Options>
|
|
49
|
-
</Combobox.Dropdown>
|
|
50
|
-
</Combobox>
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### 3. Handle submit
|
|
54
|
-
|
|
55
|
-
```tsx
|
|
56
|
-
const handleSubmit = (val: string) => {
|
|
57
|
-
setValue(val);
|
|
58
|
-
combobox.closeDropdown();
|
|
59
|
-
};
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Target Types
|
|
63
|
-
|
|
64
|
-
| Scenario | Use |
|
|
65
|
-
|---|---|
|
|
66
|
-
| Button trigger (no text input) | `<Combobox.Target targetType="button">` |
|
|
67
|
-
| Input trigger | `<Combobox.Target>` (default) |
|
|
68
|
-
| Pills + separate input (multi-select) | `<Combobox.DropdownTarget>` + `<Combobox.EventsTarget>` |
|
|
69
|
-
|
|
70
|
-
## References
|
|
71
|
-
|
|
72
|
-
- **[`references/api.md`](references/api.md)** — Full API: `useCombobox` options and store, all sub-component props, CSS variables, Styles API selectors
|
|
73
|
-
- **[`references/patterns.md`](references/patterns.md)** — Code examples: searchable select, multi-select with pills, groups, custom rendering, clear button, form integration
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
# Combobox API Reference
|
|
2
|
-
|
|
3
|
-
## Table of Contents
|
|
4
|
-
- [useCombobox hook](#usecombobox-hook)
|
|
5
|
-
- [Combobox (root)](#combobox-root)
|
|
6
|
-
- [Sub-components](#sub-components)
|
|
7
|
-
- [CSS variables & Styles API](#css-variables--styles-api)
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## useCombobox hook
|
|
12
|
-
|
|
13
|
-
```tsx
|
|
14
|
-
const combobox = useCombobox(options?: UseComboboxOptions);
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
**Options:**
|
|
18
|
-
```ts
|
|
19
|
-
interface UseComboboxOptions {
|
|
20
|
-
defaultOpened?: boolean;
|
|
21
|
-
opened?: boolean;
|
|
22
|
-
onOpenedChange?: (opened: boolean) => void;
|
|
23
|
-
onDropdownClose?: (eventSource: 'keyboard' | 'mouse' | 'unknown') => void;
|
|
24
|
-
onDropdownOpen?: (eventSource: 'keyboard' | 'mouse' | 'unknown') => void;
|
|
25
|
-
loop?: boolean; // Default: true — keyboard nav wraps at boundaries
|
|
26
|
-
scrollBehavior?: ScrollBehavior; // Default: 'instant'
|
|
27
|
-
}
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
**Returned store:**
|
|
31
|
-
```ts
|
|
32
|
-
interface ComboboxStore {
|
|
33
|
-
// Dropdown state
|
|
34
|
-
dropdownOpened: boolean;
|
|
35
|
-
openDropdown(eventSource?: 'keyboard' | 'mouse' | 'unknown'): void;
|
|
36
|
-
closeDropdown(eventSource?: 'keyboard' | 'mouse' | 'unknown'): void;
|
|
37
|
-
toggleDropdown(eventSource?: 'keyboard' | 'mouse' | 'unknown'): void;
|
|
38
|
-
|
|
39
|
-
// Option keyboard navigation
|
|
40
|
-
selectActiveOption(): string | null;
|
|
41
|
-
selectFirstOption(): string | null;
|
|
42
|
-
selectNextOption(): string | null;
|
|
43
|
-
selectPreviousOption(): string | null;
|
|
44
|
-
resetSelectedOption(): void;
|
|
45
|
-
clickSelectedOption(): void;
|
|
46
|
-
updateSelectedOptionIndex(
|
|
47
|
-
target?: 'active' | 'selected' | number,
|
|
48
|
-
options?: { scrollIntoView?: boolean }
|
|
49
|
-
): void;
|
|
50
|
-
|
|
51
|
-
// Programmatic focus
|
|
52
|
-
focusSearchInput(): void;
|
|
53
|
-
focusTarget(): void;
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## Combobox (root)
|
|
60
|
-
|
|
61
|
-
```tsx
|
|
62
|
-
<Combobox
|
|
63
|
-
store={combobox} // required — ComboboxStore from useCombobox()
|
|
64
|
-
onOptionSubmit={fn} // (value: string, optionProps) => void
|
|
65
|
-
size="sm" // MantineSize | string, default: 'sm'
|
|
66
|
-
dropdownPadding={4} // number, default: 4
|
|
67
|
-
resetSelectionOnOptionHover // boolean
|
|
68
|
-
readOnly // boolean — disables all interactions
|
|
69
|
-
// + all Popover props (position, offset, width, withinPortal, etc.)
|
|
70
|
-
/>
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
---
|
|
74
|
-
|
|
75
|
-
## Sub-components
|
|
76
|
-
|
|
77
|
-
### Combobox.Target
|
|
78
|
-
```tsx
|
|
79
|
-
<Combobox.Target
|
|
80
|
-
targetType="input" // 'button' | 'input', default: 'input'
|
|
81
|
-
withKeyboardNavigation // boolean, default: true
|
|
82
|
-
withAriaAttributes // boolean, default: true
|
|
83
|
-
withExpandedAttribute // boolean, default: false
|
|
84
|
-
autoComplete="off" // string
|
|
85
|
-
>
|
|
86
|
-
{/* single child — the trigger element */}
|
|
87
|
-
</Combobox.Target>
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
Use `targetType="button"` when the trigger is a button (Space key toggles dropdown).
|
|
91
|
-
|
|
92
|
-
### Combobox.DropdownTarget
|
|
93
|
-
Marks the element used for dropdown positioning when separate from the keyboard events target. Used together with `Combobox.EventsTarget` in multi-select/pills patterns.
|
|
94
|
-
|
|
95
|
-
### Combobox.EventsTarget
|
|
96
|
-
Receives keyboard events for dropdown navigation. Used alongside `Combobox.DropdownTarget` when the typing input is nested inside the trigger (e.g. inside `PillsInput`).
|
|
97
|
-
|
|
98
|
-
### Combobox.Dropdown
|
|
99
|
-
```tsx
|
|
100
|
-
<Combobox.Dropdown hidden={false}>
|
|
101
|
-
{/* dropdown content */}
|
|
102
|
-
</Combobox.Dropdown>
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
Use `hidden` to hide without unmounting (preserves scroll position).
|
|
106
|
-
|
|
107
|
-
### Combobox.Options
|
|
108
|
-
```tsx
|
|
109
|
-
<Combobox.Options labelledBy="some-label-id">
|
|
110
|
-
{/* Combobox.Option or Combobox.Group elements */}
|
|
111
|
-
</Combobox.Options>
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### Combobox.Option
|
|
115
|
-
```tsx
|
|
116
|
-
<Combobox.Option
|
|
117
|
-
value="react" // string | number, required
|
|
118
|
-
active={false} // visually marks as selected; used by selectActiveOption()
|
|
119
|
-
disabled={false}
|
|
120
|
-
>
|
|
121
|
-
React
|
|
122
|
-
</Combobox.Option>
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### Combobox.Search
|
|
126
|
-
Built-in search input, wired to keyboard navigation. Renders sticky at top of dropdown.
|
|
127
|
-
|
|
128
|
-
```tsx
|
|
129
|
-
<Combobox.Search
|
|
130
|
-
value={search}
|
|
131
|
-
onChange={(e) => setSearch(e.currentTarget.value)}
|
|
132
|
-
placeholder="Search..."
|
|
133
|
-
withAriaAttributes // boolean, default: true
|
|
134
|
-
withKeyboardNavigation // boolean, default: true
|
|
135
|
-
// + all Input props
|
|
136
|
-
/>
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### Combobox.Empty
|
|
140
|
-
```tsx
|
|
141
|
-
<Combobox.Empty>Nothing found</Combobox.Empty>
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### Combobox.Group
|
|
145
|
-
```tsx
|
|
146
|
-
<Combobox.Group label="Frontend">
|
|
147
|
-
<Combobox.Option value="react">React</Combobox.Option>
|
|
148
|
-
</Combobox.Group>
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### Combobox.Header / Combobox.Footer
|
|
152
|
-
```tsx
|
|
153
|
-
<Combobox.Header>Custom header</Combobox.Header>
|
|
154
|
-
<Combobox.Footer>Custom footer</Combobox.Footer>
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### Combobox.Chevron
|
|
158
|
-
```tsx
|
|
159
|
-
<Combobox.Chevron size="sm" error={error} color="blue" />
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### Combobox.ClearButton
|
|
163
|
-
```tsx
|
|
164
|
-
<Combobox.ClearButton onClear={() => setValue(null)} />
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### Combobox.HiddenInput
|
|
168
|
-
```tsx
|
|
169
|
-
<Combobox.HiddenInput
|
|
170
|
-
value={value} // string | number | (string | number)[] | null
|
|
171
|
-
valuesDivider="," // string, default: ','
|
|
172
|
-
name="myField"
|
|
173
|
-
form="myForm"
|
|
174
|
-
/>
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
|
-
## CSS variables & Styles API
|
|
180
|
-
|
|
181
|
-
### CSS variables (set on root element)
|
|
182
|
-
| Variable | Description |
|
|
183
|
-
|---|---|
|
|
184
|
-
| `--combobox-option-fz` | Option font size (driven by `size` prop) |
|
|
185
|
-
| `--combobox-option-padding` | Option padding (driven by `size` prop) |
|
|
186
|
-
| `--combobox-padding` | Dropdown padding (driven by `dropdownPadding`, default 4px) |
|
|
187
|
-
|
|
188
|
-
### Styles API selectors
|
|
189
|
-
| Selector | Element |
|
|
190
|
-
|---|---|
|
|
191
|
-
| `dropdown` | Dropdown container |
|
|
192
|
-
| `options` | Options listbox |
|
|
193
|
-
| `option` | Individual option |
|
|
194
|
-
| `search` | Search input |
|
|
195
|
-
| `empty` | Nothing found message |
|
|
196
|
-
| `header` | Dropdown header |
|
|
197
|
-
| `footer` | Dropdown footer |
|
|
198
|
-
| `group` | Group container |
|
|
199
|
-
| `groupLabel` | Group label text |
|