@fayz-ai/ui 0.14.0 → 0.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.
- package/dist/{ChartWidgetInner-GDE5PBTR.js → ChartWidgetInner-IOLIUYTB.js} +21 -8
- package/dist/ChartWidgetInner-IOLIUYTB.js.map +1 -0
- package/dist/analytics/AnalyticsCard.d.ts.map +1 -1
- package/dist/analytics/AnalyticsControls.d.ts.map +1 -1
- package/dist/chunk-3OVZ5JJQ.js +540 -0
- package/dist/chunk-3OVZ5JJQ.js.map +1 -0
- package/dist/{chunk-UZYXFEQS.js → chunk-4GK6IHOI.js} +16 -3
- package/dist/chunk-4GK6IHOI.js.map +1 -0
- package/dist/{chunk-46UZAKFJ.js → chunk-5KMAEQA3.js} +7 -6
- package/dist/chunk-5KMAEQA3.js.map +1 -0
- package/dist/chunk-AASANYXN.js +601 -0
- package/dist/chunk-AASANYXN.js.map +1 -0
- package/dist/{chunk-LFZFBN3P.js → chunk-FFJ2C5YH.js} +11 -61
- package/dist/chunk-FFJ2C5YH.js.map +1 -0
- package/dist/{chunk-5KAGNW45.js → chunk-J7F3Z52K.js} +4 -4
- package/dist/{chunk-5KAGNW45.js.map → chunk-J7F3Z52K.js.map} +1 -1
- package/dist/{chunk-2EFRFYGF.js → chunk-KD2V3TAX.js} +180 -33
- package/dist/chunk-KD2V3TAX.js.map +1 -0
- package/dist/{chunk-MVH64JFG.js → chunk-NA3GE4H3.js} +488 -537
- package/dist/chunk-NA3GE4H3.js.map +1 -0
- package/dist/chunk-OKZ6WQB3.js +57 -0
- package/dist/chunk-OKZ6WQB3.js.map +1 -0
- package/dist/{chunk-77CUIMOI.js → chunk-SLWTKHNY.js} +103 -158
- package/dist/chunk-SLWTKHNY.js.map +1 -0
- package/dist/dashboard/ChartWidgetInner.d.ts.map +1 -1
- package/dist/dashboard/index.js +5 -4
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -16
- package/dist/index.js.map +1 -1
- package/dist/layout/AppShell.d.ts +7 -2
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/Sidebar.d.ts +27 -4
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/Topbar.d.ts +10 -3
- package/dist/layout/Topbar.d.ts.map +1 -1
- package/dist/layout/index.js +5 -4
- package/dist/primitives/SearchCombobox.d.ts +9 -1
- package/dist/primitives/SearchCombobox.d.ts.map +1 -1
- package/dist/primitives/color-palette.d.ts +24 -0
- package/dist/primitives/color-palette.d.ts.map +1 -0
- package/dist/primitives/header-tabs.d.ts +11 -1
- package/dist/primitives/header-tabs.d.ts.map +1 -1
- package/dist/primitives/image-drop.d.ts +28 -0
- package/dist/primitives/image-drop.d.ts.map +1 -0
- package/dist/primitives/index.d.ts +8 -3
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +7 -5
- package/dist/primitives/list-view.d.ts +7 -1
- package/dist/primitives/list-view.d.ts.map +1 -1
- package/dist/primitives/option-select.d.ts +46 -0
- package/dist/primitives/option-select.d.ts.map +1 -0
- package/dist/primitives/page-toolbar.d.ts +20 -1
- package/dist/primitives/page-toolbar.d.ts.map +1 -1
- package/dist/primitives/sheet.d.ts.map +1 -1
- package/dist/primitives/step-progress.d.ts +20 -0
- package/dist/primitives/step-progress.d.ts.map +1 -0
- package/dist/primitives/use-row-selection.d.ts +50 -0
- package/dist/primitives/use-row-selection.d.ts.map +1 -0
- package/dist/styles.css +20 -0
- package/dist/wizard/Wizard.d.ts +38 -0
- package/dist/wizard/Wizard.d.ts.map +1 -0
- package/dist/wizard/WizardField.d.ts +22 -0
- package/dist/wizard/WizardField.d.ts.map +1 -0
- package/dist/wizard/index.d.ts +6 -0
- package/dist/wizard/index.d.ts.map +1 -0
- package/dist/wizard/index.js +5 -0
- package/dist/wizard/index.js.map +1 -0
- package/dist/wizard/logic.d.ts +39 -0
- package/dist/wizard/logic.d.ts.map +1 -0
- package/dist/wizard/types.d.ts +95 -0
- package/dist/wizard/types.d.ts.map +1 -0
- package/dist/wizard/useWizard.d.ts +47 -0
- package/dist/wizard/useWizard.d.ts.map +1 -0
- package/package.json +12 -6
- package/dist/ChartWidgetInner-GDE5PBTR.js.map +0 -1
- package/dist/chunk-2EFRFYGF.js.map +0 -1
- package/dist/chunk-46UZAKFJ.js.map +0 -1
- package/dist/chunk-77CUIMOI.js.map +0 -1
- package/dist/chunk-LFZFBN3P.js.map +0 -1
- package/dist/chunk-MVH64JFG.js.map +0 -1
- package/dist/chunk-UZYXFEQS.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/wizard/logic.ts","../src/wizard/useWizard.ts","../src/wizard/WizardField.tsx","../src/wizard/Wizard.tsx"],"names":["visibleSteps","visibleFields","next","fieldErrors","canAdvance","jsxs","jsx","React2","Loader2"],"mappings":"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","file":"chunk-AASANYXN.js","sourcesContent":["import type { WizardFieldDef, WizardStepDef, WizardValues } from './types'\n\n/**\n * The wizard's decisions, without React.\n *\n * Which steps show, which fields show, what blocks the button — all of it is a\n * function of the answers, so it lives here where it can be tested directly\n * instead of through a rendered component.\n */\n\nexport function isEmpty(value: unknown): boolean {\n if (value === undefined || value === null) return true\n if (typeof value === 'string') return value.trim() === ''\n if (Array.isArray(value)) return value.length === 0\n return false\n}\n\nexport function visibleSteps(\n steps: ReadonlyArray<WizardStepDef>,\n values: WizardValues,\n): ReadonlyArray<WizardStepDef> {\n return steps.filter((s) => (s.visibleWhen ? s.visibleWhen(values) : true))\n}\n\nexport function visibleFields(\n step: WizardStepDef | undefined,\n values: WizardValues,\n): ReadonlyArray<WizardFieldDef> {\n return (step?.fields ?? []).filter((f) => (f.visibleWhen ? f.visibleWhen(values) : true))\n}\n\n/**\n * Per-field messages for the current step.\n *\n * An untouched required field gets no message: a red line before someone has had\n * a chance to type reads as a failure they caused. The disabled button says the\n * same thing without the accusation — see `canAdvance`.\n */\nexport function fieldErrors(\n fields: ReadonlyArray<WizardFieldDef>,\n values: WizardValues,\n asyncErrors: Record<string, string | null> = {},\n): Record<string, string | null> {\n const out: Record<string, string | null> = {}\n for (const field of fields) {\n const value = values[field.id]\n out[field.id] = (isEmpty(value) ? null : field.validate?.(value, values)) ?? asyncErrors[field.id] ?? null\n }\n return out\n}\n\nexport function canAdvance(\n step: WizardStepDef | undefined,\n fields: ReadonlyArray<WizardFieldDef>,\n values: WizardValues,\n errors: Record<string, string | null>,\n): boolean {\n if (!step) return false\n if (fields.some((f) => f.required && isEmpty(values[f.id]))) return false\n if (Object.values(errors).some(Boolean)) return false\n return !step.validate?.(values)\n}\n\n/**\n * Which of a `suggest`'s answers may actually land.\n *\n * Three refusals, each for its own reason: a field nobody asks about would sit\n * in the answers invisibly and still get submitted; a field the user has\n * answered is theirs, and a slow reply must not overwrite what they typed while\n * waiting for it; an empty value would mark a field as \"suggested\" while\n * changing nothing on screen.\n */\nexport function acceptableSuggestion(\n patch: WizardValues,\n knownFieldIds: ReadonlySet<string>,\n answered: ReadonlySet<string>,\n): WizardValues {\n const accepted: WizardValues = {}\n for (const [id, value] of Object.entries(patch)) {\n if (!knownFieldIds.has(id)) continue\n if (answered.has(id)) continue\n if (isEmpty(value)) continue\n accepted[id] = value\n }\n return accepted\n}\n\n/** Every field id the flow asks about, across all steps — visible or not. */\nexport function allFieldIds(steps: ReadonlyArray<WizardStepDef>): Set<string> {\n return new Set(steps.flatMap((s) => (s.fields ?? []).map((f) => f.id)))\n}\n\nexport interface WizardDraft {\n index: number\n values: WizardValues\n}\n\n/** Tolerant on purpose: a corrupt draft is a fresh start, never a crash. */\nexport function parseDraft(raw: string | null): WizardDraft | null {\n if (!raw) return null\n try {\n const parsed = JSON.parse(raw) as { index?: unknown; values?: unknown }\n const values = parsed.values && typeof parsed.values === 'object' ? (parsed.values as WizardValues) : {}\n return { index: typeof parsed.index === 'number' ? parsed.index : 0, values }\n } catch {\n return null\n }\n}\n","import * as React from 'react'\nimport {\n acceptableSuggestion,\n allFieldIds,\n canAdvance as computeCanAdvance,\n fieldErrors as computeFieldErrors,\n isEmpty,\n parseDraft,\n visibleFields as computeVisibleFields,\n visibleSteps as computeVisibleSteps,\n type WizardDraft,\n} from './logic'\nimport type { WizardFieldDef, WizardStepDef, WizardValues } from './types'\n\nexport interface UseWizardOptions {\n steps: ReadonlyArray<WizardStepDef>\n initialValues?: WizardValues\n /**\n * localStorage key for the in-progress draft. Someone who closes the tab\n * mid-flow should not have to answer everything again. Omit to keep it in memory.\n */\n draftKey?: string\n onSubmit?: (values: WizardValues) => Promise<void> | void\n}\n\nexport interface UseWizardResult {\n /** Only the steps whose `visibleWhen` passes for the current answers. */\n steps: ReadonlyArray<WizardStepDef>\n step: WizardStepDef | undefined\n index: number\n total: number\n values: WizardValues\n setValue: (id: string, value: unknown) => void\n /** Per-field messages for the current step, keyed by field id. */\n fieldErrors: Record<string, string | null>\n /** The step-level blocking message, or null. Field-level ones live in `fieldErrors`. */\n blocker: string | null\n canAdvance: boolean\n isFirst: boolean\n isLast: boolean\n submitting: boolean\n error: string | null\n next: () => void\n back: () => void\n goTo: (index: number) => void\n submit: () => Promise<void>\n /** True once the user has answered anything, or resumed a draft that had. */\n touched: boolean\n /** Forget the persisted draft — call after a successful submit. */\n clearDraft: () => void\n /** Fields of the current step that pass their own `visibleWhen`. */\n visibleFields: ReadonlyArray<WizardFieldDef>\n /** Id of the field whose `suggest` is in flight, or null. */\n suggesting: string | null\n /** Fields currently holding a suggested answer rather than one the user gave. */\n suggested: ReadonlySet<string>\n /** Drop a suggestion the user disagrees with, and stop marking the field. */\n clearSuggestion: (id: string) => void\n}\n\nfunction readDraft(key: string | undefined): WizardDraft | null {\n if (!key || typeof localStorage === 'undefined') return null\n try {\n return parseDraft(localStorage.getItem(key))\n } catch {\n return null\n }\n}\n\nexport function useWizard({ steps, initialValues, draftKey, onSubmit }: UseWizardOptions): UseWizardResult {\n const [draft] = React.useState(() => readDraft(draftKey))\n const [values, setValues] = React.useState<WizardValues>(() => ({ ...initialValues, ...draft?.values }))\n const [index, setIndex] = React.useState(() => draft?.index ?? 0)\n const [submitting, setSubmitting] = React.useState(false)\n // Whether there is anything to lose. Seeded values (the account's own e-mail)\n // are ours, not theirs — warning about discarding those is warning about\n // nothing. A resumed draft counts: they typed it, just not this session.\n const [touched, setTouched] = React.useState(() => Object.keys(draft?.values ?? {}).length > 0)\n const [error, setError] = React.useState<string | null>(null)\n /** Async field errors (slug taken), keyed by field id. */\n const [asyncErrors, setAsyncErrors] = React.useState<Record<string, string | null>>({})\n const [suggesting, setSuggesting] = React.useState<string | null>(null)\n const [suggested, setSuggested] = React.useState<ReadonlySet<string>>(() => new Set())\n\n const visibleSteps = React.useMemo(() => computeVisibleSteps(steps, values), [steps, values])\n\n // Hiding a step can shorten the flow past where we are standing.\n const safeIndex = Math.min(index, Math.max(visibleSteps.length - 1, 0))\n const step = visibleSteps[safeIndex]\n\n const visibleFields = React.useMemo(() => computeVisibleFields(step, values), [step, values])\n\n // Seed derived fields (the slug from the name) once there is something to\n // derive FROM, then never again — re-deriving would overwrite an edit the\n // user just made. Seeding on an empty source is what silently burned the one\n // chance: it marked the field derived and wrote nothing.\n const derivedRef = React.useRef(new Set<string>())\n React.useEffect(() => {\n const seeds = visibleFields\n .filter((f) => f.derive && !derivedRef.current.has(f.id) && isEmpty(values[f.id]))\n .map((f) => [f, f.derive!(values)] as const)\n .filter(([, derived]) => !isEmpty(derived))\n if (seeds.length === 0) return\n setValues((prev) => {\n const next = { ...prev }\n for (const [field, derived] of seeds) {\n derivedRef.current.add(field.id)\n next[field.id] = derived\n }\n return next\n })\n }, [visibleFields, values])\n\n // Nothing is written until the user actually answers something. Persisting the\n // seeded values on mount left a draft behind for a flow nobody engaged with,\n // and the next session read it back as \"you had progress here\".\n React.useEffect(() => {\n if (!draftKey || !touched || typeof localStorage === 'undefined') return\n try {\n localStorage.setItem(draftKey, JSON.stringify({ index: safeIndex, values }))\n } catch {\n // A full or blocked storage must not break the flow — the draft is a convenience.\n }\n }, [draftKey, touched, safeIndex, values])\n\n // Answering something makes it theirs. A suggestion that arrives afterwards\n // must not land on top of it, and one already on screen stops being marked as\n // a suggestion the moment they edit it.\n const answeredRef = React.useRef(new Set<string>(Object.keys(draft?.values ?? {})))\n\n const setValue = React.useCallback((id: string, value: unknown) => {\n setTouched(true)\n answeredRef.current.add(id)\n setValues((prev) => ({ ...prev, [id]: value }))\n setAsyncErrors((prev) => (prev[id] ? { ...prev, [id]: null } : prev))\n setSuggested((prev) => {\n if (!prev.has(id)) return prev\n const next = new Set(prev)\n next.delete(id)\n return next\n })\n }, [])\n\n const clearSuggestion = React.useCallback((id: string) => {\n answeredRef.current.add(id)\n setValues((prev) => {\n if (!(id in prev)) return prev\n const next = { ...prev }\n delete next[id]\n return next\n })\n setSuggested((prev) => {\n if (!prev.has(id)) return prev\n const next = new Set(prev)\n next.delete(id)\n return next\n })\n }, [])\n\n // Debounced async checks for the fields that declare one.\n const checkable = visibleFields.filter((f) => f.checkAsync)\n const checkSignature = checkable.map((f) => `${f.id}:${String(values[f.id] ?? '')}`).join('|')\n React.useEffect(() => {\n if (checkable.length === 0) return\n let cancelled = false\n const timer = setTimeout(() => {\n for (const field of checkable) {\n const raw = values[field.id]\n if (typeof raw !== 'string' || raw.trim() === '') continue\n void field\n .checkAsync!(raw, values)\n .then((message) => { if (!cancelled) setAsyncErrors((prev) => ({ ...prev, [field.id]: message })) })\n // A failed availability probe must not block the flow — the server\n // still has the unique constraint, and submit surfaces the real error.\n .catch(() => { if (!cancelled) setAsyncErrors((prev) => ({ ...prev, [field.id]: null })) })\n }\n }, 400)\n return () => { cancelled = true; clearTimeout(timer) }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [checkSignature])\n\n // A suggestion may answer a field on any step, so the ids it may write are the\n // whole flow's — but only the whole flow's.\n const knownFieldIds = React.useMemo(() => allFieldIds(steps), [steps])\n\n const applySuggestion = React.useCallback(\n (patch: WizardValues) => {\n const accepted = acceptableSuggestion(patch, knownFieldIds, answeredRef.current)\n const ids = Object.keys(accepted)\n if (ids.length === 0) return\n\n // Deliberately does NOT set `touched`. A crawl the user only watched\n // happen is not progress they made, and persisting it would leave a draft\n // behind for a flow nobody engaged with — the same trap the seeded values\n // above already fell into once.\n setValues((prev) => ({ ...prev, ...accepted }))\n setSuggested((prev) => {\n const next = new Set(prev)\n for (const id of ids) next.add(id)\n return next\n })\n },\n [knownFieldIds],\n )\n\n /**\n * Debounced enrichment for the fields that declare one. Slower than\n * `checkAsync`'s 400 ms because this one leaves the building and costs money;\n * a slug probe can afford to fire on every pause, a site crawl cannot.\n */\n const suggestable = visibleFields.filter((f) => f.suggest)\n const suggestSignature = suggestable.map((f) => `${f.id}:${String(values[f.id] ?? '')}`).join('|')\n const suggestedForRef = React.useRef(new Map<string, string>())\n const suggestRunRef = React.useRef(0)\n\n React.useEffect(() => {\n if (suggestable.length === 0) return\n const pending = suggestable.filter((field) => {\n const raw = values[field.id]\n if (typeof raw !== 'string' || raw.trim() === '') return false\n // Stepping back onto the field, or re-rendering, must not buy the same\n // answer twice.\n return suggestedForRef.current.get(field.id) !== raw.trim()\n })\n if (pending.length === 0) return\n\n let cancelled = false\n const timer = setTimeout(() => {\n const run = ++suggestRunRef.current\n for (const field of pending) {\n const raw = String(values[field.id]).trim()\n suggestedForRef.current.set(field.id, raw)\n setSuggesting(field.id)\n\n void field\n .suggest!(raw, values)\n .then((patch) => {\n // A reply for an address they have since changed is stale, and\n // applying it would answer a form about the wrong business.\n if (cancelled || run !== suggestRunRef.current) return\n if (patch) applySuggestion(patch)\n })\n // Enrichment, not a gate: a failed read leaves the form as it was.\n .catch(() => {})\n .finally(() => {\n if (!cancelled && run === suggestRunRef.current) setSuggesting(null)\n })\n }\n }, 900)\n\n return () => {\n cancelled = true\n clearTimeout(timer)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [suggestSignature])\n\n const fieldErrors = React.useMemo(\n () => computeFieldErrors(visibleFields, values, asyncErrors),\n [visibleFields, values, asyncErrors],\n )\n\n const blocker = React.useMemo(() => step?.validate?.(values) ?? null, [step, values])\n\n const canAdvance = !submitting && computeCanAdvance(step, visibleFields, values, fieldErrors)\n\n const isLast = safeIndex >= visibleSteps.length - 1\n\n const clearDraft = React.useCallback(() => {\n if (!draftKey || typeof localStorage === 'undefined') return\n try { localStorage.removeItem(draftKey) } catch { /* ignore */ }\n }, [draftKey])\n\n const submit = React.useCallback(async () => {\n if (!onSubmit) return\n setSubmitting(true)\n setError(null)\n try {\n await onSubmit(values)\n clearDraft()\n } catch (err: unknown) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSubmitting(false)\n }\n }, [onSubmit, values, clearDraft])\n\n const next = React.useCallback(() => {\n if (!canAdvance) return\n if (isLast) { void submit(); return }\n setIndex((i) => Math.min(i + 1, visibleSteps.length - 1))\n }, [canAdvance, isLast, submit, visibleSteps.length])\n\n const back = React.useCallback(() => setIndex((i) => Math.max(i - 1, 0)), [])\n\n const goTo = React.useCallback(\n (target: number) => setIndex(Math.max(0, Math.min(target, visibleSteps.length - 1))),\n [visibleSteps.length],\n )\n\n return {\n steps: visibleSteps,\n step,\n index: safeIndex,\n total: visibleSteps.length,\n values,\n setValue,\n fieldErrors,\n blocker,\n canAdvance,\n isFirst: safeIndex === 0,\n isLast,\n submitting,\n error,\n next,\n back,\n goTo,\n submit,\n touched,\n clearDraft,\n visibleFields,\n suggesting,\n suggested,\n clearSuggestion,\n }\n}\n","import * as React from 'react'\nimport { Loader2, Sparkles, X } from 'lucide-react'\nimport { cn } from '../lib/cn'\nimport { ColorPalette } from '../primitives/color-palette'\nimport { ImageDrop } from '../primitives/image-drop'\nimport { OptionCards, OptionChips } from '../primitives/option-select'\nimport { Switch } from '../primitives/switch'\nimport type { WizardFieldDef, WizardValues } from './types'\n\nexport interface WizardFieldProps {\n field: WizardFieldDef\n values: WizardValues\n onChange: (id: string, value: unknown) => void\n /** Async/validation message resolved by the wizard for this field. */\n error?: string | null\n autoFocus?: boolean\n /** This field owns the 1–9 keys on this step. Only one field may. */\n shortcuts?: boolean\n /** This field's `suggest` is in flight. */\n busy?: boolean\n /** The value on screen came from a suggestion, not from the user. */\n suggested?: boolean\n /** Discard the suggestion. Only rendered when `suggested`. */\n onClearSuggestion?: () => void\n /** Text on the badge that marks a suggested answer. */\n suggestedLabel?: string\n}\n\n/** Wizard fields are the page's main event, so they run bigger than admin density. */\nconst FIELD_CLASS =\n 'h-12 w-full rounded-lg border border-border bg-card px-4 text-base text-foreground placeholder:text-muted-foreground ' +\n 'transition-colors focus:border-foreground/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ' +\n 'focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50'\n\nconst INPUT_TYPE: Partial<Record<WizardFieldDef['kind'], string>> = {\n email: 'email',\n phone: 'tel',\n}\n\nexport function WizardField({\n field,\n values,\n onChange,\n error,\n autoFocus,\n shortcuts,\n busy,\n suggested,\n onClearSuggestion,\n suggestedLabel,\n}: WizardFieldProps) {\n const value = values[field.id]\n const set = (next: unknown) => onChange(field.id, next)\n\n const body = (() => {\n switch (field.kind) {\n case 'palette':\n return (\n <ColorPalette\n value={Array.isArray(value) ? (value as string[]) : undefined}\n onChange={set}\n slots={field.slots}\n />\n )\n case 'cards':\n return (\n <OptionCards\n options={field.options ?? []}\n value={value as string | string[] | undefined}\n onChange={set}\n multi={field.multi}\n columns={field.columns}\n shortcuts={shortcuts}\n aria-label={field.label}\n />\n )\n case 'chips':\n return (\n <OptionChips\n options={field.options ?? []}\n value={value as string | string[] | undefined}\n onChange={set}\n multi={field.multi}\n shortcuts={shortcuts}\n aria-label={field.label}\n />\n )\n case 'toggle':\n return (\n <div className=\"flex items-center justify-between gap-4 rounded-lg border border-border bg-card px-4 py-3\">\n <span className=\"text-sm text-foreground\">{field.label}</span>\n <Switch checked={Boolean(value)} onCheckedChange={(checked) => set(checked)} />\n </div>\n )\n case 'image':\n return (\n <ImageDrop\n value={typeof value === 'string' ? value : undefined}\n onUpload={field.onUpload}\n onChange={(url) => set(url)}\n label={field.label}\n hint={field.hint}\n />\n )\n case 'textarea':\n return (\n <textarea\n rows={3}\n className={cn(FIELD_CLASS, 'h-auto py-3 leading-relaxed')}\n placeholder={field.placeholder}\n value={typeof value === 'string' ? value : ''}\n autoFocus={autoFocus}\n onChange={(e) => set(e.target.value)}\n />\n )\n default:\n return (\n <div className=\"relative\">\n <input\n type={INPUT_TYPE[field.kind] ?? 'text'}\n className={cn(FIELD_CLASS, busy && 'pr-11', error && 'border-destructive')}\n placeholder={field.placeholder}\n value={typeof value === 'string' ? value : ''}\n autoFocus={autoFocus}\n autoComplete={field.kind === 'email' ? 'email' : 'off'}\n onChange={(e) => set(field.normalize ? field.normalize(e.target.value) : e.target.value)}\n />\n {busy && (\n // The wrapper does the positioning and the icon does nothing but\n // spin. Both on one element fights: `animate-spin`'s keyframe sets\n // a bare `transform: rotate(...)`, which replaces the composed\n // transform that `-translate-y-1/2` lives in — so the icon drops\n // half its height on every frame and the rotation reads as a\n // stutter. `inset-y-0` + `items-center` centres with no transform\n // at all, leaving the animation the only one.\n <span className=\"pointer-events-none absolute inset-y-0 right-4 flex items-center\">\n <Loader2 className=\"h-4 w-4 animate-spin text-muted-foreground\" />\n </span>\n )}\n </div>\n )\n }\n })()\n\n // The toggle and image fields carry their own label inline; repeating it above\n // would print the question twice.\n const labelAbove = field.label && field.kind !== 'toggle' && field.kind !== 'image'\n\n return (\n <div className=\"space-y-2\">\n {(labelAbove || suggested) && (\n <div className=\"flex items-center justify-between gap-2\">\n {labelAbove ? (\n <label className=\"block text-sm font-medium text-foreground\">{field.label}</label>\n ) : (\n <span />\n )}\n {suggested && suggestedLabel && (\n <SuggestedBadge label={suggestedLabel} onClear={onClearSuggestion} />\n )}\n </div>\n )}\n {body}\n {field.hint && field.kind !== 'image' && !error && (\n <p className=\"text-xs leading-relaxed text-muted-foreground\">{field.hint}</p>\n )}\n {error && <p className=\"text-xs text-destructive\">{error}</p>}\n </div>\n )\n}\n\n/**\n * Marks an answer nobody gave. It has to be visible enough that the user knows\n * to check it and quiet enough that it doesn't read as an error — this is a head\n * start, not a warning.\n */\nfunction SuggestedBadge({ label, onClear }: { label: string; onClear?: () => void }) {\n return (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-[11px] text-muted-foreground\">\n <Sparkles className=\"h-3 w-3\" />\n {label}\n {onClear && (\n <button\n type=\"button\"\n onClick={onClear}\n aria-label={`${label} — descartar`}\n className=\"ml-0.5 rounded-full text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n )}\n </span>\n )\n}\n","import * as React from 'react'\nimport { ArrowLeft, ArrowRight, Loader2 } from 'lucide-react'\nimport { cn } from '../lib/cn'\nimport { Button } from '../primitives/button'\nimport { ConfirmDialog } from '../primitives/confirm-dialog'\nimport { StepProgress } from '../primitives/step-progress'\nimport { isEmpty as isEmptyAnswer, visibleFields as computeVisibleFields } from './logic'\nimport { useWizard, type UseWizardResult } from './useWizard'\nimport { WizardField } from './WizardField'\nimport type { WizardMedia, WizardStepDef, WizardValues } from './types'\n\nexport interface WizardLabels {\n back: string\n next: string\n finish: string\n exit: string\n stepOf: string\n exitTitle: string\n exitDescription: string\n exitConfirm: string\n exitCancel: string\n /** Badge on a field a `suggest` answered rather than the user. */\n suggested: string\n}\n\nconst DEFAULT_LABELS: WizardLabels = {\n back: 'Back',\n next: 'Continue',\n finish: 'Finish',\n exit: 'Exit',\n // `{current}` and `{total}` are substituted.\n stepOf: 'Step {current} of {total}',\n exitTitle: 'Leave setup?',\n exitDescription: 'You have already started — leaving now loses what you filled in.',\n exitConfirm: 'Leave',\n exitCancel: 'Go back',\n suggested: 'from your site',\n}\n\nexport interface WizardProps {\n steps: ReadonlyArray<WizardStepDef>\n initialValues?: WizardValues\n draftKey?: string\n onSubmit: (values: WizardValues) => Promise<void> | void\n /** Omit to hide the exit affordance — a first-run flow with nowhere to go back to. */\n onExit?: () => void\n /** Brand mark above the question. */\n logo?: React.ReactNode\n /** Panel shown when the current step declares no media of its own. */\n fallbackMedia?: WizardMedia\n labels?: Partial<WizardLabels>\n className?: string\n}\n\n/** Themed panel used when a step ships no artwork, so the split never looks broken. */\nfunction MediaFallback() {\n return (\n <div className=\"relative h-full w-full overflow-hidden bg-sidebar\">\n <div className=\"absolute inset-0 bg-gradient-to-br from-primary/25 via-transparent to-sidebar\" />\n <div className=\"absolute -right-24 -top-24 h-96 w-96 rounded-full bg-primary/20 blur-3xl\" />\n <div className=\"absolute -bottom-32 -left-16 h-96 w-96 rounded-full bg-primary/10 blur-3xl\" />\n </div>\n )\n}\n\nfunction MediaPanel({ media }: { media: WizardMedia | undefined }) {\n if (!media) return <MediaFallback />\n if (media.node) return <div className=\"h-full w-full overflow-auto bg-sidebar\">{media.node}</div>\n if (!media.src) return <MediaFallback />\n return (\n <picture className=\"block h-full w-full\">\n {media.srcDark && <source srcSet={media.srcDark} media=\"(prefers-color-scheme: dark)\" />}\n <img src={media.src} alt={media.alt ?? ''} className=\"h-full w-full object-cover\" />\n </picture>\n )\n}\n\n/**\n * Fullscreen, data-driven wizard: form column on the left, media panel on the right.\n *\n * Steps and fields are plain data (`WizardStepDef[]`), so a flow changes by editing\n * a list rather than a component — which is the whole point for questionnaires that\n * get reworded every time we learn something about a vertical.\n */\nexport function Wizard({\n steps, initialValues, draftKey, onSubmit, onExit, logo, fallbackMedia, labels, className,\n}: WizardProps) {\n const text = { ...DEFAULT_LABELS, ...labels }\n const w: UseWizardResult = useWizard({ steps, initialValues, draftKey, onSubmit })\n const [confirmExit, setConfirmExit] = React.useState(false)\n // Which way the step slid in — forward and back read as opposite motions.\n const [direction, setDirection] = React.useState<'forward' | 'back'>('forward')\n\n const goNext = React.useCallback(() => { setDirection('forward'); w.next() }, [w])\n const goBack = React.useCallback(() => { setDirection('back'); w.back() }, [w])\n\n React.useEffect(() => {\n function onKey(e: KeyboardEvent) {\n if (confirmExit) return\n const target = e.target as HTMLElement | null\n const typing = target?.tagName === 'TEXTAREA'\n if (e.key === 'Enter' && !typing && !e.shiftKey) { e.preventDefault(); goNext() }\n // ← only when nothing is focused for typing, or it would fight the caret.\n if (e.key === 'ArrowLeft' && target?.tagName !== 'INPUT' && !typing && !w.isFirst) goBack()\n }\n document.addEventListener('keydown', onKey)\n return () => document.removeEventListener('keydown', onKey)\n }, [goNext, goBack, w.isFirst, confirmExit])\n\n // The wizard covers the viewport, so anything scrollable behind it is a\n // scrollbar that scrolls nothing — and on a short screen, a page that drifts\n // under a fixed layer.\n React.useEffect(() => {\n if (typeof document === 'undefined') return\n const previous = document.body.style.overflow\n document.body.style.overflow = 'hidden'\n return () => { document.body.style.overflow = previous }\n }, [])\n\n const requestExit = () => {\n if (!onExit) return\n // Nothing typed yet is nothing to lose — asking would be ceremony.\n if (!w.touched) { onExit(); return }\n setConfirmExit(true)\n }\n\n /**\n * A step that asks one thing, once, moves on by itself.\n *\n * Picking the only answer on the screen and then reaching for \"Continue\" is\n * two gestures for one decision. Auto-advance is deliberately narrow: single\n * choice only (multi is still being built up), nothing else on the step, and\n * never into the submit — a workspace must be created by someone meaning to.\n */\n const [pendingAdvance, setPendingAdvance] = React.useState<string | null>(null)\n\n const setValue = React.useCallback(\n (id: string, value: unknown) => {\n w.setValue(id, value)\n if (w.isLast || !w.step || w.step.render) return\n const field = w.visibleFields.find((f) => f.id === id)\n if (!field || field.multi || (field.kind !== 'cards' && field.kind !== 'chips')) return\n if (w.visibleFields.length !== 1) return\n // The answer may reveal a follow-up (\"which system?\"). Advancing past a\n // box we just put on screen is worse than not advancing at all.\n if (computeVisibleFields(w.step, { ...w.values, [id]: value }).length !== 1) return\n setPendingAdvance(w.step.id)\n },\n [w],\n )\n\n // Armed by the click, fired from here — `next` refuses while `canAdvance` is\n // false, and at click time it still is: the value has not landed yet.\n React.useEffect(() => {\n if (!pendingAdvance) return\n if (pendingAdvance !== w.step?.id) { setPendingAdvance(null); return }\n if (!w.canAdvance) return\n // A beat, so the selection is seen before the screen changes.\n const timer = setTimeout(() => { setPendingAdvance(null); setDirection('forward'); w.next() }, 320)\n return () => clearTimeout(timer)\n }, [pendingAdvance, w.step?.id, w.canAdvance, w.next])\n\n // One field per step owns 1–9: the first unanswered choice group, or the first\n // one when everything is answered. Binding every group would make \"1\" mean\n // several things at once on a step that asks two questions.\n const choiceFields = w.visibleFields.filter((f) => f.kind === 'cards' || f.kind === 'chips')\n const shortcutFieldId = (choiceFields.find((f) => isEmptyAnswer(w.values[f.id])) ?? choiceFields[0])?.id\n\n const step = w.step\n if (!step) return null\n\n const nextLabel = step.nextLabel ?? (w.isLast ? text.finish : text.next)\n\n return (\n <div className={cn('fixed inset-0 z-50 flex bg-background', className)}>\n {/* Form column */}\n <div className=\"flex min-w-0 flex-1 flex-col lg:w-[58%] lg:flex-none lg:basis-[58%]\">\n <div className=\"flex-1 overflow-y-auto px-6 pt-10 sm:px-12 lg:px-16\">\n <div className=\"mx-auto w-full max-w-xl\">\n {logo && <div className=\"mb-8\">{logo}</div>}\n <div\n // Remounting on step change is what replays the entrance animation.\n key={step.id}\n className={direction === 'forward' ? 'saas-nav-forward' : 'saas-nav-back'}\n >\n {step.eyebrow && (\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-primary\">{step.eyebrow}</p>\n )}\n <h1 className=\"text-3xl font-bold leading-tight tracking-tight text-foreground sm:text-4xl\">\n {step.title}\n </h1>\n {step.subtitle && (\n <p className=\"mt-3 text-base leading-relaxed text-muted-foreground\">{step.subtitle}</p>\n )}\n\n <div className=\"mt-8 space-y-6 pb-10\">\n {step.render\n ? step.render({ values: w.values, setValue, steps: w.steps, index: w.index, submitting: w.submitting })\n : w.visibleFields.map((field, i) => (\n <WizardField\n key={field.id}\n field={field}\n values={w.values}\n onChange={setValue}\n error={w.fieldErrors[field.id]}\n autoFocus={i === 0 && (field.kind === 'text' || field.kind === 'email' || field.kind === 'slug')}\n shortcuts={field.id === shortcutFieldId}\n busy={w.suggesting === field.id}\n suggested={w.suggested.has(field.id)}\n suggestedLabel={text.suggested}\n onClearSuggestion={() => w.clearSuggestion(field.id)}\n />\n ))}\n {w.blocker && <p className=\"text-sm text-destructive\">{w.blocker}</p>}\n {w.error && <p className=\"text-sm text-destructive\">{w.error}</p>}\n </div>\n </div>\n </div>\n </div>\n\n {/* Footer — progress sits directly above it, as one landing strip */}\n <div className=\"border-t border-border/60 px-6 pb-6 pt-4 sm:px-12 lg:px-16\">\n <div className=\"mx-auto w-full max-w-xl\">\n <StepProgress\n total={w.total}\n current={w.index}\n onSelect={(i) => { setDirection('back'); w.goTo(i) }}\n aria-label={text.stepOf\n .replace('{current}', String(w.index + 1))\n .replace('{total}', String(w.total))}\n className=\"mb-4\"\n />\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-1\">\n {!w.isFirst && (\n <Button variant=\"outline\" size=\"lg\" onClick={goBack} disabled={w.submitting}>\n <ArrowLeft className=\"h-4 w-4\" />\n {text.back}\n </Button>\n )}\n {onExit && (\n <Button variant=\"ghost\" size=\"lg\" onClick={requestExit} disabled={w.submitting}>\n {text.exit}\n </Button>\n )}\n </div>\n <Button size=\"lg\" onClick={goNext} disabled={!w.canAdvance}>\n {w.submitting ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : null}\n {nextLabel}\n {!w.submitting && !w.isLast && <ArrowRight className=\"h-4 w-4\" />}\n </Button>\n </div>\n </div>\n </div>\n </div>\n\n {/* Media column — the space images live in. Gone below lg, where the\n form needs the whole width more than the flow needs decoration. */}\n <div className=\"hidden lg:block lg:flex-1\">\n <MediaPanel media={step.media ?? fallbackMedia} />\n </div>\n\n <ConfirmDialog\n open={confirmExit}\n title={text.exitTitle}\n description={text.exitDescription}\n confirmLabel={text.exitConfirm}\n cancelLabel={text.exitCancel}\n variant=\"warning\"\n // The dialog says the progress is lost, so it has to be. The draft is\n // for a closed tab or a reload, not for overriding an explicit discard —\n // keeping it here would drop the next person who opens the flow onto\n // someone else's abandoned summary screen.\n onConfirm={() => { setConfirmExit(false); w.clearDraft(); onExit?.() }}\n onCancel={() => setConfirmExit(false)}\n />\n </div>\n )\n}\n"]}
|
|
@@ -1,57 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { twMerge } from 'tailwind-merge';
|
|
3
|
-
import * as React2 from 'react';
|
|
4
|
-
import { Slot } from '@radix-ui/react-slot';
|
|
5
|
-
import { cva } from 'class-variance-authority';
|
|
6
|
-
import { jsx } from 'react/jsx-runtime';
|
|
1
|
+
import * as React from 'react';
|
|
7
2
|
import { create } from 'zustand';
|
|
8
3
|
|
|
9
|
-
// src/
|
|
10
|
-
function cn(...inputs) {
|
|
11
|
-
return twMerge(clsx(inputs));
|
|
12
|
-
}
|
|
13
|
-
var buttonVariants = cva(
|
|
14
|
-
"inline-flex items-center justify-center gap-1.5 whitespace-nowrap rounded-button text-sm font-semibold ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
15
|
-
{
|
|
16
|
-
variants: {
|
|
17
|
-
variant: {
|
|
18
|
-
// Polaris primary — near-black brand with the stronger primary bevel
|
|
19
|
-
default: "bg-primary text-primary-foreground border border-primary shadow-button-primary hover:bg-primary/90 active:shadow-button-inset",
|
|
20
|
-
destructive: "bg-destructive text-destructive-foreground border border-destructive shadow-button-primary hover:bg-destructive/90 active:shadow-button-inset",
|
|
21
|
-
// Default/secondary surface — white with hairline + bevel
|
|
22
|
-
outline: "border border-border bg-card text-foreground shadow-button hover:bg-muted active:shadow-button-inset",
|
|
23
|
-
secondary: "border border-border bg-card text-foreground shadow-button hover:bg-muted active:shadow-button-inset",
|
|
24
|
-
ghost: "hover:bg-muted hover:text-foreground",
|
|
25
|
-
link: "text-info underline-offset-4 hover:underline"
|
|
26
|
-
},
|
|
27
|
-
size: {
|
|
28
|
-
// Polaris button sizes: md 30px, sm 26px, lg 36px
|
|
29
|
-
default: "h-[30px] px-3 py-1",
|
|
30
|
-
sm: "h-[26px] rounded-button px-2.5 text-xs",
|
|
31
|
-
lg: "h-9 rounded-button px-4 text-sm",
|
|
32
|
-
icon: "h-[30px] w-[30px]"
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
defaultVariants: {
|
|
36
|
-
variant: "default",
|
|
37
|
-
size: "default"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
);
|
|
41
|
-
var Button = React2.forwardRef(
|
|
42
|
-
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
43
|
-
const Comp = asChild ? Slot : "button";
|
|
44
|
-
return /* @__PURE__ */ jsx(
|
|
45
|
-
Comp,
|
|
46
|
-
{
|
|
47
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
48
|
-
ref,
|
|
49
|
-
...props
|
|
50
|
-
}
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
);
|
|
54
|
-
Button.displayName = "Button";
|
|
4
|
+
// src/stores/page-header.store.ts
|
|
55
5
|
var usePageHeaderStore = create((set, get) => ({
|
|
56
6
|
slot: null,
|
|
57
7
|
owner: null,
|
|
@@ -73,7 +23,7 @@ var usePageHeaderStore = create((set, get) => ({
|
|
|
73
23
|
function useRegisterPageActions() {
|
|
74
24
|
const add = usePageHeaderStore((s) => s.addActions);
|
|
75
25
|
const remove = usePageHeaderStore((s) => s.removeActions);
|
|
76
|
-
|
|
26
|
+
React.useEffect(() => {
|
|
77
27
|
add();
|
|
78
28
|
return remove;
|
|
79
29
|
}, [add, remove]);
|
|
@@ -87,7 +37,7 @@ function usePageHeaderSlot() {
|
|
|
87
37
|
function usePageHeaderHost() {
|
|
88
38
|
const addHost = usePageHeaderStore((s) => s.addHost);
|
|
89
39
|
const removeHost = usePageHeaderStore((s) => s.removeHost);
|
|
90
|
-
|
|
40
|
+
React.useEffect(() => {
|
|
91
41
|
addHost();
|
|
92
42
|
return removeHost;
|
|
93
43
|
}, [addHost, removeHost]);
|
|
@@ -102,19 +52,19 @@ function PageHeaderOutlet({ className }) {
|
|
|
102
52
|
const slot = usePageHeaderStore((s) => s.slot);
|
|
103
53
|
const addOutlet = usePageHeaderStore((s) => s.addOutlet);
|
|
104
54
|
const removeOutlet = usePageHeaderStore((s) => s.removeOutlet);
|
|
105
|
-
|
|
55
|
+
React.useEffect(() => {
|
|
106
56
|
addOutlet();
|
|
107
57
|
return removeOutlet;
|
|
108
58
|
}, [addOutlet, removeOutlet]);
|
|
109
59
|
if (!slot) return null;
|
|
110
|
-
return
|
|
60
|
+
return React.createElement("div", { className: className ?? "mb-4" }, slot);
|
|
111
61
|
}
|
|
112
62
|
function usePageHeader(node, options) {
|
|
113
|
-
const id =
|
|
63
|
+
const id = React.useId();
|
|
114
64
|
const claim = usePageHeaderStore((s) => s.claim);
|
|
115
65
|
const release = usePageHeaderStore((s) => s.release);
|
|
116
66
|
const back = options?.back ?? false;
|
|
117
|
-
|
|
67
|
+
React.useEffect(() => {
|
|
118
68
|
if (node == null) {
|
|
119
69
|
release(id);
|
|
120
70
|
return;
|
|
@@ -137,6 +87,6 @@ var useLayoutStore = create((set) => ({
|
|
|
137
87
|
setCommandPaletteOpen: (open) => set({ commandPaletteOpen: open })
|
|
138
88
|
}));
|
|
139
89
|
|
|
140
|
-
export {
|
|
141
|
-
//# sourceMappingURL=chunk-
|
|
142
|
-
//# sourceMappingURL=chunk-
|
|
90
|
+
export { PageHeaderOutlet, useHasPageActions, useHasPageHeaderBack, useHasPageHeaderHost, useHasPageHeaderOutlet, useLayoutStore, usePageHeader, usePageHeaderHost, usePageHeaderSlot, useRegisterPageActions };
|
|
91
|
+
//# sourceMappingURL=chunk-FFJ2C5YH.js.map
|
|
92
|
+
//# sourceMappingURL=chunk-FFJ2C5YH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/stores/page-header.store.ts","../src/stores/layout.store.ts"],"names":["create"],"mappings":"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","file":"chunk-FFJ2C5YH.js","sourcesContent":["import * as React from 'react'\nimport { create } from 'zustand'\n\ninterface PageHeaderState {\n /** What the shell's top bar shows INSTEAD of the page title, or null. */\n slot: React.ReactNode | null\n /** Identity of whoever owns the slot, so a late unmount can't clear a newer\n * owner's content — the exact race you get navigating form → form. */\n owner: string | null\n /** The claimed header carries a back action, i.e. what the bar is showing is\n * a SUBPAGE (\"← Contas a Pagar / Nova\"), not the module's own screen. The\n * module's tab band reads this to step aside: a form reached from a tab is\n * not one of the tabs, and leaving the strip up marks a place the user is no\n * longer at, one line under a back link that says so. */\n hasBack: boolean\n /** How many shells are currently rendering the slot. A page needs to know:\n * with no host (minimal layout, an embedded form, a modal) its header would\n * be claimed into the void, and the page must draw it inline instead. */\n hosts: number\n /**\n * Quantos OUTLETS internos estão mostrando o slot. Um outlet é um container\n * mais fundo que a shell — a coluna de conteúdo de um módulo com trilha\n * lateral — que fica em melhor posição para desenhar o cabeçalho.\n *\n * Quando existe um, a barra da shell se cala: as duas juntas desenhariam a\n * mesma migalha duas vezes, e a da shell atravessa a largura inteira,\n * empurrando a trilha do módulo para baixo do topo.\n */\n outlets: number\n /**\n * Quantos blocos de ações de página estão montados agora. A barra precisa\n * saber ANTES de decidir se existe: ela some no celular de alguns produtos, e\n * um \"Novo\" entregue a uma barra escondida simplesmente não aparecia.\n */\n actions: number\n claim: (owner: string, node: React.ReactNode, hasBack?: boolean) => void\n release: (owner: string) => void\n addHost: () => void\n removeHost: () => void\n addOutlet: () => void\n removeOutlet: () => void\n addActions: () => void\n removeActions: () => void\n}\n\nconst usePageHeaderStore = create<PageHeaderState>((set, get) => ({\n slot: null,\n owner: null,\n hasBack: false,\n hosts: 0,\n outlets: 0,\n actions: 0,\n claim: (owner, node, hasBack = false) => set({ owner, slot: node, hasBack }),\n release: (owner) => {\n if (get().owner === owner) set({ owner: null, slot: null, hasBack: false })\n },\n addHost: () => set((s) => ({ hosts: s.hosts + 1 })),\n removeHost: () => set((s) => ({ hosts: Math.max(0, s.hosts - 1) })),\n addOutlet: () => set((s) => ({ outlets: s.outlets + 1 })),\n removeOutlet: () => set((s) => ({ outlets: Math.max(0, s.outlets - 1) })),\n addActions: () => set((s) => ({ actions: s.actions + 1 })),\n removeActions: () => set((s) => ({ actions: Math.max(0, s.actions - 1) })),\n}))\n\n/** Declara que esta página tem ações no topo. Chamado por PageHeaderActions. */\nexport function useRegisterPageActions(): void {\n const add = usePageHeaderStore((s) => s.addActions)\n const remove = usePageHeaderStore((s) => s.removeActions)\n React.useEffect(() => {\n add()\n return remove\n }, [add, remove])\n}\n\n/** Se alguma página tem ações no topo agora. A barra usa para não sumir com\n * elas no celular, e para não existir vazia. */\nexport function useHasPageActions(): boolean {\n return usePageHeaderStore((s) => s.actions > 0)\n}\n\n/** Read the current override. The shell calls this; pages should not. */\nexport function usePageHeaderSlot(): React.ReactNode | null {\n return usePageHeaderStore((s) => s.slot)\n}\n\n/**\n * Declare that this shell renders the page-header slot. Called by the layout,\n * never by a page. Without it `PageHeader` cannot tell \"nobody claimed the bar\"\n * from \"there is no bar\", and a header would vanish instead of falling back.\n */\nexport function usePageHeaderHost(): void {\n const addHost = usePageHeaderStore((s) => s.addHost)\n const removeHost = usePageHeaderStore((s) => s.removeHost)\n React.useEffect(() => {\n addHost()\n return removeHost\n }, [addHost, removeHost])\n}\n\n/** Whether any shell OR inner outlet is showing the slot right now. */\nexport function useHasPageHeaderHost(): boolean {\n return usePageHeaderStore((s) => s.hosts > 0 || s.outlets > 0)\n}\n\n/** True when a deeper container took over drawing the header. The shell bar\n * uses this to stand down. */\nexport function useHasPageHeaderOutlet(): boolean {\n return usePageHeaderStore((s) => s.outlets > 0)\n}\n\n/**\n * Desenha o cabeçalho AQUI em vez de na barra da shell.\n *\n * Para quem tem uma coluna própria de conteúdo — um módulo com trilha lateral —,\n * onde a barra da shell, larga demais, passaria por cima da trilha.\n */\nexport function PageHeaderOutlet({ className }: { className?: string }): React.ReactElement | null {\n const slot = usePageHeaderStore((s) => s.slot)\n const addOutlet = usePageHeaderStore((s) => s.addOutlet)\n const removeOutlet = usePageHeaderStore((s) => s.removeOutlet)\n\n React.useEffect(() => {\n addOutlet()\n return removeOutlet\n }, [addOutlet, removeOutlet])\n\n if (!slot) return null\n return React.createElement('div', { className: className ?? 'mb-4' }, slot)\n}\n\n/**\n * Put this page's own header — a back link, a breadcrumb — into the shell's top\n * bar, replacing the page title for as long as the page is mounted.\n *\n * Prefer the `PageHeader` component: it is this hook plus the one agreed layout\n * (← + title), so every screen in every app reads the same. Reach for the hook\n * directly only for a header that genuinely is not \"back + title\".\n *\n * A form or detail screen already says where it is (\"← Novo produto\") and the\n * bar above it was saying \"Produtos\" again, one line up. Two headers stacked is\n * a whole row of vertical space spent repeating a word.\n *\n * The node is re-claimed on every change so a breadcrumb whose label depends on\n * loaded data (a record's name) updates once it arrives.\n */\nexport function usePageHeader(node: React.ReactNode | null, options?: { back?: boolean }): void {\n const id = React.useId()\n const claim = usePageHeaderStore((s) => s.claim)\n const release = usePageHeaderStore((s) => s.release)\n const back = options?.back ?? false\n\n React.useEffect(() => {\n if (node == null) {\n release(id)\n return\n }\n claim(id, node, back)\n return () => release(id)\n }, [id, node, back, claim, release])\n}\n\n/** True while the bar is showing a subpage's \"← parent / title\". See\n * `PageHeaderState.hasBack`. */\nexport function useHasPageHeaderBack(): boolean {\n return usePageHeaderStore((s) => s.hasBack)\n}\n\nexport { usePageHeaderStore }\n","import { create } from 'zustand'\n\ninterface LayoutState {\n sidebarOpen: boolean\n sidebarCollapsed: boolean\n mobileDrawerOpen: boolean\n commandPaletteOpen: boolean\n toggleSidebar: () => void\n setSidebarCollapsed: (collapsed: boolean) => void\n toggleMobileDrawer: () => void\n setCommandPaletteOpen: (open: boolean) => void\n}\n\nexport const useLayoutStore = create<LayoutState>((set) => ({\n sidebarOpen: true,\n sidebarCollapsed: false,\n mobileDrawerOpen: false,\n commandPaletteOpen: false,\n\n toggleSidebar: () =>\n set((state) => ({ sidebarOpen: !state.sidebarOpen })),\n\n setSidebarCollapsed: (collapsed) =>\n set({ sidebarCollapsed: collapsed }),\n\n toggleMobileDrawer: () =>\n set((state) => ({ mobileDrawerOpen: !state.mobileDrawerOpen })),\n\n setCommandPaletteOpen: (open) =>\n set({ commandPaletteOpen: open }),\n}))\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetBody } from './chunk-
|
|
2
|
-
import { cn, Button } from './chunk-
|
|
1
|
+
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetBody } from './chunk-NA3GE4H3.js';
|
|
2
|
+
import { cn, Button } from './chunk-OKZ6WQB3.js';
|
|
3
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import { PanelRightOpen, PanelRightClose, PanelRight } from 'lucide-react';
|
|
@@ -148,5 +148,5 @@ function ContentSplitTrigger({ label, iconOnly, className }) {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
export { AppShellSkeleton, ContentSplit, ContentSplitTrigger, PageTrail, navigateToCrumb, usePageTrail, usePageTrailParent };
|
|
151
|
-
//# sourceMappingURL=chunk-
|
|
152
|
-
//# sourceMappingURL=chunk-
|
|
151
|
+
//# sourceMappingURL=chunk-J7F3Z52K.js.map
|
|
152
|
+
//# sourceMappingURL=chunk-J7F3Z52K.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/layout/AppShellSkeleton.tsx","../src/layout/page-trail.tsx","../src/layout/ContentSplit.tsx"],"names":["jsx","React2","jsxs"],"mappings":";;;;;;AAqCO,SAAS,WAAA,CAAY,EAAE,SAAA,EAAU,EAA2B;AACjE,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,aAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,EAAA;AAAA,QACT,8FAAA;AAAA,QACA,6FAAA;AAAA,QACA;AAAA;AACF;AAAA,GACF;AAEJ;AAEO,SAAS,gBAAA,CAAiB,EAAE,KAAA,EAAO,SAAA,EAAU,EAA0B;AAC5E,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,WAAA,EAAU,MAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,yEAAA,EAA2E,SAAS,CAAA;AAAA,MAElG,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAW,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,4BAChC,WAAA,EAAA,EAAY;AAAA;AAAA;AAAA,GACf;AAEJ;AACA,gBAAA,CAAiB,WAAA,GAAc,kBAAA;ACjC/B,IAAM,QAA0B,EAAC;AACjC,IAAM,gBAAA,GAAyB,oBAAgC,KAAK,CAAA;AAG7D,SAAS,SAAA,CAAU;AAAA,EACxB,KAAA;AAAA,EACA,IAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA,EAAmD;AACjD,EAAA,MAAM,MAAA,GAAe,iBAAW,gBAAgB,CAAA;AAGhD,EAAA,MAAM,KAAA,GAAc,KAAA,CAAA,OAAA;AAAA,IAClB,MAAM,CAAC,GAAG,MAAA,EAAQ,EAAE,KAAA,EAAO,IAAA,EAAM,YAAY,CAAA;AAAA,IAC7C,CAAC,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,UAAU;AAAA,GAClC;AACA,EAAA,uBAAOA,GAAAA,CAAC,gBAAA,CAAiB,UAAjB,EAA0B,KAAA,EAAO,OAAQ,QAAA,EAAS,CAAA;AAC5D;AAEO,SAAS,YAAA,GAAiC;AAC/C,EAAA,OAAa,iBAAW,gBAAgB,CAAA;AAC1C;AAMO,SAAS,mBAAmB,IAAA,EAA2C;AAC5E,EAAA,MAAM,KAAA,GAAc,iBAAW,gBAAgB,CAAA;AAC/C,EAAA,OAAa,cAAQ,MAAM;AACzB,IAAA,MAAM,KAAA,GAAQ,OAAO,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,IAAI,CAAA,GAAI,KAAA;AAC5D,IAAA,OAAO,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AAAA,EAC/B,CAAA,EAAG,CAAC,KAAA,EAAO,IAAI,CAAC,CAAA;AAClB;AAEO,SAAS,gBAAgB,KAAA,EAA6B;AAC3D,EAAA,IAAI,KAAA,CAAM,UAAA,EAAY,KAAA,CAAM,UAAA,EAAW;AAAA,OAClC,MAAA,CAAO,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,IAAA;AACpC;AC3CA,IAAM,mBAAA,GAA4BC,oBAA+C,IAAI,CAAA;AAuB9E,SAAS,YAAA,CAAa;AAAA,EAC3B,QAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,gBAAA;AAAA,EACA,UAAA,GAAa,OAAA;AAAA,EACb,SAAA;AAAA,EACA,iBAAA;AAAA,EACA,WAAA,GAAc,KAAA;AAAA,EACd,gBAAA,GAAmB,KAAA;AAAA,EACnB;AACF,CAAA,EAAsB;AACpB,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAUA,eAAS,KAAK,CAAA;AAC5D,EAAA,MAAM,OAAO,SAAA,IAAa,YAAA;AAC1B,EAAA,MAAM,UAAU,iBAAA,IAAqB,eAAA;AACrC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAUA,KAAA,CAAA,QAAA,CAAS,eAAe,gBAAgB,CAAA;AAEhF,EAAA,uBACEC,KAAC,mBAAA,CAAoB,QAAA,EAApB,EAA6B,KAAA,EAAO,EAAE,IAAA,EAAM,OAAA,EAAQ,EACnD,QAAA,EAAA;AAAA,oBAAAA,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA,CAAG,iCAAA,EAAmC,SAAS,CAAA;AAAA,QAC1D,OAAO,EAAE,mBAAA,EAAqB,kBAAkB,SAAA,GAAY,MAAA,GAAS,UAAU,CAAA,CAAA,EAAG;AAAA,QAElF,QAAA,EAAA;AAAA,0BAAAF,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,SAAA,EAAW,QAAA,EAAS,CAAA;AAAA,0BAGnCA,GAAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,oCAAA,EACd,sCACCA,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,SAAA;AAAA,cACR,IAAA,EAAK,IAAA;AAAA,cACL,OAAA,EAAS,MAAM,YAAA,CAAa,KAAK,CAAA;AAAA,cACjC,SAAA,EAAU,aAAA;AAAA,cACV,YAAA,EAAY,OAAO,UAAA,KAAe,QAAA,GAAW,UAAA,GAAa,MAAA;AAAA,cAC1D,KAAA,EAAO,OAAO,UAAA,KAAe,QAAA,GAAW,UAAA,GAAa,MAAA;AAAA,cAErD,QAAA,kBAAAA,GAAAA,CAAC,cAAA,EAAA,EAAe,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA,WACtC,mBAEAE,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2CAAA,EACb,QAAA,EAAA;AAAA,4BAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yEAAA,EACb,QAAA,EAAA;AAAA,8BAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,SAAA,EACb,QAAA,EAAA;AAAA,gCAAAF,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,uCAAA,EAAyC,QAAA,EAAA,UAAA,EAAW,CAAA;AAAA,gBAChE,oCACCA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,wCAAwC,QAAA,EAAA,gBAAA,EAAiB;AAAA,eAAA,EAE1E,CAAA;AAAA,cACC,+BACCA,GAAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,IAAA,EAAK,QAAA;AAAA,kBACL,OAAA,EAAS,MAAM,YAAA,CAAa,IAAI,CAAA;AAAA,kBAChC,SAAA,EAAU,6FAAA;AAAA,kBACV,YAAA,EAAW,UAAA;AAAA,kBAEX,QAAA,kBAAAA,GAAAA,CAAC,eAAA,EAAA,EAAgB,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA;AACvC,aAAA,EAEJ,CAAA;AAAA,4BACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,OAAO,QAAA,EAAA,KAAA,EAAM;AAAA,WAAA,EAC9B,CAAA,EAEJ;AAAA;AAAA;AAAA,KACF;AAAA,oBAGAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aACb,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAY,cAAc,OAAA,EAC/B,QAAA,kBAAAE,IAAAA,CAAC,YAAA,EAAA,EAAa,OAAM,UAAA,EAClB,QAAA,EAAA;AAAA,sBAAAA,KAAC,WAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAAF,GAAAA,CAAC,cAAY,QAAA,EAAA,UAAA,EAAW,CAAA;AAAA,QACvB,gBAAA,oBAAoBA,GAAAA,CAAC,gBAAA,EAAA,EAAkB,QAAA,EAAA,gBAAA,EAAiB;AAAA,OAAA,EAC3D,CAAA;AAAA,sBACAA,GAAAA,CAAC,SAAA,EAAA,EAAW,QAAA,EAAA,KAAA,EAAM;AAAA,KAAA,EACpB,GACF,CAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;AAWO,SAAS,mBAAA,CAAoB,EAAE,KAAA,EAAO,QAAA,EAAU,WAAU,EAA6B;AAC5F,EAAA,MAAM,GAAA,GAAYC,iBAAW,mBAAmB,CAAA;AAChD,EAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,EAAA,uBACEC,IAAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,SAAA;AAAA,MACR,IAAA,EAAK,IAAA;AAAA,MACL,OAAA,EAAS,MAAM,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA;AAAA,MAC/B,SAAA,EAAW,EAAA,CAAG,WAAA,EAAa,SAAS,CAAA;AAAA,MACpC,YAAA,EAAY,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,MAAA;AAAA,MAEhD,QAAA,EAAA;AAAA,wBAAAF,GAAAA,CAAC,cAAW,SAAA,EAAW,EAAA,CAAG,WAAW,CAAC,QAAA,IAAY,QAAQ,CAAA,EAAG,CAAA;AAAA,QAC5D,CAAC,QAAA,IAAY;AAAA;AAAA;AAAA,GAChB;AAEJ","file":"chunk-5KAGNW45.js","sourcesContent":["import * as React from 'react'\nimport { cn } from '../lib/cn'\n\n// ---------------------------------------------------------------------------\n// AppShellSkeleton — what the admin shows while it is still booting (session\n// restore, plugin runtime, first paint).\n//\n// It used to draw the SHAPE of the shell: rail, header band, tiles, table. The\n// idea was that the app would resolve into its own outline. What it did in\n// practice was promise a specific screen and then contradict it — the outline\n// is a dashboard, and half the time you were opening something else — and the\n// pulsing bars read as content that failed to load rather than content on its\n// way. Worse, it made the wait look LONGER: a page of fake rows holds the eye,\n// so every extra frame of it registers.\n//\n// One spinner on the rail's own color says exactly as much (the app is coming)\n// and nothing false. It also matches the HTML boot screen the Vite plugin\n// injects (see @fayz-ai/sdk boot-skeleton), so the whole cold load is one\n// continuous image — same background, same spinner, in the same place — from\n// first paint to mounted app, with nothing swapping underneath.\n// ---------------------------------------------------------------------------\n\nexport interface AppShellSkeletonProps {\n /** Kept for API compatibility. The boot screen no longer draws a shell shape,\n * so every layout gets the same one. */\n variant?: 'sidebar' | 'topbar' | 'minimal'\n /** Kept for API compatibility; the boot screen has no content frame. */\n contentFrame?: boolean\n /** Kept for API compatibility; the boot screen shows no logo. */\n logo?: React.ReactNode\n /** What is loading, for screen readers. */\n label: string\n className?: string\n}\n\n/** Ring spinner in the page's foreground tone. Static under reduced motion —\n * the ring alone still reads as \"busy\", a frozen spinner reads as \"stuck\". */\nexport function BootSpinner({ className }: { className?: string }) {\n return (\n <span\n aria-hidden\n className={cn(\n 'block h-7 w-7 animate-spin rounded-full border-2 border-foreground/20 border-t-foreground/70',\n 'motion-reduce:animate-none motion-reduce:border-t-foreground/20 motion-reduce:animate-pulse',\n className,\n )}\n />\n )\n}\n\nexport function AppShellSkeleton({ label, className }: AppShellSkeletonProps) {\n return (\n <div\n role=\"status\"\n aria-busy=\"true\"\n className={cn('flex h-screen items-center justify-center overflow-hidden bg-background', className)}\n >\n <span className=\"sr-only\">{label}</span>\n <BootSpinner />\n </div>\n )\n}\nAppShellSkeleton.displayName = 'AppShellSkeleton'\n","import * as React from 'react'\n\n// ---------------------------------------------------------------------------\n// PageTrail — quem é o PAI da tela que está desenhando agora.\n//\n// Uma migalha (\"← Entrega / Embalagens\") precisa de duas coisas que moram em\n// lugares diferentes: o nome do nível de cima, que só o container sabe, e o\n// nome do nível atual, que só a folha sabe. Sem um caminho entre os dois cada\n// container desenhava a própria seta \"para não perder o caminho de volta\" — e\n// foi assim que Configurações ficou com dois cabeçalhos empilhados: um da\n// barra da shell (\"Configurações\") e um escrito à mão dentro do plugin\n// (\"← Entrega\"), desalinhados, para uma coisa só.\n//\n// Aqui o container apenas DECLARA o nível dele. Quem desenha é sempre a folha,\n// uma vez só, pelo mesmo PageHeader que o resto do app usa — uma seta na tela,\n// nunca duas.\n// ---------------------------------------------------------------------------\n\nexport interface PageTrailCrumb {\n /** Nome do nível — a palavra antes da barra para quem vem abaixo. */\n label: string\n /** Rota (hash) deste nível. É também a IDENTIDADE dele: uma tela cuja rota é\n * igual à do nível não é filha dele, é ele — sem isso a lista de Locais,\n * que É a aba, viraria \"← Locais / Locais\". */\n href: string\n /** Como voltar. Sem isso, a própria rota. */\n onNavigate?: () => void\n}\n\nconst EMPTY: PageTrailCrumb[] = []\nconst PageTrailContext = React.createContext<PageTrailCrumb[]>(EMPTY)\n\n/** Declara um nível para tudo que renderizar abaixo. */\nexport function PageTrail({\n label,\n href,\n onNavigate,\n children,\n}: PageTrailCrumb & { children: React.ReactNode }) {\n const parent = React.useContext(PageTrailContext)\n // Identidade estável: a folha memoiza o nó do cabeçalho a partir daqui, e um\n // array novo a cada render faria a reivindicação da barra recomeçar sem fim.\n const trail = React.useMemo(\n () => [...parent, { label, href, onNavigate }],\n [parent, label, href, onNavigate],\n )\n return <PageTrailContext.Provider value={trail}>{children}</PageTrailContext.Provider>\n}\n\nexport function usePageTrail(): PageTrailCrumb[] {\n return React.useContext(PageTrailContext)\n}\n\n/**\n * O nível imediatamente acima de `href`, ou undefined quando não há trilha —\n * fora de Configurações a página segue sem migalha, como sempre foi.\n */\nexport function usePageTrailParent(href?: string): PageTrailCrumb | undefined {\n const trail = React.useContext(PageTrailContext)\n return React.useMemo(() => {\n const above = href ? trail.filter((c) => c.href !== href) : trail\n return above[above.length - 1]\n }, [trail, href])\n}\n\nexport function navigateToCrumb(crumb: PageTrailCrumb): void {\n if (crumb.onNavigate) crumb.onNavigate()\n else window.location.hash = crumb.href\n}\n","import * as React from 'react'\nimport { PanelRight, PanelRightClose, PanelRightOpen } from 'lucide-react'\nimport { cn } from '../lib/cn'\nimport { Button } from '../primitives/button'\nimport {\n Sheet, SheetContent, SheetHeader, SheetBody, SheetTitle, SheetDescription,\n} from '../primitives/sheet'\n\n// ---------------------------------------------------------------------------\n// ContentSplit — main content with a right-aligned companion panel, mobile\n// first. Below `lg` the aside lives in a right Sheet (opened by a trigger the\n// host places wherever fits — typically SubpageHeader actions, via\n// <ContentSplitTrigger/>). From `lg` up it docks as a sticky right column.\n//\n// Pairs with SubpageHeader/ModulePage: the page keeps its own back-button\n// header; ContentSplit only owns the columns below it. Reuse for any\n// \"document + operational panel\" page (script + shooting checklist, form +\n// help, detail + activity feed).\n// ---------------------------------------------------------------------------\n\ninterface ContentSplitContextValue {\n open: boolean\n setOpen: (open: boolean) => void\n}\n\nconst ContentSplitContext = React.createContext<ContentSplitContextValue | null>(null)\n\nexport interface ContentSplitProps {\n /** Main column (the document). */\n children: React.ReactNode\n /** Companion panel content (the checklist / help / activity). */\n aside: React.ReactNode\n /** Panel title — Sheet header on mobile, card header on desktop. */\n asideTitle: React.ReactNode\n /** Optional subtitle under the title. */\n asideDescription?: React.ReactNode\n /** Desktop column width (defaults to 20rem). */\n asideWidth?: string\n /** Controlled mobile-sheet state; uncontrolled when omitted. */\n asideOpen?: boolean\n onAsideOpenChange?: (open: boolean) => void\n /** Desktop column can collapse into a slim reopen rail. */\n collapsible?: boolean\n /** Initial desktop collapsed state (e.g. expand only on the relevant day). */\n defaultCollapsed?: boolean\n className?: string\n}\n\nexport function ContentSplit({\n children,\n aside,\n asideTitle,\n asideDescription,\n asideWidth = '20rem',\n asideOpen,\n onAsideOpenChange,\n collapsible = false,\n defaultCollapsed = false,\n className,\n}: ContentSplitProps) {\n const [internalOpen, setInternalOpen] = React.useState(false)\n const open = asideOpen ?? internalOpen\n const setOpen = onAsideOpenChange ?? setInternalOpen\n const [collapsed, setCollapsed] = React.useState(collapsible && defaultCollapsed)\n\n return (\n <ContentSplitContext.Provider value={{ open, setOpen }}>\n <div\n className={cn('lg:grid lg:items-start lg:gap-6', className)}\n style={{ gridTemplateColumns: `minmax(0, 1fr) ${collapsed ? 'auto' : asideWidth}` }}\n >\n <div className=\"min-w-0\">{children}</div>\n\n {/* Desktop: docked sticky column (or slim reopen rail when collapsed) */}\n <aside className=\"hidden lg:block lg:sticky lg:top-4\">\n {collapsed ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setCollapsed(false)}\n className=\"h-9 w-9 p-0\"\n aria-label={typeof asideTitle === 'string' ? asideTitle : undefined}\n title={typeof asideTitle === 'string' ? asideTitle : undefined}\n >\n <PanelRightOpen className=\"h-4 w-4\" />\n </Button>\n ) : (\n <div className=\"rounded-card border border-border bg-card\">\n <div className=\"flex items-start justify-between gap-2 border-b border-border px-4 py-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold text-foreground\">{asideTitle}</p>\n {asideDescription && (\n <p className=\"mt-0.5 text-xs text-muted-foreground\">{asideDescription}</p>\n )}\n </div>\n {collapsible && (\n <button\n type=\"button\"\n onClick={() => setCollapsed(true)}\n className=\"rounded p-1 text-muted-foreground transition-colors hover:bg-muted/60 hover:text-foreground\"\n aria-label=\"collapse\"\n >\n <PanelRightClose className=\"h-4 w-4\" />\n </button>\n )}\n </div>\n <div className=\"p-4\">{aside}</div>\n </div>\n )}\n </aside>\n </div>\n\n {/* Mobile: right sheet */}\n <div className=\"lg:hidden\">\n <Sheet open={open} onOpenChange={setOpen}>\n <SheetContent width=\"max-w-sm\">\n <SheetHeader>\n <SheetTitle>{asideTitle}</SheetTitle>\n {asideDescription && <SheetDescription>{asideDescription}</SheetDescription>}\n </SheetHeader>\n <SheetBody>{aside}</SheetBody>\n </SheetContent>\n </Sheet>\n </div>\n </ContentSplitContext.Provider>\n )\n}\n\nexport interface ContentSplitTriggerProps {\n /** Accessible label; also the visible text unless `iconOnly`. */\n label: React.ReactNode\n iconOnly?: boolean\n className?: string\n}\n\n/** Opens the mobile aside sheet. Renders nothing from `lg` up (the panel is\n * already docked). Place inside SubpageHeader `actions` or any toolbar. */\nexport function ContentSplitTrigger({ label, iconOnly, className }: ContentSplitTriggerProps) {\n const ctx = React.useContext(ContentSplitContext)\n if (!ctx) return null\n return (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => ctx.setOpen(true)}\n className={cn('lg:hidden', className)}\n aria-label={typeof label === 'string' ? label : undefined}\n >\n <PanelRight className={cn('h-4 w-4', !iconOnly && 'mr-1.5')} />\n {!iconOnly && label}\n </Button>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/layout/AppShellSkeleton.tsx","../src/layout/page-trail.tsx","../src/layout/ContentSplit.tsx"],"names":["jsx","React2","jsxs"],"mappings":"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","file":"chunk-J7F3Z52K.js","sourcesContent":["import * as React from 'react'\nimport { cn } from '../lib/cn'\n\n// ---------------------------------------------------------------------------\n// AppShellSkeleton — what the admin shows while it is still booting (session\n// restore, plugin runtime, first paint).\n//\n// It used to draw the SHAPE of the shell: rail, header band, tiles, table. The\n// idea was that the app would resolve into its own outline. What it did in\n// practice was promise a specific screen and then contradict it — the outline\n// is a dashboard, and half the time you were opening something else — and the\n// pulsing bars read as content that failed to load rather than content on its\n// way. Worse, it made the wait look LONGER: a page of fake rows holds the eye,\n// so every extra frame of it registers.\n//\n// One spinner on the rail's own color says exactly as much (the app is coming)\n// and nothing false. It also matches the HTML boot screen the Vite plugin\n// injects (see @fayz-ai/sdk boot-skeleton), so the whole cold load is one\n// continuous image — same background, same spinner, in the same place — from\n// first paint to mounted app, with nothing swapping underneath.\n// ---------------------------------------------------------------------------\n\nexport interface AppShellSkeletonProps {\n /** Kept for API compatibility. The boot screen no longer draws a shell shape,\n * so every layout gets the same one. */\n variant?: 'sidebar' | 'topbar' | 'minimal'\n /** Kept for API compatibility; the boot screen has no content frame. */\n contentFrame?: boolean\n /** Kept for API compatibility; the boot screen shows no logo. */\n logo?: React.ReactNode\n /** What is loading, for screen readers. */\n label: string\n className?: string\n}\n\n/** Ring spinner in the page's foreground tone. Static under reduced motion —\n * the ring alone still reads as \"busy\", a frozen spinner reads as \"stuck\". */\nexport function BootSpinner({ className }: { className?: string }) {\n return (\n <span\n aria-hidden\n className={cn(\n 'block h-7 w-7 animate-spin rounded-full border-2 border-foreground/20 border-t-foreground/70',\n 'motion-reduce:animate-none motion-reduce:border-t-foreground/20 motion-reduce:animate-pulse',\n className,\n )}\n />\n )\n}\n\nexport function AppShellSkeleton({ label, className }: AppShellSkeletonProps) {\n return (\n <div\n role=\"status\"\n aria-busy=\"true\"\n className={cn('flex h-screen items-center justify-center overflow-hidden bg-background', className)}\n >\n <span className=\"sr-only\">{label}</span>\n <BootSpinner />\n </div>\n )\n}\nAppShellSkeleton.displayName = 'AppShellSkeleton'\n","import * as React from 'react'\n\n// ---------------------------------------------------------------------------\n// PageTrail — quem é o PAI da tela que está desenhando agora.\n//\n// Uma migalha (\"← Entrega / Embalagens\") precisa de duas coisas que moram em\n// lugares diferentes: o nome do nível de cima, que só o container sabe, e o\n// nome do nível atual, que só a folha sabe. Sem um caminho entre os dois cada\n// container desenhava a própria seta \"para não perder o caminho de volta\" — e\n// foi assim que Configurações ficou com dois cabeçalhos empilhados: um da\n// barra da shell (\"Configurações\") e um escrito à mão dentro do plugin\n// (\"← Entrega\"), desalinhados, para uma coisa só.\n//\n// Aqui o container apenas DECLARA o nível dele. Quem desenha é sempre a folha,\n// uma vez só, pelo mesmo PageHeader que o resto do app usa — uma seta na tela,\n// nunca duas.\n// ---------------------------------------------------------------------------\n\nexport interface PageTrailCrumb {\n /** Nome do nível — a palavra antes da barra para quem vem abaixo. */\n label: string\n /** Rota (hash) deste nível. É também a IDENTIDADE dele: uma tela cuja rota é\n * igual à do nível não é filha dele, é ele — sem isso a lista de Locais,\n * que É a aba, viraria \"← Locais / Locais\". */\n href: string\n /** Como voltar. Sem isso, a própria rota. */\n onNavigate?: () => void\n}\n\nconst EMPTY: PageTrailCrumb[] = []\nconst PageTrailContext = React.createContext<PageTrailCrumb[]>(EMPTY)\n\n/** Declara um nível para tudo que renderizar abaixo. */\nexport function PageTrail({\n label,\n href,\n onNavigate,\n children,\n}: PageTrailCrumb & { children: React.ReactNode }) {\n const parent = React.useContext(PageTrailContext)\n // Identidade estável: a folha memoiza o nó do cabeçalho a partir daqui, e um\n // array novo a cada render faria a reivindicação da barra recomeçar sem fim.\n const trail = React.useMemo(\n () => [...parent, { label, href, onNavigate }],\n [parent, label, href, onNavigate],\n )\n return <PageTrailContext.Provider value={trail}>{children}</PageTrailContext.Provider>\n}\n\nexport function usePageTrail(): PageTrailCrumb[] {\n return React.useContext(PageTrailContext)\n}\n\n/**\n * O nível imediatamente acima de `href`, ou undefined quando não há trilha —\n * fora de Configurações a página segue sem migalha, como sempre foi.\n */\nexport function usePageTrailParent(href?: string): PageTrailCrumb | undefined {\n const trail = React.useContext(PageTrailContext)\n return React.useMemo(() => {\n const above = href ? trail.filter((c) => c.href !== href) : trail\n return above[above.length - 1]\n }, [trail, href])\n}\n\nexport function navigateToCrumb(crumb: PageTrailCrumb): void {\n if (crumb.onNavigate) crumb.onNavigate()\n else window.location.hash = crumb.href\n}\n","import * as React from 'react'\nimport { PanelRight, PanelRightClose, PanelRightOpen } from 'lucide-react'\nimport { cn } from '../lib/cn'\nimport { Button } from '../primitives/button'\nimport {\n Sheet, SheetContent, SheetHeader, SheetBody, SheetTitle, SheetDescription,\n} from '../primitives/sheet'\n\n// ---------------------------------------------------------------------------\n// ContentSplit — main content with a right-aligned companion panel, mobile\n// first. Below `lg` the aside lives in a right Sheet (opened by a trigger the\n// host places wherever fits — typically SubpageHeader actions, via\n// <ContentSplitTrigger/>). From `lg` up it docks as a sticky right column.\n//\n// Pairs with SubpageHeader/ModulePage: the page keeps its own back-button\n// header; ContentSplit only owns the columns below it. Reuse for any\n// \"document + operational panel\" page (script + shooting checklist, form +\n// help, detail + activity feed).\n// ---------------------------------------------------------------------------\n\ninterface ContentSplitContextValue {\n open: boolean\n setOpen: (open: boolean) => void\n}\n\nconst ContentSplitContext = React.createContext<ContentSplitContextValue | null>(null)\n\nexport interface ContentSplitProps {\n /** Main column (the document). */\n children: React.ReactNode\n /** Companion panel content (the checklist / help / activity). */\n aside: React.ReactNode\n /** Panel title — Sheet header on mobile, card header on desktop. */\n asideTitle: React.ReactNode\n /** Optional subtitle under the title. */\n asideDescription?: React.ReactNode\n /** Desktop column width (defaults to 20rem). */\n asideWidth?: string\n /** Controlled mobile-sheet state; uncontrolled when omitted. */\n asideOpen?: boolean\n onAsideOpenChange?: (open: boolean) => void\n /** Desktop column can collapse into a slim reopen rail. */\n collapsible?: boolean\n /** Initial desktop collapsed state (e.g. expand only on the relevant day). */\n defaultCollapsed?: boolean\n className?: string\n}\n\nexport function ContentSplit({\n children,\n aside,\n asideTitle,\n asideDescription,\n asideWidth = '20rem',\n asideOpen,\n onAsideOpenChange,\n collapsible = false,\n defaultCollapsed = false,\n className,\n}: ContentSplitProps) {\n const [internalOpen, setInternalOpen] = React.useState(false)\n const open = asideOpen ?? internalOpen\n const setOpen = onAsideOpenChange ?? setInternalOpen\n const [collapsed, setCollapsed] = React.useState(collapsible && defaultCollapsed)\n\n return (\n <ContentSplitContext.Provider value={{ open, setOpen }}>\n <div\n className={cn('lg:grid lg:items-start lg:gap-6', className)}\n style={{ gridTemplateColumns: `minmax(0, 1fr) ${collapsed ? 'auto' : asideWidth}` }}\n >\n <div className=\"min-w-0\">{children}</div>\n\n {/* Desktop: docked sticky column (or slim reopen rail when collapsed) */}\n <aside className=\"hidden lg:block lg:sticky lg:top-4\">\n {collapsed ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setCollapsed(false)}\n className=\"h-9 w-9 p-0\"\n aria-label={typeof asideTitle === 'string' ? asideTitle : undefined}\n title={typeof asideTitle === 'string' ? asideTitle : undefined}\n >\n <PanelRightOpen className=\"h-4 w-4\" />\n </Button>\n ) : (\n <div className=\"rounded-card border border-border bg-card\">\n <div className=\"flex items-start justify-between gap-2 border-b border-border px-4 py-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold text-foreground\">{asideTitle}</p>\n {asideDescription && (\n <p className=\"mt-0.5 text-xs text-muted-foreground\">{asideDescription}</p>\n )}\n </div>\n {collapsible && (\n <button\n type=\"button\"\n onClick={() => setCollapsed(true)}\n className=\"rounded p-1 text-muted-foreground transition-colors hover:bg-muted/60 hover:text-foreground\"\n aria-label=\"collapse\"\n >\n <PanelRightClose className=\"h-4 w-4\" />\n </button>\n )}\n </div>\n <div className=\"p-4\">{aside}</div>\n </div>\n )}\n </aside>\n </div>\n\n {/* Mobile: right sheet */}\n <div className=\"lg:hidden\">\n <Sheet open={open} onOpenChange={setOpen}>\n <SheetContent width=\"max-w-sm\">\n <SheetHeader>\n <SheetTitle>{asideTitle}</SheetTitle>\n {asideDescription && <SheetDescription>{asideDescription}</SheetDescription>}\n </SheetHeader>\n <SheetBody>{aside}</SheetBody>\n </SheetContent>\n </Sheet>\n </div>\n </ContentSplitContext.Provider>\n )\n}\n\nexport interface ContentSplitTriggerProps {\n /** Accessible label; also the visible text unless `iconOnly`. */\n label: React.ReactNode\n iconOnly?: boolean\n className?: string\n}\n\n/** Opens the mobile aside sheet. Renders nothing from `lg` up (the panel is\n * already docked). Place inside SubpageHeader `actions` or any toolbar. */\nexport function ContentSplitTrigger({ label, iconOnly, className }: ContentSplitTriggerProps) {\n const ctx = React.useContext(ContentSplitContext)\n if (!ctx) return null\n return (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => ctx.setOpen(true)}\n className={cn('lg:hidden', className)}\n aria-label={typeof label === 'string' ? label : undefined}\n >\n <PanelRight className={cn('h-4 w-4', !iconOnly && 'mr-1.5')} />\n {!iconOnly && label}\n </Button>\n )\n}\n"]}
|