@misael703/ui 1.14.0 → 1.15.0

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.
@@ -20,7 +20,8 @@ function Combobox({
20
20
  className,
21
21
  invalid,
22
22
  disabled,
23
- id
23
+ id,
24
+ searchable = true
24
25
  }) {
25
26
  const locale = useLocale();
26
27
  const ph = placeholder ?? locale["common.search"];
@@ -60,12 +61,14 @@ function Combobox({
60
61
  const onKey = (e) => {
61
62
  if (e.key === "ArrowDown") {
62
63
  e.preventDefault();
63
- setOpen(true);
64
- setActive((a) => Math.min(filtered.length - 1, a + 1));
64
+ if (!open) setOpen(true);
65
+ else setActive((a) => Math.min(filtered.length - 1, a + 1));
65
66
  } else if (e.key === "ArrowUp") {
67
+ if (!open) return;
66
68
  e.preventDefault();
67
69
  setActive((a) => Math.max(0, a - 1));
68
70
  } else if (e.key === "Enter") {
71
+ if (!open) return;
69
72
  e.preventDefault();
70
73
  const opt = filtered[active];
71
74
  if (opt && !opt.disabled) {
@@ -78,7 +81,7 @@ function Combobox({
78
81
  }
79
82
  };
80
83
  return /* @__PURE__ */ jsxs("div", { ref: wrapRef, className: cx("combobox", invalid && "is-invalid", disabled && "is-disabled", className), children: [
81
- /* @__PURE__ */ jsx(
84
+ searchable ? /* @__PURE__ */ jsx(
82
85
  "input",
83
86
  {
84
87
  ref: inputRef,
@@ -98,8 +101,28 @@ function Combobox({
98
101
  },
99
102
  onKeyDown: onKey
100
103
  }
104
+ ) : (
105
+ // Non-typing trigger: button shaped like `.combobox__input` (same
106
+ // border / radius / chevron) so the two variants line up visually.
107
+ // No clear button — the user re-picks from the listbox instead.
108
+ /* @__PURE__ */ jsx(
109
+ "button",
110
+ {
111
+ id,
112
+ type: "button",
113
+ role: "combobox",
114
+ "aria-haspopup": "listbox",
115
+ "aria-expanded": open,
116
+ "aria-controls": listboxId,
117
+ className: "combobox__trigger",
118
+ disabled,
119
+ onClick: () => setOpen((o) => !o),
120
+ onKeyDown: onKey,
121
+ children: selected ? /* @__PURE__ */ jsx("span", { className: "combobox__trigger-label", children: selected.label }) : /* @__PURE__ */ jsx("span", { className: "combobox__trigger-placeholder", children: ph })
122
+ }
123
+ )
101
124
  ),
102
- selected && !open && /* @__PURE__ */ jsx(
125
+ searchable && selected && !open && /* @__PURE__ */ jsx(
103
126
  "button",
104
127
  {
105
128
  type: "button",
@@ -526,5 +549,5 @@ function MonthPicker({
526
549
  }
527
550
 
528
551
  export { Combobox, DatePicker, FileUpload, MonthPicker, YearPicker };
529
- //# sourceMappingURL=chunk-TS6HCQLX.mjs.map
530
- //# sourceMappingURL=chunk-TS6HCQLX.mjs.map
552
+ //# sourceMappingURL=chunk-5MIN6LUP.mjs.map
553
+ //# sourceMappingURL=chunk-5MIN6LUP.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Pickers.tsx"],"names":[],"mappings":"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","file":"chunk-5MIN6LUP.mjs","sourcesContent":["'use client';\nimport * as React from 'react';\nimport { cx } from '../utils/cx';\nimport { CalendarIcon, ChevronLeft, ChevronRight, X } from './Icons';\nimport { resolveDateFormat, formatDate, parseDate, dateFormatPlaceholder, startOfMonth, addMonths, isSameDay, buildMonthGrid, type DateFormat } from '../utils/dateFormat';\nimport { useLocale } from '../locale/LocaleProvider';\nimport { Portal } from './Portal';\nimport { usePopoverPosition } from '../hooks/usePopoverPosition';\nimport { useDismiss } from '../hooks/useDismiss';\n\n// ---------- Combobox -----------------------------------------------------\nexport interface ComboboxOption<T = string> {\n value: T;\n label: string;\n description?: string;\n disabled?: boolean;\n}\n\nexport interface ComboboxProps<T = string> {\n value: T | null;\n onChange: (value: T | null) => void;\n options: ComboboxOption<T>[];\n placeholder?: string;\n emptyMessage?: string;\n filter?: (option: ComboboxOption<T>, query: string) => boolean;\n className?: string;\n invalid?: boolean;\n disabled?: boolean;\n id?: string;\n /**\n * Whether the trigger is a typeable text input that filters options.\n * Default `true` (the searchable Combobox). Set `false` for a non-typing\n * picker: button trigger + the same kit-styled listbox, no filter, full\n * list always. Closes the gap between native `<Select>` (jarring native\n * dropdown) and the searchable Combobox — same visual register, no input.\n */\n searchable?: boolean;\n}\n\nconst defaultFilter = <T,>(o: ComboboxOption<T>, q: string) =>\n o.label.toLowerCase().includes(q.toLowerCase());\n\nexport function Combobox<T = string>({\n value, onChange, options, placeholder,\n emptyMessage, filter = defaultFilter,\n className, invalid, disabled, id,\n searchable = true,\n}: ComboboxProps<T>) {\n const locale = useLocale();\n const ph = placeholder ?? locale['common.search'];\n const empty = emptyMessage ?? locale['common.noResults'];\n const [open, setOpen] = React.useState(false);\n const [query, setQuery] = React.useState('');\n const [active, setActive] = React.useState(0);\n const wrapRef = React.useRef<HTMLDivElement>(null);\n const inputRef = React.useRef<HTMLInputElement>(null);\n const listRef = React.useRef<HTMLUListElement>(null);\n // Stable per-instance listbox id so multiple Comboboxes don't collide on aria-controls.\n const reactId = React.useId();\n const listboxId = `${id ?? reactId}-listbox`;\n\n const selected = React.useMemo(\n () => options.find((o) => o.value === value) ?? null,\n [options, value]\n );\n const filtered = React.useMemo(\n () => (query ? options.filter((o) => filter(o, query)) : options),\n [options, query, filter]\n );\n\n const pos = usePopoverPosition(wrapRef, listRef, {\n open,\n side: 'bottom',\n align: 'start',\n offset: 4,\n matchAnchorWidth: true,\n });\n\n // Escape is handled by the input's onKeyDown; here we only need\n // outside-click (closeOnEscape: false avoids a double close).\n useDismiss({\n open,\n onDismiss: () => setOpen(false),\n refs: [wrapRef, listRef],\n closeOnEscape: false,\n });\n\n React.useEffect(() => { setActive(0); }, [query, open]);\n\n const onKey = (e: React.KeyboardEvent<HTMLElement>) => {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (!open) setOpen(true);\n else setActive((a) => Math.min(filtered.length - 1, a + 1));\n } else if (e.key === 'ArrowUp') {\n // Only navigate when the listbox is open (no-op otherwise).\n if (!open) return;\n e.preventDefault();\n setActive((a) => Math.max(0, a - 1));\n } else if (e.key === 'Enter') {\n // Only commit when the listbox is open — without this gate, Enter on\n // a button trigger that just opened would race with the open and\n // immediately select the first option.\n if (!open) return;\n e.preventDefault();\n const opt = filtered[active];\n if (opt && !opt.disabled) {\n onChange(opt.value);\n setQuery('');\n setOpen(false);\n }\n } else if (e.key === 'Escape') {\n setOpen(false);\n }\n };\n\n return (\n <div ref={wrapRef} className={cx('combobox', invalid && 'is-invalid', disabled && 'is-disabled', className)}>\n {searchable ? (\n <input\n ref={inputRef}\n id={id}\n type=\"text\"\n role=\"combobox\"\n aria-expanded={open}\n aria-controls={listboxId}\n className=\"combobox__input\"\n placeholder={ph}\n disabled={disabled}\n value={open ? query : selected?.label ?? ''}\n onFocus={() => setOpen(true)}\n onChange={(e) => { setQuery(e.target.value); setOpen(true); }}\n onKeyDown={onKey}\n />\n ) : (\n // Non-typing trigger: button shaped like `.combobox__input` (same\n // border / radius / chevron) so the two variants line up visually.\n // No clear button — the user re-picks from the listbox instead.\n <button\n id={id}\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={listboxId}\n className=\"combobox__trigger\"\n disabled={disabled}\n onClick={() => setOpen((o) => !o)}\n onKeyDown={onKey}\n >\n {selected ? (\n <span className=\"combobox__trigger-label\">{selected.label}</span>\n ) : (\n <span className=\"combobox__trigger-placeholder\">{ph}</span>\n )}\n </button>\n )}\n {searchable && selected && !open && (\n <button\n type=\"button\"\n className=\"combobox__clear\"\n onClick={() => { onChange(null); setQuery(''); inputRef.current?.focus(); }}\n aria-label={locale['picker.clearSelection']}\n ><X size={16} /></button>\n )}\n {open && (\n <Portal>\n <ul\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n className={cx('combobox__list', 'is-floating')}\n style={{\n position: 'fixed',\n top: pos.top,\n left: pos.left,\n width: pos.width,\n visibility: pos.ready ? 'visible' : 'hidden',\n }}\n >\n {filtered.length === 0 ? (\n <li className=\"combobox__empty\">{empty}</li>\n ) : (\n filtered.map((o, i) => (\n <li\n key={String(o.value)}\n role=\"option\"\n aria-selected={o.value === value}\n aria-disabled={o.disabled}\n className={cx('combobox__option', i === active && 'is-active', o.value === value && 'is-selected', o.disabled && 'is-disabled')}\n onMouseEnter={() => setActive(i)}\n onMouseDown={(e) => {\n e.preventDefault();\n if (o.disabled) return;\n onChange(o.value);\n setQuery('');\n setOpen(false);\n }}\n >\n <span className=\"combobox__option-label\">{o.label}</span>\n {o.description && <span className=\"combobox__option-desc\">{o.description}</span>}\n </li>\n ))\n )}\n </ul>\n </Portal>\n )}\n </div>\n );\n}\n\n// ---------- DatePicker (text + calendar popover) -------------------------\nexport interface DatePickerProps {\n value: Date | null;\n onChange: (date: Date | null) => void;\n minDate?: Date;\n maxDate?: Date;\n placeholder?: string;\n disabled?: boolean;\n invalid?: boolean;\n className?: string;\n id?: string;\n /**\n * Display & parse format. Default `'auto'` derives from `configureBrand().locale`\n * (e.g. `es-CL` → `dd-mm-aaaa`, `en-US` → `mm-dd-aaaa`, `ja-JP` → `aaaa-mm-dd`).\n */\n format?: DateFormat;\n}\n\nexport function DatePicker({\n value, onChange, minDate, maxDate, placeholder,\n disabled, invalid, className, id, format = 'auto',\n}: DatePickerProps) {\n const locale = useLocale();\n const fmt = resolveDateFormat(format);\n const ph = placeholder ?? dateFormatPlaceholder(fmt);\n const weekdays = locale['picker.weekdaysShort'];\n const months = locale['calendar.months'];\n const [open, setOpen] = React.useState(false);\n const [view, setView] = React.useState(() => startOfMonth(value ?? new Date()));\n const wrapRef = React.useRef<HTMLDivElement>(null);\n const popoverRef = React.useRef<HTMLDivElement>(null);\n\n // Portaled to body (escapes overflow ancestors) with flip/clamp and\n // scroll/resize reposition — same primitive as Combobox above. No\n // returnFocusRef: the input opens on focus, so refocusing it on close\n // would immediately reopen the calendar (Combobox omits it for the same\n // reason). Escape still closes via useDismiss's default handler.\n const pos = usePopoverPosition(wrapRef, popoverRef, {\n open,\n side: 'bottom',\n align: 'start',\n offset: 4,\n });\n\n useDismiss({\n open,\n onDismiss: () => setOpen(false),\n refs: [wrapRef, popoverRef],\n });\n\n React.useEffect(() => {\n if (value) setView(startOfMonth(value));\n }, [value]);\n\n const { cells } = buildMonthGrid(view, 0);\n\n const isDisabled = (d: Date) =>\n (minDate && d < new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())) ||\n (maxDate && d > new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate()));\n\n return (\n <div ref={wrapRef} className={cx('datepicker', invalid && 'is-invalid', disabled && 'is-disabled', className)}>\n <input\n id={id}\n type=\"text\"\n className=\"datepicker__input\"\n placeholder={ph}\n disabled={disabled}\n value={value ? formatDate(value, fmt) : ''}\n onChange={(e) => {\n const d = parseDate(e.target.value, fmt);\n onChange(d);\n }}\n onFocus={() => setOpen(true)}\n aria-invalid={invalid || undefined}\n />\n <button\n type=\"button\"\n className=\"datepicker__toggle\"\n onClick={() => setOpen((o) => !o)}\n disabled={disabled}\n aria-label={locale['picker.openCalendar']}\n ><CalendarIcon size={16} /></button>\n {open && (\n <Portal>\n <div\n ref={popoverRef}\n className={cx('datepicker__popover', 'is-floating')}\n role=\"dialog\"\n style={{\n position: 'fixed',\n top: pos.top,\n left: pos.left,\n visibility: pos.ready ? 'visible' : 'hidden',\n }}\n >\n <div className=\"datepicker__nav\">\n <button type=\"button\" onClick={() => setView((v) => addMonths(v, -1))} aria-label={locale['calendar.prevMonth']}><ChevronLeft size={16} /></button>\n <span className=\"datepicker__title\">{months[view.getMonth()]} {view.getFullYear()}</span>\n <button type=\"button\" onClick={() => setView((v) => addMonths(v, 1))} aria-label={locale['calendar.nextMonth']}><ChevronRight size={16} /></button>\n </div>\n <div className=\"datepicker__grid\">\n {weekdays.map((w, i) => <span key={i} className=\"datepicker__dow\">{w}</span>)}\n {cells.map((d, i) => {\n if (!d) return <span key={`b${i}`} />;\n const sel = value && isSameDay(d, value);\n const today = isSameDay(d, new Date());\n const off = isDisabled(d);\n return (\n <button\n key={i}\n type=\"button\"\n className={cx('datepicker__day', sel && 'is-selected', today && 'is-today', off && 'is-disabled')}\n disabled={!!off}\n onClick={() => { onChange(d); setOpen(false); }}\n >\n {d.getDate()}\n </button>\n );\n })}\n </div>\n </div>\n </Portal>\n )}\n </div>\n );\n}\n\n// ---------- FileUpload (drop zone) ---------------------------------------\nexport interface FileUploadProps {\n onFiles: (files: File[]) => void;\n accept?: string;\n multiple?: boolean;\n maxSize?: number; // bytes\n disabled?: boolean;\n className?: string;\n hint?: React.ReactNode;\n /** Accessible name for the drop zone (e.g. \"Subir foto de perfil\"). */\n 'aria-label'?: string;\n}\n\nexport function FileUpload({\n onFiles, accept, multiple = false, maxSize, disabled, className, hint,\n 'aria-label': ariaLabel,\n}: FileUploadProps) {\n const [drag, setDrag] = React.useState(false);\n const inputRef = React.useRef<HTMLInputElement>(null);\n const hintId = React.useId();\n const locale = useLocale();\n const handle = (list: FileList | null) => {\n if (!list) return;\n let arr = Array.from(list);\n if (maxSize) arr = arr.filter((f) => f.size <= maxSize);\n if (!multiple) arr = arr.slice(0, 1);\n onFiles(arr);\n };\n return (\n <div\n className={cx('file-upload', drag && 'is-drag', disabled && 'is-disabled', className)}\n onDragOver={(e) => { e.preventDefault(); if (!disabled) setDrag(true); }}\n onDragLeave={() => setDrag(false)}\n onDrop={(e) => { e.preventDefault(); setDrag(false); if (!disabled) handle(e.dataTransfer.files); }}\n onClick={() => !disabled && inputRef.current?.click()}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-label={ariaLabel}\n aria-describedby={hint ? hintId : undefined}\n onKeyDown={(e) => { if ((e.key === 'Enter' || e.key === ' ') && !disabled) inputRef.current?.click(); }}\n >\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n hidden\n onChange={(e) => handle(e.target.files)}\n />\n <div className=\"file-upload__icon\" aria-hidden=\"true\">⤴</div>\n <div className=\"file-upload__title\">{locale['fileUpload.title']}</div>\n {hint && <div id={hintId} className=\"file-upload__hint\">{hint}</div>}\n </div>\n );\n}\n\n// ---------- GridPickerField (shared shell: YearPicker / MonthPicker) ------\ninterface GridCell {\n key: string;\n label: React.ReactNode;\n selected?: boolean;\n /** Dimmed (outside the current decade) — YearPicker only. */\n outside?: boolean;\n disabled?: boolean;\n onSelect: () => void;\n}\n\ninterface GridPickerFieldProps {\n rootClass: string;\n displayValue: string;\n placeholder: string;\n ariaLabel: string;\n navTitle: React.ReactNode;\n prevLabel: string;\n nextLabel: string;\n onPrev: () => void;\n onNext: () => void;\n cells: GridCell[];\n disabled?: boolean;\n invalid?: boolean;\n id?: string;\n className?: string;\n}\n\nfunction GridPickerField({\n rootClass, displayValue, placeholder, ariaLabel, navTitle,\n prevLabel, nextLabel, onPrev, onNext, cells,\n disabled, invalid, id, className,\n}: GridPickerFieldProps) {\n const [open, setOpen] = React.useState(false);\n const wrapRef = React.useRef<HTMLDivElement>(null);\n const popoverRef = React.useRef<HTMLDivElement>(null);\n\n // Same floating primitive as DatePicker (Portal + flip/clamp + dismiss).\n const pos = usePopoverPosition(wrapRef, popoverRef, {\n open,\n side: 'bottom',\n align: 'start',\n offset: 4,\n });\n useDismiss({ open, onDismiss: () => setOpen(false), refs: [wrapRef, popoverRef] });\n\n return (\n <div\n ref={wrapRef}\n className={cx(rootClass, 'gridpicker', invalid && 'is-invalid', disabled && 'is-disabled', className)}\n >\n <input\n id={id}\n type=\"text\"\n readOnly\n className=\"gridpicker__input\"\n placeholder={placeholder}\n disabled={disabled}\n value={displayValue}\n onFocus={() => setOpen(true)}\n onClick={() => setOpen(true)}\n aria-invalid={invalid || undefined}\n />\n <button\n type=\"button\"\n className=\"gridpicker__toggle\"\n onClick={() => setOpen((o) => !o)}\n disabled={disabled}\n aria-label={ariaLabel}\n >\n <CalendarIcon size={16} />\n </button>\n {open && (\n <Portal>\n <div\n ref={popoverRef}\n className={cx('gridpicker__popover', 'is-floating')}\n role=\"dialog\"\n style={{\n position: 'fixed',\n top: pos.top,\n left: pos.left,\n visibility: pos.ready ? 'visible' : 'hidden',\n }}\n >\n <div className=\"gridpicker__nav\">\n <button type=\"button\" onClick={onPrev} aria-label={prevLabel}><ChevronLeft size={16} /></button>\n <span className=\"gridpicker__title\">{navTitle}</span>\n <button type=\"button\" onClick={onNext} aria-label={nextLabel}><ChevronRight size={16} /></button>\n </div>\n <div className=\"gridpicker__grid\">\n {cells.map((c) => (\n <button\n key={c.key}\n type=\"button\"\n className={cx('gridpicker__cell', c.selected && 'is-selected', c.outside && 'is-out')}\n disabled={c.disabled}\n onClick={() => { c.onSelect(); setOpen(false); }}\n >\n {c.label}\n </button>\n ))}\n </div>\n </div>\n </Portal>\n )}\n </div>\n );\n}\n\n// ---------- YearPicker ---------------------------------------------------\nexport interface YearPickerProps {\n value: number | null;\n onChange: (year: number | null) => void;\n minYear?: number;\n maxYear?: number;\n placeholder?: string;\n disabled?: boolean;\n invalid?: boolean;\n id?: string;\n className?: string;\n}\n\nexport function YearPicker({\n value, onChange, minYear, maxYear, placeholder,\n disabled, invalid, id, className,\n}: YearPickerProps) {\n const t = useLocale();\n const base = value ?? new Date().getFullYear();\n const [decade, setDecade] = React.useState(Math.floor(base / 10) * 10);\n\n React.useEffect(() => {\n if (value != null) setDecade(Math.floor(value / 10) * 10);\n }, [value]);\n\n const cells: GridCell[] = Array.from({ length: 12 }, (_, i) => {\n const year = decade - 1 + i;\n return {\n key: String(year),\n label: year,\n selected: value === year,\n outside: year < decade || year > decade + 9,\n disabled: (minYear != null && year < minYear) || (maxYear != null && year > maxYear),\n onSelect: () => onChange(year),\n };\n });\n\n return (\n <GridPickerField\n rootClass=\"yearpicker\"\n displayValue={value != null ? String(value) : ''}\n placeholder={placeholder ?? t['picker.selectYear']}\n ariaLabel={t['picker.openCalendar']}\n navTitle={`${decade}-${decade + 9}`}\n prevLabel={t['picker.prevDecade']}\n nextLabel={t['picker.nextDecade']}\n onPrev={() => setDecade((d) => d - 10)}\n onNext={() => setDecade((d) => d + 10)}\n cells={cells}\n disabled={disabled}\n invalid={invalid}\n id={id}\n className={className}\n />\n );\n}\n\n// ---------- MonthPicker --------------------------------------------------\nexport interface MonthPickerProps {\n value: Date | null;\n onChange: (date: Date | null) => void;\n minDate?: Date;\n maxDate?: Date;\n placeholder?: string;\n disabled?: boolean;\n invalid?: boolean;\n id?: string;\n className?: string;\n}\n\nexport function MonthPicker({\n value, onChange, minDate, maxDate, placeholder,\n disabled, invalid, id, className,\n}: MonthPickerProps) {\n const t = useLocale();\n const months = t['calendar.months'];\n const base = value ?? new Date();\n const [year, setYear] = React.useState(base.getFullYear());\n\n React.useEffect(() => {\n if (value) setYear(value.getFullYear());\n }, [value]);\n\n const monthStart = (y: number, m: number) => new Date(y, m, 1);\n const outOfRange = (m: number) =>\n (minDate != null && monthStart(year, m) < monthStart(minDate.getFullYear(), minDate.getMonth())) ||\n (maxDate != null && monthStart(year, m) > monthStart(maxDate.getFullYear(), maxDate.getMonth()));\n\n const cells: GridCell[] = months.map((name, m) => ({\n key: String(m),\n label: name,\n selected: !!value && value.getFullYear() === year && value.getMonth() === m,\n disabled: outOfRange(m),\n onSelect: () => onChange(new Date(year, m, 1)),\n }));\n\n return (\n <GridPickerField\n rootClass=\"monthpicker\"\n displayValue={value ? `${months[value.getMonth()]} ${value.getFullYear()}` : ''}\n placeholder={placeholder ?? t['picker.selectMonth']}\n ariaLabel={t['picker.openCalendar']}\n navTitle={String(year)}\n prevLabel={t['picker.prevYear']}\n nextLabel={t['picker.nextYear']}\n onPrev={() => setYear((y) => y - 1)}\n onNext={() => setYear((y) => y + 1)}\n cells={cells}\n disabled={disabled}\n invalid={invalid}\n id={id}\n className={className}\n />\n );\n}\n"]}
@@ -42,7 +42,8 @@ function Combobox({
42
42
  className,
43
43
  invalid,
44
44
  disabled,
45
- id
45
+ id,
46
+ searchable = true
46
47
  }) {
47
48
  const locale = chunk4VMQLSHV_js.useLocale();
48
49
  const ph = placeholder ?? locale["common.search"];
@@ -82,12 +83,14 @@ function Combobox({
82
83
  const onKey = (e) => {
83
84
  if (e.key === "ArrowDown") {
84
85
  e.preventDefault();
85
- setOpen(true);
86
- setActive((a) => Math.min(filtered.length - 1, a + 1));
86
+ if (!open) setOpen(true);
87
+ else setActive((a) => Math.min(filtered.length - 1, a + 1));
87
88
  } else if (e.key === "ArrowUp") {
89
+ if (!open) return;
88
90
  e.preventDefault();
89
91
  setActive((a) => Math.max(0, a - 1));
90
92
  } else if (e.key === "Enter") {
93
+ if (!open) return;
91
94
  e.preventDefault();
92
95
  const opt = filtered[active];
93
96
  if (opt && !opt.disabled) {
@@ -100,7 +103,7 @@ function Combobox({
100
103
  }
101
104
  };
102
105
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: wrapRef, className: chunkPASF6T4H_js.cx("combobox", invalid && "is-invalid", disabled && "is-disabled", className), children: [
103
- /* @__PURE__ */ jsxRuntime.jsx(
106
+ searchable ? /* @__PURE__ */ jsxRuntime.jsx(
104
107
  "input",
105
108
  {
106
109
  ref: inputRef,
@@ -120,8 +123,28 @@ function Combobox({
120
123
  },
121
124
  onKeyDown: onKey
122
125
  }
126
+ ) : (
127
+ // Non-typing trigger: button shaped like `.combobox__input` (same
128
+ // border / radius / chevron) so the two variants line up visually.
129
+ // No clear button — the user re-picks from the listbox instead.
130
+ /* @__PURE__ */ jsxRuntime.jsx(
131
+ "button",
132
+ {
133
+ id,
134
+ type: "button",
135
+ role: "combobox",
136
+ "aria-haspopup": "listbox",
137
+ "aria-expanded": open,
138
+ "aria-controls": listboxId,
139
+ className: "combobox__trigger",
140
+ disabled,
141
+ onClick: () => setOpen((o) => !o),
142
+ onKeyDown: onKey,
143
+ children: selected ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "combobox__trigger-label", children: selected.label }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "combobox__trigger-placeholder", children: ph })
144
+ }
145
+ )
123
146
  ),
124
- selected && !open && /* @__PURE__ */ jsxRuntime.jsx(
147
+ searchable && selected && !open && /* @__PURE__ */ jsxRuntime.jsx(
125
148
  "button",
126
149
  {
127
150
  type: "button",
@@ -552,5 +575,5 @@ exports.DatePicker = DatePicker;
552
575
  exports.FileUpload = FileUpload;
553
576
  exports.MonthPicker = MonthPicker;
554
577
  exports.YearPicker = YearPicker;
555
- //# sourceMappingURL=chunk-CPATAMLH.js.map
556
- //# sourceMappingURL=chunk-CPATAMLH.js.map
578
+ //# sourceMappingURL=chunk-62F5E5NQ.js.map
579
+ //# sourceMappingURL=chunk-62F5E5NQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Pickers.tsx"],"names":["useLocale","React","usePopoverPosition","useDismiss","jsxs","cx","jsx","X","Portal","resolveDateFormat","dateFormatPlaceholder","startOfMonth","buildMonthGrid","formatDate","parseDate","CalendarIcon","addMonths","ChevronLeft","ChevronRight","isSameDay"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,IAAM,aAAA,GAAgB,CAAK,CAAA,EAAsB,CAAA,KAC/C,CAAA,CAAE,KAAA,CAAM,WAAA,EAAY,CAAE,QAAA,CAAS,CAAA,CAAE,WAAA,EAAa,CAAA;AAEzC,SAAS,QAAA,CAAqB;AAAA,EACnC,KAAA;AAAA,EAAO,QAAA;AAAA,EAAU,OAAA;AAAA,EAAS,WAAA;AAAA,EAC1B,YAAA;AAAA,EAAc,MAAA,GAAS,aAAA;AAAA,EACvB,SAAA;AAAA,EAAW,OAAA;AAAA,EAAS,QAAA;AAAA,EAAU,EAAA;AAAA,EAC9B,UAAA,GAAa;AACf,CAAA,EAAqB;AACnB,EAAA,MAAM,SAASA,0BAAA,EAAU;AACzB,EAAA,MAAM,EAAA,GAAK,WAAA,IAAe,MAAA,CAAO,eAAe,CAAA;AAChD,EAAA,MAAM,KAAA,GAAQ,YAAA,IAAgB,MAAA,CAAO,kBAAkB,CAAA;AACvD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAUC,0BAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAUA,0BAAS,EAAE,CAAA;AAC3C,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAUA,0BAAS,CAAC,CAAA;AAC5C,EAAA,MAAM,OAAA,GAAgBA,wBAAuB,IAAI,CAAA;AACjD,EAAA,MAAM,QAAA,GAAiBA,wBAAyB,IAAI,CAAA;AACpD,EAAA,MAAM,OAAA,GAAgBA,wBAAyB,IAAI,CAAA;AAEnD,EAAA,MAAM,UAAgBA,gBAAA,CAAA,KAAA,EAAM;AAC5B,EAAA,MAAM,SAAA,GAAY,CAAA,EAAG,EAAA,IAAM,OAAO,CAAA,QAAA,CAAA;AAElC,EAAA,MAAM,QAAA,GAAiBA,gBAAA,CAAA,OAAA;AAAA,IACrB,MAAM,QAAQ,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,KAAA,KAAU,KAAK,CAAA,IAAK,IAAA;AAAA,IAChD,CAAC,SAAS,KAAK;AAAA,GACjB;AACA,EAAA,MAAM,QAAA,GAAiBA,gBAAA,CAAA,OAAA;AAAA,IACrB,MAAO,KAAA,GAAQ,OAAA,CAAQ,MAAA,CAAO,CAAC,MAAM,MAAA,CAAO,CAAA,EAAG,KAAK,CAAC,CAAA,GAAI,OAAA;AAAA,IACzD,CAAC,OAAA,EAAS,KAAA,EAAO,MAAM;AAAA,GACzB;AAEA,EAAA,MAAM,GAAA,GAAMC,mCAAA,CAAmB,OAAA,EAAS,OAAA,EAAS;AAAA,IAC/C,IAAA;AAAA,IACA,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,MAAA,EAAQ,CAAA;AAAA,IACR,gBAAA,EAAkB;AAAA,GACnB,CAAA;AAID,EAAAC,2BAAA,CAAW;AAAA,IACT,IAAA;AAAA,IACA,SAAA,EAAW,MAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,IAC9B,IAAA,EAAM,CAAC,OAAA,EAAS,OAAO,CAAA;AAAA,IACvB,aAAA,EAAe;AAAA,GAChB,CAAA;AAED,EAAMF,2BAAU,MAAM;AAAE,IAAA,SAAA,CAAU,CAAC,CAAA;AAAA,EAAG,CAAA,EAAG,CAAC,KAAA,EAAO,IAAI,CAAC,CAAA;AAEtD,EAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,KAAwC;AACrD,IAAA,IAAI,CAAA,CAAE,QAAQ,WAAA,EAAa;AACzB,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,IAAI,CAAC,IAAA,EAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,WAClB,SAAA,CAAU,CAAC,CAAA,KAAM,IAAA,CAAK,GAAA,CAAI,SAAS,MAAA,GAAS,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAA;AAAA,IAC5D,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,SAAA,EAAW;AAE9B,MAAA,IAAI,CAAC,IAAA,EAAM;AACX,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,SAAA,CAAU,CAAC,CAAA,KAAM,IAAA,CAAK,IAAI,CAAA,EAAG,CAAA,GAAI,CAAC,CAAC,CAAA;AAAA,IACrC,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,OAAA,EAAS;AAI5B,MAAA,IAAI,CAAC,IAAA,EAAM;AACX,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,MAAM,GAAA,GAAM,SAAS,MAAM,CAAA;AAC3B,MAAA,IAAI,GAAA,IAAO,CAAC,GAAA,CAAI,QAAA,EAAU;AACxB,QAAA,QAAA,CAAS,IAAI,KAAK,CAAA;AAClB,QAAA,QAAA,CAAS,EAAE,CAAA;AACX,QAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,MACf;AAAA,IACF,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU;AAC7B,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACf;AAAA,EACF,CAAA;AAEA,EAAA,uBACEG,eAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,OAAA,EAAS,SAAA,EAAWC,mBAAA,CAAG,UAAA,EAAY,OAAA,IAAW,YAAA,EAAc,QAAA,IAAY,aAAA,EAAe,SAAS,CAAA,EACvG,QAAA,EAAA;AAAA,IAAA,UAAA,mBACCC,cAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,QAAA;AAAA,QACL,EAAA;AAAA,QACA,IAAA,EAAK,MAAA;AAAA,QACL,IAAA,EAAK,UAAA;AAAA,QACL,eAAA,EAAe,IAAA;AAAA,QACf,eAAA,EAAe,SAAA;AAAA,QACf,SAAA,EAAU,iBAAA;AAAA,QACV,WAAA,EAAa,EAAA;AAAA,QACb,QAAA;AAAA,QACA,KAAA,EAAO,IAAA,GAAO,KAAA,GAAQ,QAAA,EAAU,KAAA,IAAS,EAAA;AAAA,QACzC,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,QAC3B,QAAA,EAAU,CAAC,CAAA,KAAM;AAAE,UAAA,QAAA,CAAS,CAAA,CAAE,OAAO,KAAK,CAAA;AAAG,UAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,QAAG,CAAA;AAAA,QAC5D,SAAA,EAAW;AAAA;AAAA,KACb;AAAA;AAAA;AAAA;AAAA,sBAKAA,cAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,EAAA;AAAA,UACA,IAAA,EAAK,QAAA;AAAA,UACL,IAAA,EAAK,UAAA;AAAA,UACL,eAAA,EAAc,SAAA;AAAA,UACd,eAAA,EAAe,IAAA;AAAA,UACf,eAAA,EAAe,SAAA;AAAA,UACf,SAAA,EAAU,mBAAA;AAAA,UACV,QAAA;AAAA,UACA,SAAS,MAAM,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,UAChC,SAAA,EAAW,KAAA;AAAA,UAEV,QAAA,EAAA,QAAA,mBACCA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yBAAA,EAA2B,QAAA,EAAA,QAAA,CAAS,KAAA,EAAM,CAAA,mBAE1DA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,+BAAA,EAAiC,QAAA,EAAA,EAAA,EAAG;AAAA;AAAA;AAExD,KAAA;AAAA,IAED,UAAA,IAAc,QAAA,IAAY,CAAC,IAAA,oBAC1BA,cAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAU,iBAAA;AAAA,QACV,SAAS,MAAM;AAAE,UAAA,QAAA,CAAS,IAAI,CAAA;AAAG,UAAA,QAAA,CAAS,EAAE,CAAA;AAAG,UAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AAAA,QAAG,CAAA;AAAA,QAC1E,YAAA,EAAY,OAAO,uBAAuB,CAAA;AAAA,QAC3C,QAAA,kBAAAA,cAAA,CAACC,kBAAA,EAAA,EAAE,IAAA,EAAM,EAAA,EAAI;AAAA;AAAA,KAAE;AAAA,IAEjB,IAAA,mCACEC,uBAAA,EAAA,EACD,QAAA,kBAAAF,cAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,OAAA;AAAA,QACL,EAAA,EAAI,SAAA;AAAA,QACJ,IAAA,EAAK,SAAA;AAAA,QACL,SAAA,EAAWD,mBAAA,CAAG,gBAAA,EAAkB,aAAa,CAAA;AAAA,QAC7C,KAAA,EAAO;AAAA,UACL,QAAA,EAAU,OAAA;AAAA,UACV,KAAK,GAAA,CAAI,GAAA;AAAA,UACT,MAAM,GAAA,CAAI,IAAA;AAAA,UACV,OAAO,GAAA,CAAI,KAAA;AAAA,UACX,UAAA,EAAY,GAAA,CAAI,KAAA,GAAQ,SAAA,GAAY;AAAA,SACtC;AAAA,QAEC,QAAA,EAAA,QAAA,CAAS,MAAA,KAAW,CAAA,mBACnBC,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,iBAAA,EAAmB,QAAA,EAAA,KAAA,EAAM,CAAA,GAEvC,QAAA,CAAS,GAAA,CAAI,CAAC,GAAG,CAAA,qBACfF,eAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAK,QAAA;AAAA,YACL,eAAA,EAAe,EAAE,KAAA,KAAU,KAAA;AAAA,YAC3B,iBAAe,CAAA,CAAE,QAAA;AAAA,YACjB,SAAA,EAAWC,mBAAA,CAAG,kBAAA,EAAoB,CAAA,KAAM,MAAA,IAAU,WAAA,EAAa,CAAA,CAAE,KAAA,KAAU,KAAA,IAAS,aAAA,EAAe,CAAA,CAAE,QAAA,IAAY,aAAa,CAAA;AAAA,YAC9H,YAAA,EAAc,MAAM,SAAA,CAAU,CAAC,CAAA;AAAA,YAC/B,WAAA,EAAa,CAAC,CAAA,KAAM;AAClB,cAAA,CAAA,CAAE,cAAA,EAAe;AACjB,cAAA,IAAI,EAAE,QAAA,EAAU;AAChB,cAAA,QAAA,CAAS,EAAE,KAAK,CAAA;AAChB,cAAA,QAAA,CAAS,EAAE,CAAA;AACX,cAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,YACf,CAAA;AAAA,YAEA,QAAA,EAAA;AAAA,8BAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wBAAA,EAA0B,QAAA,EAAA,CAAA,CAAE,KAAA,EAAM,CAAA;AAAA,cACjD,EAAE,WAAA,oBAAeA,cAAA,CAAC,UAAK,SAAA,EAAU,uBAAA,EAAyB,YAAE,WAAA,EAAY;AAAA;AAAA,WAAA;AAAA,UAfpE,MAAA,CAAO,EAAE,KAAK;AAAA,SAiBtB;AAAA;AAAA,KAEL,EACA;AAAA,GAAA,EAEJ,CAAA;AAEJ;AAoBO,SAAS,UAAA,CAAW;AAAA,EACzB,KAAA;AAAA,EAAO,QAAA;AAAA,EAAU,OAAA;AAAA,EAAS,OAAA;AAAA,EAAS,WAAA;AAAA,EACnC,QAAA;AAAA,EAAU,OAAA;AAAA,EAAS,SAAA;AAAA,EAAW,EAAA;AAAA,EAAI,MAAA,GAAS;AAC7C,CAAA,EAAoB;AAClB,EAAA,MAAM,SAASN,0BAAA,EAAU;AACzB,EAAA,MAAM,GAAA,GAAMS,mCAAkB,MAAM,CAAA;AACpC,EAAA,MAAM,EAAA,GAAK,WAAA,IAAeC,sCAAA,CAAsB,GAAG,CAAA;AACnD,EAAA,MAAM,QAAA,GAAW,OAAO,sBAAsB,CAAA;AAC9C,EAAA,MAAM,MAAA,GAAS,OAAO,iBAAiB,CAAA;AACvC,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAUT,0BAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAUA,gBAAA,CAAA,QAAA,CAAS,MAAMU,6BAAA,CAAa,KAAA,oBAAS,IAAI,IAAA,EAAM,CAAC,CAAA;AAC9E,EAAA,MAAM,OAAA,GAAgBV,wBAAuB,IAAI,CAAA;AACjD,EAAA,MAAM,UAAA,GAAmBA,wBAAuB,IAAI,CAAA;AAOpD,EAAA,MAAM,GAAA,GAAMC,mCAAA,CAAmB,OAAA,EAAS,UAAA,EAAY;AAAA,IAClD,IAAA;AAAA,IACA,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,MAAA,EAAQ;AAAA,GACT,CAAA;AAED,EAAAC,2BAAA,CAAW;AAAA,IACT,IAAA;AAAA,IACA,SAAA,EAAW,MAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,IAC9B,IAAA,EAAM,CAAC,OAAA,EAAS,UAAU;AAAA,GAC3B,CAAA;AAED,EAAMF,2BAAU,MAAM;AACpB,IAAA,IAAI,KAAA,EAAO,OAAA,CAAQU,6BAAA,CAAa,KAAK,CAAC,CAAA;AAAA,EACxC,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,MAAM,EAAE,KAAA,EAAM,GAAIC,+BAAA,CAAe,MAAM,CAAC,CAAA;AAExC,EAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KACjB,OAAA,IAAW,CAAA,GAAI,IAAI,IAAA,CAAK,OAAA,CAAQ,WAAA,EAAY,EAAG,OAAA,CAAQ,QAAA,EAAS,EAAG,OAAA,CAAQ,OAAA,EAAS,CAAA,IACpF,OAAA,IAAW,CAAA,GAAI,IAAI,IAAA,CAAK,OAAA,CAAQ,WAAA,EAAY,EAAG,OAAA,CAAQ,QAAA,EAAS,EAAG,OAAA,CAAQ,SAAS,CAAA;AAEvF,EAAA,uBACER,eAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,OAAA,EAAS,SAAA,EAAWC,mBAAA,CAAG,YAAA,EAAc,OAAA,IAAW,YAAA,EAAc,QAAA,IAAY,aAAA,EAAe,SAAS,CAAA,EAC1G,QAAA,EAAA;AAAA,oBAAAC,cAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,EAAA;AAAA,QACA,IAAA,EAAK,MAAA;AAAA,QACL,SAAA,EAAU,mBAAA;AAAA,QACV,WAAA,EAAa,EAAA;AAAA,QACb,QAAA;AAAA,QACA,KAAA,EAAO,KAAA,GAAQO,2BAAA,CAAW,KAAA,EAAO,GAAG,CAAA,GAAI,EAAA;AAAA,QACxC,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,UAAA,MAAM,CAAA,GAAIC,0BAAA,CAAU,CAAA,CAAE,MAAA,CAAO,OAAO,GAAG,CAAA;AACvC,UAAA,QAAA,CAAS,CAAC,CAAA;AAAA,QACZ,CAAA;AAAA,QACA,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,QAC3B,gBAAc,OAAA,IAAW;AAAA;AAAA,KAC3B;AAAA,oBACAR,cAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAU,oBAAA;AAAA,QACV,SAAS,MAAM,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,QAChC,QAAA;AAAA,QACA,YAAA,EAAY,OAAO,qBAAqB,CAAA;AAAA,QACzC,QAAA,kBAAAA,cAAA,CAACS,6BAAA,EAAA,EAAa,IAAA,EAAM,EAAA,EAAI;AAAA;AAAA,KAAE;AAAA,IAC1B,IAAA,mCACEP,uBAAA,EAAA,EACD,QAAA,kBAAAJ,eAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,UAAA;AAAA,QACL,SAAA,EAAWC,mBAAA,CAAG,qBAAA,EAAuB,aAAa,CAAA;AAAA,QAClD,IAAA,EAAK,QAAA;AAAA,QACL,KAAA,EAAO;AAAA,UACL,QAAA,EAAU,OAAA;AAAA,UACV,KAAK,GAAA,CAAI,GAAA;AAAA,UACT,MAAM,GAAA,CAAI,IAAA;AAAA,UACV,UAAA,EAAY,GAAA,CAAI,KAAA,GAAQ,SAAA,GAAY;AAAA,SACtC;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAAD,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,iBAAA,EACb,QAAA,EAAA;AAAA,4BAAAE,cAAA,CAAC,QAAA,EAAA,EAAO,MAAK,QAAA,EAAS,OAAA,EAAS,MAAM,OAAA,CAAQ,CAAC,MAAMU,0BAAA,CAAU,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,cAAY,MAAA,CAAO,oBAAoB,GAAG,QAAA,kBAAAV,cAAA,CAACW,4BAAA,EAAA,EAAY,IAAA,EAAM,EAAA,EAAI,CAAA,EAAE,CAAA;AAAA,4BAC1Ib,eAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mBAAA,EAAqB,QAAA,EAAA;AAAA,cAAA,MAAA,CAAO,IAAA,CAAK,UAAU,CAAA;AAAA,cAAE,GAAA;AAAA,cAAE,KAAK,WAAA;AAAY,aAAA,EAAE,CAAA;AAAA,4BAClFE,cAAA,CAAC,YAAO,IAAA,EAAK,QAAA,EAAS,SAAS,MAAM,OAAA,CAAQ,CAAC,CAAA,KAAMU,0BAAA,CAAU,CAAA,EAAG,CAAC,CAAC,CAAA,EAAG,cAAY,MAAA,CAAO,oBAAoB,GAAG,QAAA,kBAAAV,cAAA,CAACY,6BAAA,EAAA,EAAa,IAAA,EAAM,EAAA,EAAI,CAAA,EAAE;AAAA,WAAA,EAC5I,CAAA;AAAA,0BACAd,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBAAA,EACZ,QAAA,EAAA;AAAA,YAAA,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBAAME,cAAA,CAAC,UAAa,SAAA,EAAU,iBAAA,EAAmB,QAAA,EAAA,CAAA,EAAA,EAAhC,CAAkC,CAAO,CAAA;AAAA,YAC3E,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM;AACnB,cAAA,IAAI,CAAC,CAAA,EAAG,sCAAQ,MAAA,EAAA,EAAA,EAAU,CAAA,CAAA,EAAI,CAAC,CAAA,CAAI,CAAA;AACnC,cAAA,MAAM,GAAA,GAAM,KAAA,IAASa,0BAAA,CAAU,CAAA,EAAG,KAAK,CAAA;AACvC,cAAA,MAAM,KAAA,GAAQA,0BAAA,CAAU,CAAA,kBAAG,IAAI,MAAM,CAAA;AACrC,cAAA,MAAM,GAAA,GAAM,WAAW,CAAC,CAAA;AACxB,cAAA,uBACEb,cAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBAEC,IAAA,EAAK,QAAA;AAAA,kBACL,SAAA,EAAWD,oBAAG,iBAAA,EAAmB,GAAA,IAAO,eAAe,KAAA,IAAS,UAAA,EAAY,OAAO,aAAa,CAAA;AAAA,kBAChG,QAAA,EAAU,CAAC,CAAC,GAAA;AAAA,kBACZ,SAAS,MAAM;AAAE,oBAAA,QAAA,CAAS,CAAC,CAAA;AAAG,oBAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,kBAAG,CAAA;AAAA,kBAE7C,YAAE,OAAA;AAAQ,iBAAA;AAAA,gBANN;AAAA,eAOP;AAAA,YAEJ,CAAC;AAAA,WAAA,EACH;AAAA;AAAA;AAAA,KACF,EACA;AAAA,GAAA,EAEJ,CAAA;AAEJ;AAeO,SAAS,UAAA,CAAW;AAAA,EACzB,OAAA;AAAA,EAAS,MAAA;AAAA,EAAQ,QAAA,GAAW,KAAA;AAAA,EAAO,OAAA;AAAA,EAAS,QAAA;AAAA,EAAU,SAAA;AAAA,EAAW,IAAA;AAAA,EACjE,YAAA,EAAc;AAChB,CAAA,EAAoB;AAClB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAUJ,0BAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,QAAA,GAAiBA,wBAAyB,IAAI,CAAA;AACpD,EAAA,MAAM,SAAeA,gBAAA,CAAA,KAAA,EAAM;AAC3B,EAAA,MAAM,SAASD,0BAAA,EAAU;AACzB,EAAA,MAAM,MAAA,GAAS,CAAC,IAAA,KAA0B;AACxC,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,IAAI,GAAA,GAAM,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA;AACzB,IAAA,IAAI,OAAA,QAAe,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,OAAO,CAAA;AACtD,IAAA,IAAI,CAAC,QAAA,EAAU,GAAA,GAAM,GAAA,CAAI,KAAA,CAAM,GAAG,CAAC,CAAA;AACnC,IAAA,OAAA,CAAQ,GAAG,CAAA;AAAA,EACb,CAAA;AACA,EAAA,uBACEI,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAWC,mBAAA,CAAG,aAAA,EAAe,QAAQ,SAAA,EAAW,QAAA,IAAY,eAAe,SAAS,CAAA;AAAA,MACpF,UAAA,EAAY,CAAC,CAAA,KAAM;AAAE,QAAA,CAAA,CAAE,cAAA,EAAe;AAAG,QAAA,IAAI,CAAC,QAAA,EAAU,OAAA,CAAQ,IAAI,CAAA;AAAA,MAAG,CAAA;AAAA,MACvE,WAAA,EAAa,MAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,MAChC,MAAA,EAAQ,CAAC,CAAA,KAAM;AAAE,QAAA,CAAA,CAAE,cAAA,EAAe;AAAG,QAAA,OAAA,CAAQ,KAAK,CAAA;AAAG,QAAA,IAAI,CAAC,QAAA,EAAU,MAAA,CAAO,CAAA,CAAE,aAAa,KAAK,CAAA;AAAA,MAAG,CAAA;AAAA,MAClG,SAAS,MAAM,CAAC,QAAA,IAAY,QAAA,CAAS,SAAS,KAAA,EAAM;AAAA,MACpD,IAAA,EAAK,QAAA;AAAA,MACL,QAAA,EAAU,WAAW,EAAA,GAAK,CAAA;AAAA,MAC1B,YAAA,EAAY,SAAA;AAAA,MACZ,kBAAA,EAAkB,OAAO,MAAA,GAAS,MAAA;AAAA,MAClC,SAAA,EAAW,CAAC,CAAA,KAAM;AAAE,QAAA,IAAA,CAAK,CAAA,CAAE,GAAA,KAAQ,OAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,QAAQ,CAAC,QAAA,EAAU,QAAA,CAAS,OAAA,EAAS,KAAA,EAAM;AAAA,MAAG,CAAA;AAAA,MAEtG,QAAA,EAAA;AAAA,wBAAAC,cAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,QAAA;AAAA,YACL,IAAA,EAAK,MAAA;AAAA,YACL,MAAA;AAAA,YACA,QAAA;AAAA,YACA,QAAA;AAAA,YACA,MAAA,EAAM,IAAA;AAAA,YACN,UAAU,CAAC,CAAA,KAAM,MAAA,CAAO,CAAA,CAAE,OAAO,KAAK;AAAA;AAAA,SACxC;AAAA,uCACC,KAAA,EAAA,EAAI,SAAA,EAAU,mBAAA,EAAoB,aAAA,EAAY,QAAO,QAAA,EAAA,QAAA,EAAC,CAAA;AAAA,uCACtD,KAAA,EAAA,EAAI,SAAA,EAAU,oBAAA,EAAsB,QAAA,EAAA,MAAA,CAAO,kBAAkB,CAAA,EAAE,CAAA;AAAA,QAC/D,wBAAQA,cAAA,CAAC,KAAA,EAAA,EAAI,IAAI,MAAA,EAAQ,SAAA,EAAU,qBAAqB,QAAA,EAAA,IAAA,EAAK;AAAA;AAAA;AAAA,GAChE;AAEJ;AA8BA,SAAS,eAAA,CAAgB;AAAA,EACvB,SAAA;AAAA,EAAW,YAAA;AAAA,EAAc,WAAA;AAAA,EAAa,SAAA;AAAA,EAAW,QAAA;AAAA,EACjD,SAAA;AAAA,EAAW,SAAA;AAAA,EAAW,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,KAAA;AAAA,EACtC,QAAA;AAAA,EAAU,OAAA;AAAA,EAAS,EAAA;AAAA,EAAI;AACzB,CAAA,EAAyB;AACvB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAUL,0BAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,OAAA,GAAgBA,wBAAuB,IAAI,CAAA;AACjD,EAAA,MAAM,UAAA,GAAmBA,wBAAuB,IAAI,CAAA;AAGpD,EAAA,MAAM,GAAA,GAAMC,mCAAA,CAAmB,OAAA,EAAS,UAAA,EAAY;AAAA,IAClD,IAAA;AAAA,IACA,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,MAAA,EAAQ;AAAA,GACT,CAAA;AACD,EAAAC,2BAAA,CAAW,EAAE,IAAA,EAAM,SAAA,EAAW,MAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,IAAA,EAAM,CAAC,OAAA,EAAS,UAAU,CAAA,EAAG,CAAA;AAEjF,EAAA,uBACEC,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,OAAA;AAAA,MACL,SAAA,EAAWC,oBAAG,SAAA,EAAW,YAAA,EAAc,WAAW,YAAA,EAAc,QAAA,IAAY,eAAe,SAAS,CAAA;AAAA,MAEpG,QAAA,EAAA;AAAA,wBAAAC,cAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,EAAA;AAAA,YACA,IAAA,EAAK,MAAA;AAAA,YACL,QAAA,EAAQ,IAAA;AAAA,YACR,SAAA,EAAU,mBAAA;AAAA,YACV,WAAA;AAAA,YACA,QAAA;AAAA,YACA,KAAA,EAAO,YAAA;AAAA,YACP,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,YAC3B,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,YAC3B,gBAAc,OAAA,IAAW;AAAA;AAAA,SAC3B;AAAA,wBACAA,cAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,SAAA,EAAU,oBAAA;AAAA,YACV,SAAS,MAAM,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,YAChC,QAAA;AAAA,YACA,YAAA,EAAY,SAAA;AAAA,YAEZ,QAAA,kBAAAA,cAAA,CAACS,6BAAA,EAAA,EAAa,IAAA,EAAM,EAAA,EAAI;AAAA;AAAA,SAC1B;AAAA,QACC,IAAA,mCACEP,uBAAA,EAAA,EACC,QAAA,kBAAAJ,eAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,UAAA;AAAA,YACL,SAAA,EAAWC,mBAAA,CAAG,qBAAA,EAAuB,aAAa,CAAA;AAAA,YAClD,IAAA,EAAK,QAAA;AAAA,YACL,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,OAAA;AAAA,cACV,KAAK,GAAA,CAAI,GAAA;AAAA,cACT,MAAM,GAAA,CAAI,IAAA;AAAA,cACV,UAAA,EAAY,GAAA,CAAI,KAAA,GAAQ,SAAA,GAAY;AAAA,aACtC;AAAA,YAEA,QAAA,EAAA;AAAA,8BAAAD,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,iBAAA,EACb,QAAA,EAAA;AAAA,gCAAAE,cAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,OAAA,EAAS,MAAA,EAAQ,YAAA,EAAY,SAAA,EAAW,QAAA,kBAAAA,cAAA,CAACW,4BAAA,EAAA,EAAY,IAAA,EAAM,EAAA,EAAI,CAAA,EAAE,CAAA;AAAA,gCACvFX,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mBAAA,EAAqB,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,gCAC9CA,cAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,OAAA,EAAS,MAAA,EAAQ,YAAA,EAAY,SAAA,EAAW,QAAA,kBAAAA,cAAA,CAACY,6BAAA,EAAA,EAAa,IAAA,EAAM,EAAA,EAAI,CAAA,EAAE;AAAA,eAAA,EAC1F,CAAA;AAAA,6CACC,KAAA,EAAA,EAAI,SAAA,EAAU,oBACZ,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,qBACVZ,cAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBAEC,IAAA,EAAK,QAAA;AAAA,kBACL,SAAA,EAAWD,oBAAG,kBAAA,EAAoB,CAAA,CAAE,YAAY,aAAA,EAAe,CAAA,CAAE,WAAW,QAAQ,CAAA;AAAA,kBACpF,UAAU,CAAA,CAAE,QAAA;AAAA,kBACZ,SAAS,MAAM;AAAE,oBAAA,CAAA,CAAE,QAAA,EAAS;AAAG,oBAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,kBAAG,CAAA;AAAA,kBAE9C,QAAA,EAAA,CAAA,CAAE;AAAA,iBAAA;AAAA,gBANE,CAAA,CAAE;AAAA,eAQV,CAAA,EACH;AAAA;AAAA;AAAA,SACF,EACF;AAAA;AAAA;AAAA,GAEJ;AAEJ;AAeO,SAAS,UAAA,CAAW;AAAA,EACzB,KAAA;AAAA,EAAO,QAAA;AAAA,EAAU,OAAA;AAAA,EAAS,OAAA;AAAA,EAAS,WAAA;AAAA,EACnC,QAAA;AAAA,EAAU,OAAA;AAAA,EAAS,EAAA;AAAA,EAAI;AACzB,CAAA,EAAoB;AAClB,EAAA,MAAM,IAAIL,0BAAA,EAAU;AACpB,EAAA,MAAM,IAAA,GAAO,KAAA,IAAA,iBAAS,IAAI,IAAA,IAAO,WAAA,EAAY;AAC7C,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAUC,gBAAA,CAAA,QAAA,CAAS,KAAK,KAAA,CAAM,IAAA,GAAO,EAAE,CAAA,GAAI,EAAE,CAAA;AAErE,EAAMA,2BAAU,MAAM;AACpB,IAAA,IAAI,KAAA,IAAS,MAAM,SAAA,CAAU,IAAA,CAAK,MAAM,KAAA,GAAQ,EAAE,IAAI,EAAE,CAAA;AAAA,EAC1D,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,MAAM,KAAA,GAAoB,MAAM,IAAA,CAAK,EAAE,QAAQ,EAAA,EAAG,EAAG,CAAC,CAAA,EAAG,CAAA,KAAM;AAC7D,IAAA,MAAM,IAAA,GAAO,SAAS,CAAA,GAAI,CAAA;AAC1B,IAAA,OAAO;AAAA,MACL,GAAA,EAAK,OAAO,IAAI,CAAA;AAAA,MAChB,KAAA,EAAO,IAAA;AAAA,MACP,UAAU,KAAA,KAAU,IAAA;AAAA,MACpB,OAAA,EAAS,IAAA,GAAO,MAAA,IAAU,IAAA,GAAO,MAAA,GAAS,CAAA;AAAA,MAC1C,UAAW,OAAA,IAAW,IAAA,IAAQ,OAAO,OAAA,IAAa,OAAA,IAAW,QAAQ,IAAA,GAAO,OAAA;AAAA,MAC5E,QAAA,EAAU,MAAM,QAAA,CAAS,IAAI;AAAA,KAC/B;AAAA,EACF,CAAC,CAAA;AAED,EAAA,uBACEK,cAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,YAAA;AAAA,MACV,YAAA,EAAc,KAAA,IAAS,IAAA,GAAO,MAAA,CAAO,KAAK,CAAA,GAAI,EAAA;AAAA,MAC9C,WAAA,EAAa,WAAA,IAAe,CAAA,CAAE,mBAAmB,CAAA;AAAA,MACjD,SAAA,EAAW,EAAE,qBAAqB,CAAA;AAAA,MAClC,QAAA,EAAU,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,SAAS,CAAC,CAAA,CAAA;AAAA,MACjC,SAAA,EAAW,EAAE,mBAAmB,CAAA;AAAA,MAChC,SAAA,EAAW,EAAE,mBAAmB,CAAA;AAAA,MAChC,QAAQ,MAAM,SAAA,CAAU,CAAC,CAAA,KAAM,IAAI,EAAE,CAAA;AAAA,MACrC,QAAQ,MAAM,SAAA,CAAU,CAAC,CAAA,KAAM,IAAI,EAAE,CAAA;AAAA,MACrC,KAAA;AAAA,MACA,QAAA;AAAA,MACA,OAAA;AAAA,MACA,EAAA;AAAA,MACA;AAAA;AAAA,GACF;AAEJ;AAeO,SAAS,WAAA,CAAY;AAAA,EAC1B,KAAA;AAAA,EAAO,QAAA;AAAA,EAAU,OAAA;AAAA,EAAS,OAAA;AAAA,EAAS,WAAA;AAAA,EACnC,QAAA;AAAA,EAAU,OAAA;AAAA,EAAS,EAAA;AAAA,EAAI;AACzB,CAAA,EAAqB;AACnB,EAAA,MAAM,IAAIN,0BAAA,EAAU;AACpB,EAAA,MAAM,MAAA,GAAS,EAAE,iBAAiB,CAAA;AAClC,EAAA,MAAM,IAAA,GAAO,KAAA,oBAAS,IAAI,IAAA,EAAK;AAC/B,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,IAAUC,gBAAA,CAAA,QAAA,CAAS,IAAA,CAAK,aAAa,CAAA;AAEzD,EAAMA,2BAAU,MAAM;AACpB,IAAA,IAAI,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,WAAA,EAAa,CAAA;AAAA,EACxC,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,MAAM,UAAA,GAAa,CAAC,CAAA,EAAW,CAAA,KAAc,IAAI,IAAA,CAAK,CAAA,EAAG,GAAG,CAAC,CAAA;AAC7D,EAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KACjB,OAAA,IAAW,IAAA,IAAQ,UAAA,CAAW,IAAA,EAAM,CAAC,CAAA,GAAI,UAAA,CAAW,OAAA,CAAQ,WAAA,EAAY,EAAG,OAAA,CAAQ,QAAA,EAAU,CAAA,IAC7F,OAAA,IAAW,IAAA,IAAQ,UAAA,CAAW,IAAA,EAAM,CAAC,CAAA,GAAI,UAAA,CAAW,OAAA,CAAQ,WAAA,EAAY,EAAG,OAAA,CAAQ,UAAU,CAAA;AAEhG,EAAA,MAAM,KAAA,GAAoB,MAAA,CAAO,GAAA,CAAI,CAAC,MAAM,CAAA,MAAO;AAAA,IACjD,GAAA,EAAK,OAAO,CAAC,CAAA;AAAA,IACb,KAAA,EAAO,IAAA;AAAA,IACP,QAAA,EAAU,CAAC,CAAC,KAAA,IAAS,KAAA,CAAM,aAAY,KAAM,IAAA,IAAQ,KAAA,CAAM,QAAA,EAAS,KAAM,CAAA;AAAA,IAC1E,QAAA,EAAU,WAAW,CAAC,CAAA;AAAA,IACtB,QAAA,EAAU,MAAM,QAAA,CAAS,IAAI,KAAK,IAAA,EAAM,CAAA,EAAG,CAAC,CAAC;AAAA,GAC/C,CAAE,CAAA;AAEF,EAAA,uBACEK,cAAA;AAAA,IAAC,eAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,aAAA;AAAA,MACV,YAAA,EAAc,KAAA,GAAQ,CAAA,EAAG,MAAA,CAAO,KAAA,CAAM,QAAA,EAAU,CAAC,CAAA,CAAA,EAAI,KAAA,CAAM,WAAA,EAAa,CAAA,CAAA,GAAK,EAAA;AAAA,MAC7E,WAAA,EAAa,WAAA,IAAe,CAAA,CAAE,oBAAoB,CAAA;AAAA,MAClD,SAAA,EAAW,EAAE,qBAAqB,CAAA;AAAA,MAClC,QAAA,EAAU,OAAO,IAAI,CAAA;AAAA,MACrB,SAAA,EAAW,EAAE,iBAAiB,CAAA;AAAA,MAC9B,SAAA,EAAW,EAAE,iBAAiB,CAAA;AAAA,MAC9B,QAAQ,MAAM,OAAA,CAAQ,CAAC,CAAA,KAAM,IAAI,CAAC,CAAA;AAAA,MAClC,QAAQ,MAAM,OAAA,CAAQ,CAAC,CAAA,KAAM,IAAI,CAAC,CAAA;AAAA,MAClC,KAAA;AAAA,MACA,QAAA;AAAA,MACA,OAAA;AAAA,MACA,EAAA;AAAA,MACA;AAAA;AAAA,GACF;AAEJ","file":"chunk-62F5E5NQ.js","sourcesContent":["'use client';\nimport * as React from 'react';\nimport { cx } from '../utils/cx';\nimport { CalendarIcon, ChevronLeft, ChevronRight, X } from './Icons';\nimport { resolveDateFormat, formatDate, parseDate, dateFormatPlaceholder, startOfMonth, addMonths, isSameDay, buildMonthGrid, type DateFormat } from '../utils/dateFormat';\nimport { useLocale } from '../locale/LocaleProvider';\nimport { Portal } from './Portal';\nimport { usePopoverPosition } from '../hooks/usePopoverPosition';\nimport { useDismiss } from '../hooks/useDismiss';\n\n// ---------- Combobox -----------------------------------------------------\nexport interface ComboboxOption<T = string> {\n value: T;\n label: string;\n description?: string;\n disabled?: boolean;\n}\n\nexport interface ComboboxProps<T = string> {\n value: T | null;\n onChange: (value: T | null) => void;\n options: ComboboxOption<T>[];\n placeholder?: string;\n emptyMessage?: string;\n filter?: (option: ComboboxOption<T>, query: string) => boolean;\n className?: string;\n invalid?: boolean;\n disabled?: boolean;\n id?: string;\n /**\n * Whether the trigger is a typeable text input that filters options.\n * Default `true` (the searchable Combobox). Set `false` for a non-typing\n * picker: button trigger + the same kit-styled listbox, no filter, full\n * list always. Closes the gap between native `<Select>` (jarring native\n * dropdown) and the searchable Combobox — same visual register, no input.\n */\n searchable?: boolean;\n}\n\nconst defaultFilter = <T,>(o: ComboboxOption<T>, q: string) =>\n o.label.toLowerCase().includes(q.toLowerCase());\n\nexport function Combobox<T = string>({\n value, onChange, options, placeholder,\n emptyMessage, filter = defaultFilter,\n className, invalid, disabled, id,\n searchable = true,\n}: ComboboxProps<T>) {\n const locale = useLocale();\n const ph = placeholder ?? locale['common.search'];\n const empty = emptyMessage ?? locale['common.noResults'];\n const [open, setOpen] = React.useState(false);\n const [query, setQuery] = React.useState('');\n const [active, setActive] = React.useState(0);\n const wrapRef = React.useRef<HTMLDivElement>(null);\n const inputRef = React.useRef<HTMLInputElement>(null);\n const listRef = React.useRef<HTMLUListElement>(null);\n // Stable per-instance listbox id so multiple Comboboxes don't collide on aria-controls.\n const reactId = React.useId();\n const listboxId = `${id ?? reactId}-listbox`;\n\n const selected = React.useMemo(\n () => options.find((o) => o.value === value) ?? null,\n [options, value]\n );\n const filtered = React.useMemo(\n () => (query ? options.filter((o) => filter(o, query)) : options),\n [options, query, filter]\n );\n\n const pos = usePopoverPosition(wrapRef, listRef, {\n open,\n side: 'bottom',\n align: 'start',\n offset: 4,\n matchAnchorWidth: true,\n });\n\n // Escape is handled by the input's onKeyDown; here we only need\n // outside-click (closeOnEscape: false avoids a double close).\n useDismiss({\n open,\n onDismiss: () => setOpen(false),\n refs: [wrapRef, listRef],\n closeOnEscape: false,\n });\n\n React.useEffect(() => { setActive(0); }, [query, open]);\n\n const onKey = (e: React.KeyboardEvent<HTMLElement>) => {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (!open) setOpen(true);\n else setActive((a) => Math.min(filtered.length - 1, a + 1));\n } else if (e.key === 'ArrowUp') {\n // Only navigate when the listbox is open (no-op otherwise).\n if (!open) return;\n e.preventDefault();\n setActive((a) => Math.max(0, a - 1));\n } else if (e.key === 'Enter') {\n // Only commit when the listbox is open — without this gate, Enter on\n // a button trigger that just opened would race with the open and\n // immediately select the first option.\n if (!open) return;\n e.preventDefault();\n const opt = filtered[active];\n if (opt && !opt.disabled) {\n onChange(opt.value);\n setQuery('');\n setOpen(false);\n }\n } else if (e.key === 'Escape') {\n setOpen(false);\n }\n };\n\n return (\n <div ref={wrapRef} className={cx('combobox', invalid && 'is-invalid', disabled && 'is-disabled', className)}>\n {searchable ? (\n <input\n ref={inputRef}\n id={id}\n type=\"text\"\n role=\"combobox\"\n aria-expanded={open}\n aria-controls={listboxId}\n className=\"combobox__input\"\n placeholder={ph}\n disabled={disabled}\n value={open ? query : selected?.label ?? ''}\n onFocus={() => setOpen(true)}\n onChange={(e) => { setQuery(e.target.value); setOpen(true); }}\n onKeyDown={onKey}\n />\n ) : (\n // Non-typing trigger: button shaped like `.combobox__input` (same\n // border / radius / chevron) so the two variants line up visually.\n // No clear button — the user re-picks from the listbox instead.\n <button\n id={id}\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={listboxId}\n className=\"combobox__trigger\"\n disabled={disabled}\n onClick={() => setOpen((o) => !o)}\n onKeyDown={onKey}\n >\n {selected ? (\n <span className=\"combobox__trigger-label\">{selected.label}</span>\n ) : (\n <span className=\"combobox__trigger-placeholder\">{ph}</span>\n )}\n </button>\n )}\n {searchable && selected && !open && (\n <button\n type=\"button\"\n className=\"combobox__clear\"\n onClick={() => { onChange(null); setQuery(''); inputRef.current?.focus(); }}\n aria-label={locale['picker.clearSelection']}\n ><X size={16} /></button>\n )}\n {open && (\n <Portal>\n <ul\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n className={cx('combobox__list', 'is-floating')}\n style={{\n position: 'fixed',\n top: pos.top,\n left: pos.left,\n width: pos.width,\n visibility: pos.ready ? 'visible' : 'hidden',\n }}\n >\n {filtered.length === 0 ? (\n <li className=\"combobox__empty\">{empty}</li>\n ) : (\n filtered.map((o, i) => (\n <li\n key={String(o.value)}\n role=\"option\"\n aria-selected={o.value === value}\n aria-disabled={o.disabled}\n className={cx('combobox__option', i === active && 'is-active', o.value === value && 'is-selected', o.disabled && 'is-disabled')}\n onMouseEnter={() => setActive(i)}\n onMouseDown={(e) => {\n e.preventDefault();\n if (o.disabled) return;\n onChange(o.value);\n setQuery('');\n setOpen(false);\n }}\n >\n <span className=\"combobox__option-label\">{o.label}</span>\n {o.description && <span className=\"combobox__option-desc\">{o.description}</span>}\n </li>\n ))\n )}\n </ul>\n </Portal>\n )}\n </div>\n );\n}\n\n// ---------- DatePicker (text + calendar popover) -------------------------\nexport interface DatePickerProps {\n value: Date | null;\n onChange: (date: Date | null) => void;\n minDate?: Date;\n maxDate?: Date;\n placeholder?: string;\n disabled?: boolean;\n invalid?: boolean;\n className?: string;\n id?: string;\n /**\n * Display & parse format. Default `'auto'` derives from `configureBrand().locale`\n * (e.g. `es-CL` → `dd-mm-aaaa`, `en-US` → `mm-dd-aaaa`, `ja-JP` → `aaaa-mm-dd`).\n */\n format?: DateFormat;\n}\n\nexport function DatePicker({\n value, onChange, minDate, maxDate, placeholder,\n disabled, invalid, className, id, format = 'auto',\n}: DatePickerProps) {\n const locale = useLocale();\n const fmt = resolveDateFormat(format);\n const ph = placeholder ?? dateFormatPlaceholder(fmt);\n const weekdays = locale['picker.weekdaysShort'];\n const months = locale['calendar.months'];\n const [open, setOpen] = React.useState(false);\n const [view, setView] = React.useState(() => startOfMonth(value ?? new Date()));\n const wrapRef = React.useRef<HTMLDivElement>(null);\n const popoverRef = React.useRef<HTMLDivElement>(null);\n\n // Portaled to body (escapes overflow ancestors) with flip/clamp and\n // scroll/resize reposition — same primitive as Combobox above. No\n // returnFocusRef: the input opens on focus, so refocusing it on close\n // would immediately reopen the calendar (Combobox omits it for the same\n // reason). Escape still closes via useDismiss's default handler.\n const pos = usePopoverPosition(wrapRef, popoverRef, {\n open,\n side: 'bottom',\n align: 'start',\n offset: 4,\n });\n\n useDismiss({\n open,\n onDismiss: () => setOpen(false),\n refs: [wrapRef, popoverRef],\n });\n\n React.useEffect(() => {\n if (value) setView(startOfMonth(value));\n }, [value]);\n\n const { cells } = buildMonthGrid(view, 0);\n\n const isDisabled = (d: Date) =>\n (minDate && d < new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate())) ||\n (maxDate && d > new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate()));\n\n return (\n <div ref={wrapRef} className={cx('datepicker', invalid && 'is-invalid', disabled && 'is-disabled', className)}>\n <input\n id={id}\n type=\"text\"\n className=\"datepicker__input\"\n placeholder={ph}\n disabled={disabled}\n value={value ? formatDate(value, fmt) : ''}\n onChange={(e) => {\n const d = parseDate(e.target.value, fmt);\n onChange(d);\n }}\n onFocus={() => setOpen(true)}\n aria-invalid={invalid || undefined}\n />\n <button\n type=\"button\"\n className=\"datepicker__toggle\"\n onClick={() => setOpen((o) => !o)}\n disabled={disabled}\n aria-label={locale['picker.openCalendar']}\n ><CalendarIcon size={16} /></button>\n {open && (\n <Portal>\n <div\n ref={popoverRef}\n className={cx('datepicker__popover', 'is-floating')}\n role=\"dialog\"\n style={{\n position: 'fixed',\n top: pos.top,\n left: pos.left,\n visibility: pos.ready ? 'visible' : 'hidden',\n }}\n >\n <div className=\"datepicker__nav\">\n <button type=\"button\" onClick={() => setView((v) => addMonths(v, -1))} aria-label={locale['calendar.prevMonth']}><ChevronLeft size={16} /></button>\n <span className=\"datepicker__title\">{months[view.getMonth()]} {view.getFullYear()}</span>\n <button type=\"button\" onClick={() => setView((v) => addMonths(v, 1))} aria-label={locale['calendar.nextMonth']}><ChevronRight size={16} /></button>\n </div>\n <div className=\"datepicker__grid\">\n {weekdays.map((w, i) => <span key={i} className=\"datepicker__dow\">{w}</span>)}\n {cells.map((d, i) => {\n if (!d) return <span key={`b${i}`} />;\n const sel = value && isSameDay(d, value);\n const today = isSameDay(d, new Date());\n const off = isDisabled(d);\n return (\n <button\n key={i}\n type=\"button\"\n className={cx('datepicker__day', sel && 'is-selected', today && 'is-today', off && 'is-disabled')}\n disabled={!!off}\n onClick={() => { onChange(d); setOpen(false); }}\n >\n {d.getDate()}\n </button>\n );\n })}\n </div>\n </div>\n </Portal>\n )}\n </div>\n );\n}\n\n// ---------- FileUpload (drop zone) ---------------------------------------\nexport interface FileUploadProps {\n onFiles: (files: File[]) => void;\n accept?: string;\n multiple?: boolean;\n maxSize?: number; // bytes\n disabled?: boolean;\n className?: string;\n hint?: React.ReactNode;\n /** Accessible name for the drop zone (e.g. \"Subir foto de perfil\"). */\n 'aria-label'?: string;\n}\n\nexport function FileUpload({\n onFiles, accept, multiple = false, maxSize, disabled, className, hint,\n 'aria-label': ariaLabel,\n}: FileUploadProps) {\n const [drag, setDrag] = React.useState(false);\n const inputRef = React.useRef<HTMLInputElement>(null);\n const hintId = React.useId();\n const locale = useLocale();\n const handle = (list: FileList | null) => {\n if (!list) return;\n let arr = Array.from(list);\n if (maxSize) arr = arr.filter((f) => f.size <= maxSize);\n if (!multiple) arr = arr.slice(0, 1);\n onFiles(arr);\n };\n return (\n <div\n className={cx('file-upload', drag && 'is-drag', disabled && 'is-disabled', className)}\n onDragOver={(e) => { e.preventDefault(); if (!disabled) setDrag(true); }}\n onDragLeave={() => setDrag(false)}\n onDrop={(e) => { e.preventDefault(); setDrag(false); if (!disabled) handle(e.dataTransfer.files); }}\n onClick={() => !disabled && inputRef.current?.click()}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-label={ariaLabel}\n aria-describedby={hint ? hintId : undefined}\n onKeyDown={(e) => { if ((e.key === 'Enter' || e.key === ' ') && !disabled) inputRef.current?.click(); }}\n >\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n hidden\n onChange={(e) => handle(e.target.files)}\n />\n <div className=\"file-upload__icon\" aria-hidden=\"true\">⤴</div>\n <div className=\"file-upload__title\">{locale['fileUpload.title']}</div>\n {hint && <div id={hintId} className=\"file-upload__hint\">{hint}</div>}\n </div>\n );\n}\n\n// ---------- GridPickerField (shared shell: YearPicker / MonthPicker) ------\ninterface GridCell {\n key: string;\n label: React.ReactNode;\n selected?: boolean;\n /** Dimmed (outside the current decade) — YearPicker only. */\n outside?: boolean;\n disabled?: boolean;\n onSelect: () => void;\n}\n\ninterface GridPickerFieldProps {\n rootClass: string;\n displayValue: string;\n placeholder: string;\n ariaLabel: string;\n navTitle: React.ReactNode;\n prevLabel: string;\n nextLabel: string;\n onPrev: () => void;\n onNext: () => void;\n cells: GridCell[];\n disabled?: boolean;\n invalid?: boolean;\n id?: string;\n className?: string;\n}\n\nfunction GridPickerField({\n rootClass, displayValue, placeholder, ariaLabel, navTitle,\n prevLabel, nextLabel, onPrev, onNext, cells,\n disabled, invalid, id, className,\n}: GridPickerFieldProps) {\n const [open, setOpen] = React.useState(false);\n const wrapRef = React.useRef<HTMLDivElement>(null);\n const popoverRef = React.useRef<HTMLDivElement>(null);\n\n // Same floating primitive as DatePicker (Portal + flip/clamp + dismiss).\n const pos = usePopoverPosition(wrapRef, popoverRef, {\n open,\n side: 'bottom',\n align: 'start',\n offset: 4,\n });\n useDismiss({ open, onDismiss: () => setOpen(false), refs: [wrapRef, popoverRef] });\n\n return (\n <div\n ref={wrapRef}\n className={cx(rootClass, 'gridpicker', invalid && 'is-invalid', disabled && 'is-disabled', className)}\n >\n <input\n id={id}\n type=\"text\"\n readOnly\n className=\"gridpicker__input\"\n placeholder={placeholder}\n disabled={disabled}\n value={displayValue}\n onFocus={() => setOpen(true)}\n onClick={() => setOpen(true)}\n aria-invalid={invalid || undefined}\n />\n <button\n type=\"button\"\n className=\"gridpicker__toggle\"\n onClick={() => setOpen((o) => !o)}\n disabled={disabled}\n aria-label={ariaLabel}\n >\n <CalendarIcon size={16} />\n </button>\n {open && (\n <Portal>\n <div\n ref={popoverRef}\n className={cx('gridpicker__popover', 'is-floating')}\n role=\"dialog\"\n style={{\n position: 'fixed',\n top: pos.top,\n left: pos.left,\n visibility: pos.ready ? 'visible' : 'hidden',\n }}\n >\n <div className=\"gridpicker__nav\">\n <button type=\"button\" onClick={onPrev} aria-label={prevLabel}><ChevronLeft size={16} /></button>\n <span className=\"gridpicker__title\">{navTitle}</span>\n <button type=\"button\" onClick={onNext} aria-label={nextLabel}><ChevronRight size={16} /></button>\n </div>\n <div className=\"gridpicker__grid\">\n {cells.map((c) => (\n <button\n key={c.key}\n type=\"button\"\n className={cx('gridpicker__cell', c.selected && 'is-selected', c.outside && 'is-out')}\n disabled={c.disabled}\n onClick={() => { c.onSelect(); setOpen(false); }}\n >\n {c.label}\n </button>\n ))}\n </div>\n </div>\n </Portal>\n )}\n </div>\n );\n}\n\n// ---------- YearPicker ---------------------------------------------------\nexport interface YearPickerProps {\n value: number | null;\n onChange: (year: number | null) => void;\n minYear?: number;\n maxYear?: number;\n placeholder?: string;\n disabled?: boolean;\n invalid?: boolean;\n id?: string;\n className?: string;\n}\n\nexport function YearPicker({\n value, onChange, minYear, maxYear, placeholder,\n disabled, invalid, id, className,\n}: YearPickerProps) {\n const t = useLocale();\n const base = value ?? new Date().getFullYear();\n const [decade, setDecade] = React.useState(Math.floor(base / 10) * 10);\n\n React.useEffect(() => {\n if (value != null) setDecade(Math.floor(value / 10) * 10);\n }, [value]);\n\n const cells: GridCell[] = Array.from({ length: 12 }, (_, i) => {\n const year = decade - 1 + i;\n return {\n key: String(year),\n label: year,\n selected: value === year,\n outside: year < decade || year > decade + 9,\n disabled: (minYear != null && year < minYear) || (maxYear != null && year > maxYear),\n onSelect: () => onChange(year),\n };\n });\n\n return (\n <GridPickerField\n rootClass=\"yearpicker\"\n displayValue={value != null ? String(value) : ''}\n placeholder={placeholder ?? t['picker.selectYear']}\n ariaLabel={t['picker.openCalendar']}\n navTitle={`${decade}-${decade + 9}`}\n prevLabel={t['picker.prevDecade']}\n nextLabel={t['picker.nextDecade']}\n onPrev={() => setDecade((d) => d - 10)}\n onNext={() => setDecade((d) => d + 10)}\n cells={cells}\n disabled={disabled}\n invalid={invalid}\n id={id}\n className={className}\n />\n );\n}\n\n// ---------- MonthPicker --------------------------------------------------\nexport interface MonthPickerProps {\n value: Date | null;\n onChange: (date: Date | null) => void;\n minDate?: Date;\n maxDate?: Date;\n placeholder?: string;\n disabled?: boolean;\n invalid?: boolean;\n id?: string;\n className?: string;\n}\n\nexport function MonthPicker({\n value, onChange, minDate, maxDate, placeholder,\n disabled, invalid, id, className,\n}: MonthPickerProps) {\n const t = useLocale();\n const months = t['calendar.months'];\n const base = value ?? new Date();\n const [year, setYear] = React.useState(base.getFullYear());\n\n React.useEffect(() => {\n if (value) setYear(value.getFullYear());\n }, [value]);\n\n const monthStart = (y: number, m: number) => new Date(y, m, 1);\n const outOfRange = (m: number) =>\n (minDate != null && monthStart(year, m) < monthStart(minDate.getFullYear(), minDate.getMonth())) ||\n (maxDate != null && monthStart(year, m) > monthStart(maxDate.getFullYear(), maxDate.getMonth()));\n\n const cells: GridCell[] = months.map((name, m) => ({\n key: String(m),\n label: name,\n selected: !!value && value.getFullYear() === year && value.getMonth() === m,\n disabled: outOfRange(m),\n onSelect: () => onChange(new Date(year, m, 1)),\n }));\n\n return (\n <GridPickerField\n rootClass=\"monthpicker\"\n displayValue={value ? `${months[value.getMonth()]} ${value.getFullYear()}` : ''}\n placeholder={placeholder ?? t['picker.selectMonth']}\n ariaLabel={t['picker.openCalendar']}\n navTitle={String(year)}\n prevLabel={t['picker.prevYear']}\n nextLabel={t['picker.nextYear']}\n onPrev={() => setYear((y) => y - 1)}\n onNext={() => setYear((y) => y + 1)}\n cells={cells}\n disabled={disabled}\n invalid={invalid}\n id={id}\n className={className}\n />\n );\n}\n"]}
@@ -71,7 +71,9 @@ function AppShell({
71
71
  children,
72
72
  className,
73
73
  theme = "default",
74
- linkAs
74
+ linkAs,
75
+ headerLayout = "side",
76
+ header
75
77
  }) {
76
78
  const [internalCollapsed, setInternalCollapsed] = React__namespace.useState(defaultCollapsed);
77
79
  const [mobileOpen, setMobileOpen] = React__namespace.useState(false);
@@ -82,6 +84,25 @@ function AppShell({
82
84
  onCollapsedChange?.(v);
83
85
  };
84
86
  const closeMobile = React__namespace.useCallback(() => setMobileOpen(false), []);
87
+ if (headerLayout === "top") {
88
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkPASF6T4H_js.cx("appshell", `appshell--${theme}`, "appshell--header-top", collapsed && "is-collapsed", className), children: [
89
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "appshell__header", role: "banner", children: [
90
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "appshell__header-left", children: header?.left }),
91
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "appshell__header-center", children: header?.center }),
92
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "appshell__header-right", children: header?.right })
93
+ ] }),
94
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "appshell__body", children: [
95
+ /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "appshell__sidebar", "aria-label": t["appshell.mainNav"], children: [
96
+ /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "appshell__nav", children: sections.map((s, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "appshell__navsection", children: [
97
+ s.label && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "appshell__navlabel-section", children: s.label }),
98
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { children: s.items.map((it) => /* @__PURE__ */ jsxRuntime.jsx(NavItemNode, { item: it, depth: 0, linkAs, onCloseMobile: closeMobile }, it.id)) })
99
+ ] }, s.id ?? i)) }),
100
+ footer != null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "appshell__sidebar-foot", children: footer })
101
+ ] }),
102
+ /* @__PURE__ */ jsxRuntime.jsx("main", { className: "appshell__content", role: "main", children })
103
+ ] })
104
+ ] });
105
+ }
85
106
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkPASF6T4H_js.cx("appshell", `appshell--${theme}`, collapsed && "is-collapsed", mobileOpen && "is-mobile-open", className), children: [
86
107
  /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "appshell__sidebar", "aria-label": t["appshell.mainNav"], children: [
87
108
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "appshell__brand", children: collapsed ? brandCollapsed ?? brand : brand }),
@@ -146,5 +167,5 @@ function PageHeader({ title, description, breadcrumbs, actions, meta, className
146
167
 
147
168
  exports.AppShell = AppShell;
148
169
  exports.PageHeader = PageHeader;
149
- //# sourceMappingURL=chunk-QLYPHMPH.js.map
150
- //# sourceMappingURL=chunk-QLYPHMPH.js.map
170
+ //# sourceMappingURL=chunk-7LCZ6ABE.js.map
171
+ //# sourceMappingURL=chunk-7LCZ6ABE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/AppShell.tsx"],"names":["React","NavItemNode","cx","jsxs","Fragment","jsx","useLocale","ChevronRight","ChevronLeft","MenuIcon"],"mappings":"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","file":"chunk-7LCZ6ABE.js","sourcesContent":["'use client';\nimport * as React from 'react';\nimport { cx } from '../utils/cx';\nimport { ChevronLeft, ChevronRight, MenuIcon } from './Icons';\nimport { useLocale } from '../locale/LocaleProvider';\n\n// ---------- AppShell (Sidebar + Topbar + Content) -----------------------\n// Designed to drop into a Next.js app/layout.tsx as a Client Component shell.\n\nexport interface NavItem {\n id: string;\n label: React.ReactNode;\n icon?: React.ReactNode;\n href?: string;\n active?: boolean;\n badge?: React.ReactNode;\n onSelect?: () => void;\n children?: NavItem[];\n}\n\nexport interface NavSection {\n id?: string;\n label?: React.ReactNode;\n items: NavItem[];\n}\n\nexport type AppShellTheme = 'default' | 'brand';\n\nexport type AppShellHeaderLayout = 'side' | 'top';\n\nexport interface AppShellHeader {\n /** Left slot — typically a menu/hamburger trigger or back action. */\n left?: React.ReactNode;\n /** Center slot — typically the brand (Logo). Lands at the true viewport centre. */\n center?: React.ReactNode;\n /** Right slot — notifications, user avatar, utilities. */\n right?: React.ReactNode;\n}\n\nexport interface AppShellProps {\n brand?: React.ReactNode;\n brandCollapsed?: React.ReactNode;\n sections: NavSection[];\n topbar?: React.ReactNode;\n footer?: React.ReactNode;\n user?: React.ReactNode;\n defaultCollapsed?: boolean;\n collapsed?: boolean;\n onCollapsedChange?: (c: boolean) => void;\n children: React.ReactNode;\n className?: string;\n /**\n * Sidebar color theme:\n * - `default` (light): claro, mejor para apps data-heavy de uso prolongado.\n * - `brand`: sidebar azul de marca con texto blanco. Mayor brand recall.\n */\n theme?: AppShellTheme;\n /** Render-prop for navigation links so the host app can use Next.js Link, etc. */\n linkAs?: (item: NavItem, content: React.ReactNode, className: string) => React.ReactNode;\n /**\n * Where the chrome lives. Default `'side'` is the legacy layout. `'top'`\n * renders a full-width header above the body with three slots\n * (`header.left/center/right`); the centre slot lands at the **true\n * viewport centre** (1fr·auto·1fr column grid). The sidebar has no brand\n * block (brand goes in `header.center`) and `collapsed` hides the\n * sidebar entirely — no 72px rail. The topbar is **invariant** to the\n * collapse (only the sidebar changes width). `theme=\"brand\"` tints both\n * header and sidebar with the same brand colour (single knob). `brand`,\n * `brandCollapsed` and `topbar` are ignored when `'top'`.\n */\n headerLayout?: AppShellHeaderLayout;\n /** Slots for the top-layout header (only used when `headerLayout=\"top\"`). */\n header?: AppShellHeader;\n}\n\n// Recursive nav item, memoized so a single item's parent re-render doesn't\n// churn through every other item in the tree. Stability of `linkAs` and\n// `onCloseMobile` is the parent's responsibility (we stabilize\n// `onCloseMobile` via useCallback below; consumers should memoize `linkAs`\n// if they care about avoiding renders, but for typical Next.js Link usage\n// the inline arrow is rarely a hot path).\ninterface NavItemNodeProps {\n item: NavItem;\n depth: number;\n linkAs?: AppShellProps['linkAs'];\n onCloseMobile: () => void;\n}\n\nconst NavItemNode = React.memo(function NavItemNode({\n item, depth, linkAs, onCloseMobile,\n}: NavItemNodeProps) {\n const klass = cx('appshell__navitem', item.active && 'is-active', `appshell__navitem--depth-${depth}`);\n const inner = (\n <>\n {item.icon && <span className=\"appshell__navicon\" aria-hidden=\"true\">{item.icon}</span>}\n <span className=\"appshell__navlabel\">{item.label}</span>\n {item.badge && <span className=\"appshell__navbadge\">{item.badge}</span>}\n </>\n );\n const node = item.href && linkAs\n ? linkAs(item, inner, klass)\n : (\n <a\n href={item.href ?? '#'}\n className={klass}\n aria-current={item.active ? 'page' : undefined}\n onClick={(e) => {\n if (!item.href) e.preventDefault();\n item.onSelect?.();\n onCloseMobile();\n }}\n >\n {inner}\n </a>\n );\n return (\n <li>\n {node}\n {item.children && item.children.length > 0 && (\n <ul className=\"appshell__navchildren\">\n {item.children.map((c) => (\n <NavItemNode key={c.id} item={c} depth={depth + 1} linkAs={linkAs} onCloseMobile={onCloseMobile} />\n ))}\n </ul>\n )}\n </li>\n );\n});\n\nexport function AppShell({\n brand, brandCollapsed, sections, topbar, footer, user,\n defaultCollapsed = false, collapsed: ctrlCollapsed, onCollapsedChange,\n children, className, theme = 'default', linkAs,\n headerLayout = 'side', header,\n}: AppShellProps) {\n const [internalCollapsed, setInternalCollapsed] = React.useState(defaultCollapsed);\n const [mobileOpen, setMobileOpen] = React.useState(false);\n const t = useLocale();\n const collapsed = ctrlCollapsed ?? internalCollapsed;\n const setCollapsed = (v: boolean) => {\n if (ctrlCollapsed === undefined) setInternalCollapsed(v);\n onCollapsedChange?.(v);\n };\n const closeMobile = React.useCallback(() => setMobileOpen(false), []);\n\n // Top-header variant: full-width header above the body. Topbar is\n // invariant to `collapsed` (only the inner body's columns animate); brand\n // lives in `header.center` at the true viewport centre. Default\n // `headerLayout=\"side\"` falls through to the legacy JSX below\n // (byte-identical for existing consumers).\n if (headerLayout === 'top') {\n return (\n <div className={cx('appshell', `appshell--${theme}`, 'appshell--header-top', collapsed && 'is-collapsed', className)}>\n <header className=\"appshell__header\" role=\"banner\">\n <div className=\"appshell__header-left\">{header?.left}</div>\n <div className=\"appshell__header-center\">{header?.center}</div>\n <div className=\"appshell__header-right\">{header?.right}</div>\n </header>\n <div className=\"appshell__body\">\n <aside className=\"appshell__sidebar\" aria-label={t['appshell.mainNav']}>\n <nav className=\"appshell__nav\">\n {sections.map((s, i) => (\n <div key={s.id ?? i} className=\"appshell__navsection\">\n {s.label && <div className=\"appshell__navlabel-section\">{s.label}</div>}\n <ul>{s.items.map((it) => (\n <NavItemNode key={it.id} item={it} depth={0} linkAs={linkAs} onCloseMobile={closeMobile} />\n ))}</ul>\n </div>\n ))}\n </nav>\n {footer != null && <div className=\"appshell__sidebar-foot\">{footer}</div>}\n </aside>\n <main className=\"appshell__content\" role=\"main\">{children}</main>\n </div>\n </div>\n );\n }\n\n return (\n <div className={cx('appshell', `appshell--${theme}`, collapsed && 'is-collapsed', mobileOpen && 'is-mobile-open', className)}>\n <aside className=\"appshell__sidebar\" aria-label={t['appshell.mainNav']}>\n <div className=\"appshell__brand\">\n {collapsed ? (brandCollapsed ?? brand) : brand}\n </div>\n <nav className=\"appshell__nav\">\n {sections.map((s, i) => (\n <div key={s.id ?? i} className=\"appshell__navsection\">\n {s.label && <div className=\"appshell__navlabel-section\">{s.label}</div>}\n <ul>{s.items.map((it) => (\n <NavItemNode key={it.id} item={it} depth={0} linkAs={linkAs} onCloseMobile={closeMobile} />\n ))}</ul>\n </div>\n ))}\n </nav>\n <div className=\"appshell__sidebar-foot\">\n {footer}\n <button\n type=\"button\"\n className=\"appshell__collapse\"\n onClick={() => setCollapsed(!collapsed)}\n aria-expanded={!collapsed}\n aria-label={collapsed ? t['appshell.expandMenu'] : t['appshell.collapseMenu']}\n title={collapsed ? t['appshell.expand'] : t['appshell.collapse']}\n >\n {collapsed ? <ChevronRight size={14} /> : <ChevronLeft size={14} />}\n </button>\n </div>\n </aside>\n\n <div className=\"appshell__main\">\n <header className=\"appshell__topbar\">\n <button\n type=\"button\"\n className=\"appshell__hamburger\"\n aria-label={t['appshell.openMenu']}\n aria-expanded={mobileOpen}\n onClick={() => setMobileOpen((o) => !o)}\n ><MenuIcon size={20} /></button>\n <div className=\"appshell__topbar-content\">{topbar}</div>\n {user && <div className=\"appshell__topbar-user\">{user}</div>}\n </header>\n <main className=\"appshell__content\" role=\"main\">{children}</main>\n </div>\n\n {mobileOpen && (\n <div className=\"appshell__scrim\" onClick={() => setMobileOpen(false)} aria-hidden=\"true\" />\n )}\n </div>\n );\n}\n\n// ---------- PageHeader --------------------------------------------------\nexport interface PageHeaderProps {\n title: React.ReactNode;\n description?: React.ReactNode;\n breadcrumbs?: Array<{ label: React.ReactNode; href?: string }>;\n actions?: React.ReactNode;\n meta?: React.ReactNode;\n className?: string;\n}\n\nexport function PageHeader({ title, description, breadcrumbs, actions, meta, className }: PageHeaderProps) {\n const t = useLocale();\n return (\n <div className={cx('page-header', className)}>\n {breadcrumbs && breadcrumbs.length > 0 && (\n <nav className=\"page-header__crumbs\" aria-label={t['appshell.breadcrumb']}>\n <ol>\n {breadcrumbs.map((c, i) => (\n <li key={i}>\n {c.href ? <a href={c.href}>{c.label}</a> : <span aria-current=\"page\">{c.label}</span>}\n {i < breadcrumbs.length - 1 && <span className=\"page-header__crumb-sep\" aria-hidden=\"true\">/</span>}\n </li>\n ))}\n </ol>\n </nav>\n )}\n <div className=\"page-header__row\">\n <div className=\"page-header__title-wrap\">\n <h1 className=\"page-header__title\">{title}</h1>\n {description && <p className=\"page-header__desc\">{description}</p>}\n </div>\n {actions && <div className=\"page-header__actions\">{actions}</div>}\n </div>\n {meta && <div className=\"page-header__meta\">{meta}</div>}\n </div>\n );\n}\n"]}
@@ -49,7 +49,9 @@ function AppShell({
49
49
  children,
50
50
  className,
51
51
  theme = "default",
52
- linkAs
52
+ linkAs,
53
+ headerLayout = "side",
54
+ header
53
55
  }) {
54
56
  const [internalCollapsed, setInternalCollapsed] = React.useState(defaultCollapsed);
55
57
  const [mobileOpen, setMobileOpen] = React.useState(false);
@@ -60,6 +62,25 @@ function AppShell({
60
62
  onCollapsedChange?.(v);
61
63
  };
62
64
  const closeMobile = React.useCallback(() => setMobileOpen(false), []);
65
+ if (headerLayout === "top") {
66
+ return /* @__PURE__ */ jsxs("div", { className: cx("appshell", `appshell--${theme}`, "appshell--header-top", collapsed && "is-collapsed", className), children: [
67
+ /* @__PURE__ */ jsxs("header", { className: "appshell__header", role: "banner", children: [
68
+ /* @__PURE__ */ jsx("div", { className: "appshell__header-left", children: header?.left }),
69
+ /* @__PURE__ */ jsx("div", { className: "appshell__header-center", children: header?.center }),
70
+ /* @__PURE__ */ jsx("div", { className: "appshell__header-right", children: header?.right })
71
+ ] }),
72
+ /* @__PURE__ */ jsxs("div", { className: "appshell__body", children: [
73
+ /* @__PURE__ */ jsxs("aside", { className: "appshell__sidebar", "aria-label": t["appshell.mainNav"], children: [
74
+ /* @__PURE__ */ jsx("nav", { className: "appshell__nav", children: sections.map((s, i) => /* @__PURE__ */ jsxs("div", { className: "appshell__navsection", children: [
75
+ s.label && /* @__PURE__ */ jsx("div", { className: "appshell__navlabel-section", children: s.label }),
76
+ /* @__PURE__ */ jsx("ul", { children: s.items.map((it) => /* @__PURE__ */ jsx(NavItemNode, { item: it, depth: 0, linkAs, onCloseMobile: closeMobile }, it.id)) })
77
+ ] }, s.id ?? i)) }),
78
+ footer != null && /* @__PURE__ */ jsx("div", { className: "appshell__sidebar-foot", children: footer })
79
+ ] }),
80
+ /* @__PURE__ */ jsx("main", { className: "appshell__content", role: "main", children })
81
+ ] })
82
+ ] });
83
+ }
63
84
  return /* @__PURE__ */ jsxs("div", { className: cx("appshell", `appshell--${theme}`, collapsed && "is-collapsed", mobileOpen && "is-mobile-open", className), children: [
64
85
  /* @__PURE__ */ jsxs("aside", { className: "appshell__sidebar", "aria-label": t["appshell.mainNav"], children: [
65
86
  /* @__PURE__ */ jsx("div", { className: "appshell__brand", children: collapsed ? brandCollapsed ?? brand : brand }),
@@ -123,5 +144,5 @@ function PageHeader({ title, description, breadcrumbs, actions, meta, className
123
144
  }
124
145
 
125
146
  export { AppShell, PageHeader };
126
- //# sourceMappingURL=chunk-HUEO23A2.mjs.map
127
- //# sourceMappingURL=chunk-HUEO23A2.mjs.map
147
+ //# sourceMappingURL=chunk-Y6AYAE4O.mjs.map
148
+ //# sourceMappingURL=chunk-Y6AYAE4O.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/AppShell.tsx"],"names":["NavItemNode"],"mappings":"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","file":"chunk-Y6AYAE4O.mjs","sourcesContent":["'use client';\nimport * as React from 'react';\nimport { cx } from '../utils/cx';\nimport { ChevronLeft, ChevronRight, MenuIcon } from './Icons';\nimport { useLocale } from '../locale/LocaleProvider';\n\n// ---------- AppShell (Sidebar + Topbar + Content) -----------------------\n// Designed to drop into a Next.js app/layout.tsx as a Client Component shell.\n\nexport interface NavItem {\n id: string;\n label: React.ReactNode;\n icon?: React.ReactNode;\n href?: string;\n active?: boolean;\n badge?: React.ReactNode;\n onSelect?: () => void;\n children?: NavItem[];\n}\n\nexport interface NavSection {\n id?: string;\n label?: React.ReactNode;\n items: NavItem[];\n}\n\nexport type AppShellTheme = 'default' | 'brand';\n\nexport type AppShellHeaderLayout = 'side' | 'top';\n\nexport interface AppShellHeader {\n /** Left slot — typically a menu/hamburger trigger or back action. */\n left?: React.ReactNode;\n /** Center slot — typically the brand (Logo). Lands at the true viewport centre. */\n center?: React.ReactNode;\n /** Right slot — notifications, user avatar, utilities. */\n right?: React.ReactNode;\n}\n\nexport interface AppShellProps {\n brand?: React.ReactNode;\n brandCollapsed?: React.ReactNode;\n sections: NavSection[];\n topbar?: React.ReactNode;\n footer?: React.ReactNode;\n user?: React.ReactNode;\n defaultCollapsed?: boolean;\n collapsed?: boolean;\n onCollapsedChange?: (c: boolean) => void;\n children: React.ReactNode;\n className?: string;\n /**\n * Sidebar color theme:\n * - `default` (light): claro, mejor para apps data-heavy de uso prolongado.\n * - `brand`: sidebar azul de marca con texto blanco. Mayor brand recall.\n */\n theme?: AppShellTheme;\n /** Render-prop for navigation links so the host app can use Next.js Link, etc. */\n linkAs?: (item: NavItem, content: React.ReactNode, className: string) => React.ReactNode;\n /**\n * Where the chrome lives. Default `'side'` is the legacy layout. `'top'`\n * renders a full-width header above the body with three slots\n * (`header.left/center/right`); the centre slot lands at the **true\n * viewport centre** (1fr·auto·1fr column grid). The sidebar has no brand\n * block (brand goes in `header.center`) and `collapsed` hides the\n * sidebar entirely — no 72px rail. The topbar is **invariant** to the\n * collapse (only the sidebar changes width). `theme=\"brand\"` tints both\n * header and sidebar with the same brand colour (single knob). `brand`,\n * `brandCollapsed` and `topbar` are ignored when `'top'`.\n */\n headerLayout?: AppShellHeaderLayout;\n /** Slots for the top-layout header (only used when `headerLayout=\"top\"`). */\n header?: AppShellHeader;\n}\n\n// Recursive nav item, memoized so a single item's parent re-render doesn't\n// churn through every other item in the tree. Stability of `linkAs` and\n// `onCloseMobile` is the parent's responsibility (we stabilize\n// `onCloseMobile` via useCallback below; consumers should memoize `linkAs`\n// if they care about avoiding renders, but for typical Next.js Link usage\n// the inline arrow is rarely a hot path).\ninterface NavItemNodeProps {\n item: NavItem;\n depth: number;\n linkAs?: AppShellProps['linkAs'];\n onCloseMobile: () => void;\n}\n\nconst NavItemNode = React.memo(function NavItemNode({\n item, depth, linkAs, onCloseMobile,\n}: NavItemNodeProps) {\n const klass = cx('appshell__navitem', item.active && 'is-active', `appshell__navitem--depth-${depth}`);\n const inner = (\n <>\n {item.icon && <span className=\"appshell__navicon\" aria-hidden=\"true\">{item.icon}</span>}\n <span className=\"appshell__navlabel\">{item.label}</span>\n {item.badge && <span className=\"appshell__navbadge\">{item.badge}</span>}\n </>\n );\n const node = item.href && linkAs\n ? linkAs(item, inner, klass)\n : (\n <a\n href={item.href ?? '#'}\n className={klass}\n aria-current={item.active ? 'page' : undefined}\n onClick={(e) => {\n if (!item.href) e.preventDefault();\n item.onSelect?.();\n onCloseMobile();\n }}\n >\n {inner}\n </a>\n );\n return (\n <li>\n {node}\n {item.children && item.children.length > 0 && (\n <ul className=\"appshell__navchildren\">\n {item.children.map((c) => (\n <NavItemNode key={c.id} item={c} depth={depth + 1} linkAs={linkAs} onCloseMobile={onCloseMobile} />\n ))}\n </ul>\n )}\n </li>\n );\n});\n\nexport function AppShell({\n brand, brandCollapsed, sections, topbar, footer, user,\n defaultCollapsed = false, collapsed: ctrlCollapsed, onCollapsedChange,\n children, className, theme = 'default', linkAs,\n headerLayout = 'side', header,\n}: AppShellProps) {\n const [internalCollapsed, setInternalCollapsed] = React.useState(defaultCollapsed);\n const [mobileOpen, setMobileOpen] = React.useState(false);\n const t = useLocale();\n const collapsed = ctrlCollapsed ?? internalCollapsed;\n const setCollapsed = (v: boolean) => {\n if (ctrlCollapsed === undefined) setInternalCollapsed(v);\n onCollapsedChange?.(v);\n };\n const closeMobile = React.useCallback(() => setMobileOpen(false), []);\n\n // Top-header variant: full-width header above the body. Topbar is\n // invariant to `collapsed` (only the inner body's columns animate); brand\n // lives in `header.center` at the true viewport centre. Default\n // `headerLayout=\"side\"` falls through to the legacy JSX below\n // (byte-identical for existing consumers).\n if (headerLayout === 'top') {\n return (\n <div className={cx('appshell', `appshell--${theme}`, 'appshell--header-top', collapsed && 'is-collapsed', className)}>\n <header className=\"appshell__header\" role=\"banner\">\n <div className=\"appshell__header-left\">{header?.left}</div>\n <div className=\"appshell__header-center\">{header?.center}</div>\n <div className=\"appshell__header-right\">{header?.right}</div>\n </header>\n <div className=\"appshell__body\">\n <aside className=\"appshell__sidebar\" aria-label={t['appshell.mainNav']}>\n <nav className=\"appshell__nav\">\n {sections.map((s, i) => (\n <div key={s.id ?? i} className=\"appshell__navsection\">\n {s.label && <div className=\"appshell__navlabel-section\">{s.label}</div>}\n <ul>{s.items.map((it) => (\n <NavItemNode key={it.id} item={it} depth={0} linkAs={linkAs} onCloseMobile={closeMobile} />\n ))}</ul>\n </div>\n ))}\n </nav>\n {footer != null && <div className=\"appshell__sidebar-foot\">{footer}</div>}\n </aside>\n <main className=\"appshell__content\" role=\"main\">{children}</main>\n </div>\n </div>\n );\n }\n\n return (\n <div className={cx('appshell', `appshell--${theme}`, collapsed && 'is-collapsed', mobileOpen && 'is-mobile-open', className)}>\n <aside className=\"appshell__sidebar\" aria-label={t['appshell.mainNav']}>\n <div className=\"appshell__brand\">\n {collapsed ? (brandCollapsed ?? brand) : brand}\n </div>\n <nav className=\"appshell__nav\">\n {sections.map((s, i) => (\n <div key={s.id ?? i} className=\"appshell__navsection\">\n {s.label && <div className=\"appshell__navlabel-section\">{s.label}</div>}\n <ul>{s.items.map((it) => (\n <NavItemNode key={it.id} item={it} depth={0} linkAs={linkAs} onCloseMobile={closeMobile} />\n ))}</ul>\n </div>\n ))}\n </nav>\n <div className=\"appshell__sidebar-foot\">\n {footer}\n <button\n type=\"button\"\n className=\"appshell__collapse\"\n onClick={() => setCollapsed(!collapsed)}\n aria-expanded={!collapsed}\n aria-label={collapsed ? t['appshell.expandMenu'] : t['appshell.collapseMenu']}\n title={collapsed ? t['appshell.expand'] : t['appshell.collapse']}\n >\n {collapsed ? <ChevronRight size={14} /> : <ChevronLeft size={14} />}\n </button>\n </div>\n </aside>\n\n <div className=\"appshell__main\">\n <header className=\"appshell__topbar\">\n <button\n type=\"button\"\n className=\"appshell__hamburger\"\n aria-label={t['appshell.openMenu']}\n aria-expanded={mobileOpen}\n onClick={() => setMobileOpen((o) => !o)}\n ><MenuIcon size={20} /></button>\n <div className=\"appshell__topbar-content\">{topbar}</div>\n {user && <div className=\"appshell__topbar-user\">{user}</div>}\n </header>\n <main className=\"appshell__content\" role=\"main\">{children}</main>\n </div>\n\n {mobileOpen && (\n <div className=\"appshell__scrim\" onClick={() => setMobileOpen(false)} aria-hidden=\"true\" />\n )}\n </div>\n );\n}\n\n// ---------- PageHeader --------------------------------------------------\nexport interface PageHeaderProps {\n title: React.ReactNode;\n description?: React.ReactNode;\n breadcrumbs?: Array<{ label: React.ReactNode; href?: string }>;\n actions?: React.ReactNode;\n meta?: React.ReactNode;\n className?: string;\n}\n\nexport function PageHeader({ title, description, breadcrumbs, actions, meta, className }: PageHeaderProps) {\n const t = useLocale();\n return (\n <div className={cx('page-header', className)}>\n {breadcrumbs && breadcrumbs.length > 0 && (\n <nav className=\"page-header__crumbs\" aria-label={t['appshell.breadcrumb']}>\n <ol>\n {breadcrumbs.map((c, i) => (\n <li key={i}>\n {c.href ? <a href={c.href}>{c.label}</a> : <span aria-current=\"page\">{c.label}</span>}\n {i < breadcrumbs.length - 1 && <span className=\"page-header__crumb-sep\" aria-hidden=\"true\">/</span>}\n </li>\n ))}\n </ol>\n </nav>\n )}\n <div className=\"page-header__row\">\n <div className=\"page-header__title-wrap\">\n <h1 className=\"page-header__title\">{title}</h1>\n {description && <p className=\"page-header__desc\">{description}</p>}\n </div>\n {actions && <div className=\"page-header__actions\">{actions}</div>}\n </div>\n {meta && <div className=\"page-header__meta\">{meta}</div>}\n </div>\n );\n}\n"]}
@@ -17,6 +17,15 @@ interface NavSection {
17
17
  items: NavItem[];
18
18
  }
19
19
  type AppShellTheme = 'default' | 'brand';
20
+ type AppShellHeaderLayout = 'side' | 'top';
21
+ interface AppShellHeader {
22
+ /** Left slot — typically a menu/hamburger trigger or back action. */
23
+ left?: React.ReactNode;
24
+ /** Center slot — typically the brand (Logo). Lands at the true viewport centre. */
25
+ center?: React.ReactNode;
26
+ /** Right slot — notifications, user avatar, utilities. */
27
+ right?: React.ReactNode;
28
+ }
20
29
  interface AppShellProps {
21
30
  brand?: React.ReactNode;
22
31
  brandCollapsed?: React.ReactNode;
@@ -37,8 +46,22 @@ interface AppShellProps {
37
46
  theme?: AppShellTheme;
38
47
  /** Render-prop for navigation links so the host app can use Next.js Link, etc. */
39
48
  linkAs?: (item: NavItem, content: React.ReactNode, className: string) => React.ReactNode;
49
+ /**
50
+ * Where the chrome lives. Default `'side'` is the legacy layout. `'top'`
51
+ * renders a full-width header above the body with three slots
52
+ * (`header.left/center/right`); the centre slot lands at the **true
53
+ * viewport centre** (1fr·auto·1fr column grid). The sidebar has no brand
54
+ * block (brand goes in `header.center`) and `collapsed` hides the
55
+ * sidebar entirely — no 72px rail. The topbar is **invariant** to the
56
+ * collapse (only the sidebar changes width). `theme="brand"` tints both
57
+ * header and sidebar with the same brand colour (single knob). `brand`,
58
+ * `brandCollapsed` and `topbar` are ignored when `'top'`.
59
+ */
60
+ headerLayout?: AppShellHeaderLayout;
61
+ /** Slots for the top-layout header (only used when `headerLayout="top"`). */
62
+ header?: AppShellHeader;
40
63
  }
41
- declare function AppShell({ brand, brandCollapsed, sections, topbar, footer, user, defaultCollapsed, collapsed: ctrlCollapsed, onCollapsedChange, children, className, theme, linkAs, }: AppShellProps): react_jsx_runtime.JSX.Element;
64
+ declare function AppShell({ brand, brandCollapsed, sections, topbar, footer, user, defaultCollapsed, collapsed: ctrlCollapsed, onCollapsedChange, children, className, theme, linkAs, headerLayout, header, }: AppShellProps): react_jsx_runtime.JSX.Element;
42
65
  interface PageHeaderProps {
43
66
  title: React.ReactNode;
44
67
  description?: React.ReactNode;
@@ -52,4 +75,4 @@ interface PageHeaderProps {
52
75
  }
53
76
  declare function PageHeader({ title, description, breadcrumbs, actions, meta, className }: PageHeaderProps): react_jsx_runtime.JSX.Element;
54
77
 
55
- export { AppShell, type AppShellProps, type AppShellTheme, type NavItem, type NavSection, PageHeader, type PageHeaderProps };
78
+ export { AppShell, type AppShellHeader, type AppShellHeaderLayout, type AppShellProps, type AppShellTheme, type NavItem, type NavSection, PageHeader, type PageHeaderProps };