@k2b/ui 0.46.0 → 0.47.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.
Files changed (54) hide show
  1. package/dist/browser/chat/ChatDecision.js +10 -6
  2. package/dist/browser/chat/ChatDecision.js.map +1 -1
  3. package/dist/browser/content/VirtualFeed.js +26 -21
  4. package/dist/browser/content/VirtualFeed.js.map +1 -1
  5. package/dist/browser/inputs/Combobox.js +14 -6
  6. package/dist/browser/inputs/Combobox.js.map +1 -1
  7. package/dist/browser/layout/AnchoredPopover.js +2 -1
  8. package/dist/browser/layout/AnchoredPopover.js.map +1 -1
  9. package/dist/browser/layout/AppWorkspace.js +340 -440
  10. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  11. package/dist/browser/layout/AppWorkspaceSidebarItemStatus.js +113 -0
  12. package/dist/browser/layout/AppWorkspaceSidebarItemStatus.js.map +1 -0
  13. package/dist/browser/layout/DetailPanel.js +1 -1
  14. package/dist/browser/layout/DetailPanel.js.map +1 -1
  15. package/dist/browser/layout/DetailSections.js +236 -132
  16. package/dist/browser/layout/DetailSections.js.map +1 -1
  17. package/dist/browser/layout/MobileShell.js +30 -13
  18. package/dist/browser/layout/MobileShell.js.map +1 -1
  19. package/dist/browser/layout/detail-sections-messages.js +4 -0
  20. package/dist/browser/layout/detail-sections-messages.js.map +1 -1
  21. package/dist/browser/layout/index.js +1 -0
  22. package/dist/browser/layout/index.js.map +1 -1
  23. package/dist/ssr/chat/ChatDecision.js +10 -6
  24. package/dist/ssr/chat/ChatDecision.js.map +1 -1
  25. package/dist/ssr/content/VirtualFeed.js +26 -21
  26. package/dist/ssr/content/VirtualFeed.js.map +1 -1
  27. package/dist/ssr/inputs/Combobox.js +6 -3
  28. package/dist/ssr/inputs/Combobox.js.map +1 -1
  29. package/dist/ssr/layout/AnchoredPopover.js +2 -1
  30. package/dist/ssr/layout/AnchoredPopover.js.map +1 -1
  31. package/dist/ssr/layout/AppWorkspace.js +61 -127
  32. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  33. package/dist/ssr/layout/AppWorkspaceSidebarItemStatus.js +76 -0
  34. package/dist/ssr/layout/AppWorkspaceSidebarItemStatus.js.map +1 -0
  35. package/dist/ssr/layout/DetailPanel.js +1 -1
  36. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  37. package/dist/ssr/layout/DetailSections.js +126 -50
  38. package/dist/ssr/layout/DetailSections.js.map +1 -1
  39. package/dist/ssr/layout/MobileShell.js +16 -2
  40. package/dist/ssr/layout/MobileShell.js.map +1 -1
  41. package/dist/ssr/layout/detail-sections-messages.js +4 -0
  42. package/dist/ssr/layout/detail-sections-messages.js.map +1 -1
  43. package/dist/ssr/layout/index.js +1 -0
  44. package/dist/ssr/layout/index.js.map +1 -1
  45. package/dist/styles.css +1 -1
  46. package/dist/types/chat/ChatDecision.d.ts +5 -0
  47. package/dist/types/inputs/Combobox.d.ts +2 -0
  48. package/dist/types/layout/AppWorkspace.d.ts +2 -28
  49. package/dist/types/layout/AppWorkspaceSidebarItemStatus.d.ts +30 -0
  50. package/dist/types/layout/DetailSections.d.ts +32 -2
  51. package/dist/types/layout/MobileShell.d.ts +12 -0
  52. package/dist/types/layout/detail-sections-messages.d.ts +2 -0
  53. package/dist/types/layout/index.d.ts +1 -0
  54. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["layout/DetailSections.tsx"],"sourcesContent":["import { createMemo, createSignal, For, type JSX, onCleanup, Show } from \"solid-js\";\nimport { Button } from \"../actions/Button\";\nimport { Avatar, type AvatarShape } from \"../surfaces/Avatar\";\nimport { AvatarStack, type AvatarStackPerson } from \"../surfaces/AvatarStack\";\nimport { personColor } from \"../surfaces/person-color\";\nimport DetailPanel from \"./DetailPanel\";\nimport { useDetailPanelMessages } from \"./detail-panel-messages\";\nimport { useDetailSectionMessages } from \"./detail-sections-messages\";\n\n/*\n * Shared sections of an object's detail panel. Each one is a `DetailPanel.Section` with its icon, title, and count, so\n * its content starts on the title's text edge, and each keeps its height while its data changes. Apps pass data; the\n * order of sections is a convention (see the DetailPanel UI context).\n */\n\nconst listNames = (names: readonly string[], and: string): string =>\n names.length <= 1 ? (names[0] ?? \"\") : `${names.slice(0, -1).join(\", \")} ${and} ${names.at(-1)}`;\n\n// ── Presence ────────────────────────────────────────────────────────────\n\nexport type DetailPresencePerson = {\n /** Stable key, such as the account id. */\n id: string;\n name: string;\n /** A shorter name for the chip and the line below it, such as the first name. Defaults to `name`. */\n shortName?: string;\n src?: string | null;\n icon?: string;\n /** `square` for agents and service accounts. */\n shape?: AvatarShape;\n /** The person's color, the same as their cursor and comments. Defaults to `personColor(name)`. */\n color?: string;\n /** Writing shows a pen and the person's place; reading shows an eye. */\n activity?: \"writing\" | \"reading\";\n /** Where the person is, such as the heading of the section they write in. */\n place?: string;\n /** Short text at the end of the person's row in the full list, such as \"2 tabs\". */\n trailing?: JSX.Element;\n /** Goes to the person's place. */\n onSelect?: () => void;\n /** The person viewing: the fixed \"You\" chip at the end, never one of the others. */\n self?: boolean;\n};\n\n/** `offline` keeps the last known people, pale and without live dots; `unavailable` offers `onRetry`. */\nexport type DetailPresenceState = \"live\" | \"loading\" | \"offline\" | \"unavailable\";\n\nexport type DetailPresenceProps = {\n people: readonly DetailPresencePerson[];\n state?: DetailPresenceState;\n /**\n * The quiet line below the people when it does not say who writes where: alone (\"Whoever opens the note appears\n * here\"), offline (\"Offline · as of 19:24\"), or unavailable (\"Your changes are still being saved\").\n */\n note?: JSX.Element;\n onRetry?: () => void;\n /** One control at the end of the title row, such as \"Copy link\". */\n actions?: JSX.Element;\n /** Defaults to \"Here now\". */\n title?: string;\n /** One quiet line below the full list. */\n listHint?: JSX.Element;\n class?: string;\n};\n\nconst PresenceFace = (props: { person: DetailPresencePerson; live: boolean }): JSX.Element => (\n <span class=\"k2b-detail-presence__face\" data-live={props.live ? \"true\" : undefined}>\n <Avatar name={props.person.name} src={props.person.src} icon={props.person.icon} shape={props.person.shape} size=\"xs\" alt=\"\" />\n <span class=\"k2b-detail-presence__dot\" aria-hidden=\"true\" />\n </span>\n);\n\n/**\n * \"Here now\": who has the object open, what they do, and where. Always two lines tall in every state, so people\n * coming, going, or moving never shift the panel. Chips that do not fit wrap into a hidden line and count as \"+n\";\n * \"+n\" and \"You\" open the full list, which `AvatarStack` shows beside it or as a sheet on phones.\n */\nexport function DetailPresence(props: DetailPresenceProps): JSX.Element {\n const t = useDetailSectionMessages();\n const state = () => props.state ?? \"live\";\n const others = createMemo(() => props.people.filter((person) => !person.self));\n const self = createMemo(() => props.people.find((person) => person.self));\n const short = (person: DetailPresencePerson) => person.shortName ?? person.name;\n const color = (person: DetailPresencePerson) => person.color ?? personColor(person.name);\n const [hidden, setHidden] = createSignal(0);\n let chips: HTMLDivElement | undefined;\n\n // Chips that do not fit wrap into the clipped second line; they leave the tab order and count as \"+n\".\n const fit = () => {\n if (!chips) return;\n const all = Array.from(chips.children).filter((child): child is HTMLElement => child instanceof HTMLElement);\n const top = all[0]?.offsetTop ?? 0;\n let wrapped = 0;\n for (const chip of all) {\n const out = chip.offsetTop > top;\n chip.inert = out;\n if (out) wrapped += 1;\n }\n setHidden(wrapped);\n };\n // The strip mounts again after loading or an outage, so each mounted strip watches itself.\n const watchChips = (element: HTMLDivElement) => {\n chips = element;\n if (typeof ResizeObserver === \"undefined\") return;\n const resized = new ResizeObserver(fit);\n resized.observe(element);\n const changed = new MutationObserver(fit);\n changed.observe(element, { childList: true });\n queueMicrotask(fit);\n onCleanup(() => {\n resized.disconnect();\n changed.disconnect();\n });\n };\n\n const describe = (person: DetailPresencePerson) =>\n person.activity === \"writing\"\n ? t().personWriting({ name: person.name, place: person.place ?? \"\" })\n : t().personReading({ name: person.name });\n\n const listPeople = createMemo<AvatarStackPerson[]>(() =>\n props.people.map((person) => ({\n id: person.id,\n name: person.self ? t().you : person.name,\n src: person.src,\n icon: person.icon,\n shape: person.shape,\n self: person.self,\n detailIcon: person.self ? undefined : person.activity === \"writing\" ? \"ti ti-pencil\" : \"ti ti-eye\",\n detail: [person.self ? undefined : person.activity === \"writing\" ? t().writing : t().reading, person.place]\n .filter(Boolean)\n .join(\" · \"),\n trailing: person.trailing,\n onSelect: person.onSelect,\n })),\n );\n\n const where = (): JSX.Element => {\n if (state() === \"offline\" || others().length === 0) return props.note;\n const writers = others().filter((person) => person.activity === \"writing\");\n const readers = others().filter((person) => person.activity !== \"writing\");\n return (\n <>\n <For each={writers}>\n {(person, index) => (\n <>\n {index() > 0 ? \", \" : \"\"}\n <span class=\"k2b-detail-presence__swatch\" style={{ \"--k2b-person-color\": color(person) }} aria-hidden=\"true\" />\n <strong>{short(person)}</strong>\n <Show when={person.place}>\n {(place) => (\n <>\n {\" \"}\n {t().writesIn} {place()}\n </>\n )}\n </Show>\n </>\n )}\n </For>\n <Show when={writers.length > 0 && readers.length > 0}>{\" · \"}</Show>\n <Show when={readers.length > 0}>{t().readingAlong({ names: listNames(readers.map(short), t().and), count: readers.length })}</Show>\n </>\n );\n };\n\n const chip = (person: DetailPresencePerson): JSX.Element => {\n const content = (\n <>\n <PresenceFace person={person} live={state() === \"live\"} />\n {short(person)}\n <i\n class={person.activity === \"writing\" ? \"ti ti-pencil k2b-detail-presence__activity\" : \"ti ti-eye k2b-detail-presence__activity\"}\n data-activity={person.activity ?? \"reading\"}\n aria-hidden=\"true\"\n />\n </>\n );\n return (\n <Show\n when={person.onSelect && state() === \"live\"}\n fallback={\n <span class=\"k2b-detail-presence__chip\" style={{ \"--k2b-person-color\": color(person) }} title={describe(person)}>\n <span class=\"k2b-sr-only\">{describe(person)}</span>\n <span aria-hidden=\"true\" class=\"k2b-detail-presence__chip-content\">\n {content}\n </span>\n </span>\n }\n >\n <button\n type=\"button\"\n class=\"k2b-detail-presence__chip\"\n style={{ \"--k2b-person-color\": color(person) }}\n title={describe(person)}\n aria-label={t().jumpTo({ name: person.name, place: person.place ?? \"\" })}\n onClick={() => person.onSelect?.()}\n >\n <span aria-hidden=\"true\" class=\"k2b-detail-presence__chip-content\">\n {content}\n </span>\n </button>\n </Show>\n );\n };\n\n const count = () => ((state() === \"live\" || state() === \"offline\") && others().length > 0 ? others().length : undefined);\n const meta = () => (state() === \"live\" && others().length === 0 ? t().onlyYou : undefined);\n\n return (\n <DetailPanel.Section\n title={props.title ?? t().hereNow}\n icon=\"ti ti-users\"\n count={count()}\n meta={meta()}\n actions={props.actions}\n class={props.class}\n >\n <div class=\"k2b-detail-presence\" data-state={state()} aria-busy={state() === \"loading\" ? \"true\" : undefined}>\n <Show\n when={state() !== \"loading\" && state() !== \"unavailable\"}\n fallback={\n <Show\n when={state() === \"unavailable\"}\n fallback={\n <>\n <div class=\"k2b-detail-presence__strip\" aria-hidden=\"true\">\n <span class=\"k2b-detail-presence__skeleton\" />\n <span class=\"k2b-detail-presence__skeleton\" />\n <span class=\"k2b-detail-presence__skeleton\" />\n </div>\n <p class=\"k2b-detail-presence__where\">\n <span class=\"k2b-detail-presence__skeleton-line\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\" role=\"status\">\n {t().presenceLoading}\n </span>\n </p>\n </>\n }\n >\n <div class=\"k2b-detail-presence__strip k2b-detail-presence__problem\" role=\"status\">\n <i class=\"ti ti-alert-triangle\" aria-hidden=\"true\" />\n <span class=\"k2b-truncate-fade\">{t().presenceUnavailable}</span>\n <Show when={props.onRetry}>\n {(retry) => (\n <Button variant=\"text\" size=\"xs\" class=\"k2b-detail-presence__retry\" onClick={() => retry()()}>\n <i class=\"ti ti-refresh\" aria-hidden=\"true\" /> {t().retry}\n </Button>\n )}\n </Show>\n </div>\n <p class=\"k2b-detail-presence__where k2b-truncate-fade\">{props.note}</p>\n </Show>\n }\n >\n <div class=\"k2b-detail-presence__strip\">\n <div ref={watchChips} class=\"k2b-detail-presence__chips\">\n <For each={others()}>{(person) => chip(person)}</For>\n </div>\n <AvatarStack\n class=\"k2b-detail-presence__all\"\n people={listPeople()}\n title={props.title ?? t().hereNow}\n label={t().everyoneHere({ count: props.people.length })}\n hint={props.listHint}\n trigger={\n <>\n <span class=\"k2b-detail-presence__more\" data-empty={hidden() === 0 ? \"true\" : undefined}>\n +{hidden()}\n </span>\n <Show when={self()}>\n {(person) => (\n <span class=\"k2b-detail-presence__self\">\n <PresenceFace person={person()} live={false} />\n {t().you}\n </span>\n )}\n </Show>\n </>\n }\n />\n </div>\n <p class=\"k2b-detail-presence__where k2b-truncate-fade\">{where()}</p>\n </Show>\n </div>\n </DetailPanel.Section>\n );\n}\n\n/** A fixed slot at the end of a row for the people working there, such as an outline heading. Always the same width. */\nexport function DetailPresenceSlot(props: { people: readonly DetailPresencePerson[]; max?: number }): JSX.Element {\n const max = () => Math.max(1, props.max ?? 2);\n return (\n <span class=\"k2b-detail-presence-slot\" aria-hidden=\"true\">\n <For each={props.people.slice(0, max())}>\n {(person) => <Avatar name={person.name} src={person.src} icon={person.icon} shape={person.shape} size=\"xs\" alt=\"\" />}\n </For>\n <Show when={props.people.length > max()}>\n <span class=\"k2b-detail-presence-slot__more\">+{props.people.length - max()}</span>\n </Show>\n </span>\n );\n}\n\n// ── Access ──────────────────────────────────────────────────────────────\n\nexport type DetailAccessEntry = {\n id: string;\n name: string;\n /** Sets the avatar: a person's picture or initials, a group, a service, all signed-in people, or public. */\n kind?: \"person\" | \"group\" | \"service\" | \"everyone\" | \"public\";\n src?: string | null;\n /** One quiet word after the name, such as \"Service\". */\n detail?: JSX.Element;\n /** The role in words, such as \"Can edit\". */\n role: JSX.Element;\n /** The person viewing; listed as \"You\". */\n self?: boolean;\n};\n\nexport type DetailAccessProps = {\n entries: readonly DetailAccessEntry[];\n state?: \"ready\" | \"loading\" | \"error\";\n onRetry?: () => void;\n /** Rows before \"Show n more\". Defaults to 5. */\n limit?: number;\n /** A way to change access, only for people who may; others read the list. */\n manage?: { label: string; href?: string; onClick?: () => void };\n /** A quiet line below the list, such as \"Applies to the whole notebook\". */\n note?: JSX.Element;\n /** Defaults to \"Access\". */\n title?: string;\n defaultOpen?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n class?: string;\n};\n\nconst ACCESS_ICONS: Record<NonNullable<DetailAccessEntry[\"kind\"]>, string | undefined> = {\n person: undefined,\n service: undefined,\n group: \"ti ti-users-group\",\n everyone: \"ti ti-users\",\n public: \"ti ti-world\",\n};\n\n/**\n * Who has access and with which role, read-only. Closed it names the first entries; open it lists `limit` rows and\n * \"Show n more\". A list that may load later passes `state=\"loading\"` and keeps its place.\n */\nexport function DetailAccess(props: DetailAccessProps): JSX.Element {\n const t = useDetailSectionMessages();\n const panel = useDetailPanelMessages();\n const [all, setAll] = createSignal(false);\n const limit = () => Math.max(1, props.limit ?? 5);\n const state = () => props.state ?? \"ready\";\n const shown = () => (all() ? props.entries : props.entries.slice(0, limit()));\n const hiddenCount = () => Math.max(0, props.entries.length - limit());\n const nameOf = (entry: DetailAccessEntry) => (entry.self ? t().you : entry.name);\n const summary = () => {\n if (state() === \"loading\") return t().accessLoading;\n if (state() === \"error\") return t().accessFailed;\n const names = props.entries.slice(0, 2).map(nameOf);\n return names.length ? t().accessSummary({ names: names.join(\", \"), more: Math.max(0, props.entries.length - 2) }) : undefined;\n };\n const leading = (entry: DetailAccessEntry) => {\n const kind = entry.kind ?? \"person\";\n return (\n <Avatar\n name={entry.name}\n src={kind === \"person\" ? entry.src : undefined}\n icon={ACCESS_ICONS[kind]}\n shape={kind === \"person\" ? \"circle\" : \"square\"}\n size=\"xs\"\n alt=\"\"\n />\n );\n };\n return (\n <DetailPanel.Section\n title={props.title ?? t().access}\n icon=\"ti ti-lock-access\"\n count={state() === \"ready\" ? props.entries.length : undefined}\n collapsible\n summary={summary()}\n defaultOpen={props.defaultOpen}\n open={props.open}\n onOpenChange={props.onOpenChange}\n class={props.class}\n >\n <div class=\"k2b-detail-section-rows\" aria-busy={state() === \"loading\" ? \"true\" : undefined}>\n <Show when={state() === \"loading\"}>\n <For each={[0, 1, 2]}>\n {() => (\n <DetailPanel.Row leading={<span class=\"k2b-detail-row-skeleton__face\" />} title={<span class=\"k2b-detail-row-skeleton\" />} />\n )}\n </For>\n <span class=\"k2b-sr-only\" role=\"status\">\n {t().accessLoading}\n </span>\n </Show>\n <Show when={state() === \"error\"}>\n <div class=\"k2b-detail-section-error\" role=\"alert\">\n <i class=\"ti ti-alert-circle\" aria-hidden=\"true\" />\n <span>{t().accessFailed}</span>\n <Show when={props.onRetry}>\n {(retry) => (\n <Button variant=\"text\" size=\"xs\" onClick={() => retry()()}>\n {t().retry}\n </Button>\n )}\n </Show>\n </div>\n </Show>\n <Show when={state() === \"ready\"}>\n <For each={shown()}>\n {(entry) => <DetailPanel.Row leading={leading(entry)} title={nameOf(entry)} description={entry.detail} trailing={entry.role} />}\n </For>\n <Show when={hiddenCount() > 0}>\n <DetailPanel.Action\n type=\"button\"\n aria-expanded={all()}\n leading={<i class={all() ? \"ti ti-chevron-up\" : \"ti ti-chevron-down\"} aria-hidden=\"true\" />}\n title={all() ? panel().showLess : panel().showMore({ count: hiddenCount() })}\n onClick={() => setAll(!all())}\n />\n </Show>\n </Show>\n <Show when={props.manage}>\n {(manage) => (\n <Show\n when={manage().href}\n fallback={\n <DetailPanel.Action\n type=\"button\"\n leading={<i class=\"ti ti-settings\" aria-hidden=\"true\" />}\n title={manage().label}\n onClick={() => manage().onClick?.()}\n />\n }\n >\n {(href) => (\n <DetailPanel.Action href={href()} leading={<i class=\"ti ti-settings\" aria-hidden=\"true\" />} title={manage().label} />\n )}\n </Show>\n )}\n </Show>\n <Show when={props.note}>\n <p class=\"k2b-detail-section-note\">{props.note}</p>\n </Show>\n </div>\n </DetailPanel.Section>\n );\n}\n\n// ── Links ───────────────────────────────────────────────────────────────\n\nexport type DetailLinkItem = {\n id: string;\n title: string;\n href?: string;\n onClick?: (event: MouseEvent) => void;\n /** Defaults to a document. */\n icon?: string;\n /** Quiet text at the end, such as the other notebook's name. */\n trailing?: JSX.Element;\n};\n\nexport type DetailLinksProps = {\n /** What links here. */\n incoming: readonly DetailLinkItem[];\n /** What this object links to. */\n outgoing: readonly DetailLinkItem[];\n /** Rows per direction before \"Show n more\". Defaults to 5. */\n limit?: number;\n /** Defaults to \"Links\". */\n title?: string;\n defaultOpen?: boolean;\n class?: string;\n};\n\nconst LinkGroup = (props: { label: string; items: readonly DetailLinkItem[]; limit: number }): JSX.Element => {\n const panel = useDetailPanelMessages();\n const [all, setAll] = createSignal(false);\n const hiddenCount = () => Math.max(0, props.items.length - props.limit);\n return (\n <div class=\"k2b-detail-section-group\">\n <div class=\"k2b-detail-section-label\">{props.label}</div>\n <For each={all() ? props.items : props.items.slice(0, props.limit)}>\n {(item) => {\n const shared = {\n leading: <i class={item.icon ?? \"ti ti-file-text\"} aria-hidden=\"true\" />,\n title: item.title,\n trailing: item.trailing,\n };\n return (\n <Show when={item.href} fallback={<DetailPanel.Action type=\"button\" onClick={(event) => item.onClick?.(event)} {...shared} />}>\n {(href) => <DetailPanel.Action href={href()} onClick={(event: MouseEvent) => item.onClick?.(event)} {...shared} />}\n </Show>\n );\n }}\n </For>\n <Show when={hiddenCount() > 0}>\n <DetailPanel.Action\n type=\"button\"\n aria-expanded={all()}\n leading={<i class={all() ? \"ti ti-chevron-up\" : \"ti ti-chevron-down\"} aria-hidden=\"true\" />}\n title={all() ? panel().showLess : panel().showMore({ count: hiddenCount() })}\n onClick={() => setAll(!all())}\n />\n </Show>\n </div>\n );\n};\n\n/** \"Linked from\" and \"Links to\" in one section. Without links it is one row: the title and \"None yet\". */\nexport function DetailLinks(props: DetailLinksProps): JSX.Element {\n const t = useDetailSectionMessages();\n const limit = () => Math.max(1, props.limit ?? 5);\n const total = () => props.incoming.length + props.outgoing.length;\n const summary = () => {\n const names = (items: readonly DetailLinkItem[]) => ({\n names: listNames(\n items.slice(0, 2).map((item) => item.title),\n t().and,\n ),\n more: Math.max(0, items.length - 2),\n });\n return props.incoming.length ? t().linkedBySummary(names(props.incoming)) : t().linksToSummary(names(props.outgoing));\n };\n return (\n <Show\n when={total() > 0}\n fallback={<DetailPanel.Section title={props.title ?? t().links} icon=\"ti ti-arrows-exchange\" count={0} class={props.class} />}\n >\n <DetailPanel.Section\n title={props.title ?? t().links}\n icon=\"ti ti-arrows-exchange\"\n count={total()}\n collapsible\n defaultOpen={props.defaultOpen ?? true}\n summary={summary()}\n class={props.class}\n >\n <div class=\"k2b-detail-section-rows\">\n <Show when={props.incoming.length > 0}>\n <LinkGroup label={t().linkedBy({ count: props.incoming.length })} items={props.incoming} limit={limit()} />\n </Show>\n <Show when={props.outgoing.length > 0}>\n <LinkGroup label={t().linksTo({ count: props.outgoing.length })} items={props.outgoing} limit={limit()} />\n </Show>\n </div>\n </DetailPanel.Section>\n </Show>\n );\n}\n\n// ── Properties ──────────────────────────────────────────────────────────\n\nexport type DetailProperty = {\n id: string;\n label: JSX.Element;\n value: JSX.Element;\n /** An avatar or icon before the value. */\n leading?: JSX.Element;\n /** Makes the value a link, such as \"23 versions\" to the version history. */\n href?: string;\n};\n\nexport type DetailPropertiesProps = {\n items: readonly DetailProperty[];\n /** Defaults to \"Properties\". */\n title?: string;\n icon?: string;\n /** One line for the closed section, such as \"412 words · created 12 March by Jana Berger\". */\n summary?: JSX.Element;\n /** Open by default only when the properties are the object's main content. */\n defaultOpen?: boolean;\n class?: string;\n};\n\n/** Facts about the object as label and value rows, such as created, edited, size, and the way to its history. */\nexport function DetailProperties(props: DetailPropertiesProps): JSX.Element {\n const t = useDetailSectionMessages();\n return (\n <DetailPanel.Section\n title={props.title ?? t().properties}\n icon={props.icon ?? \"ti ti-info-square\"}\n collapsible\n defaultOpen={props.defaultOpen}\n summary={props.summary}\n class={props.class}\n >\n <dl class=\"k2b-detail-properties\">\n <For each={props.items}>\n {(item) => (\n <div class=\"k2b-detail-properties__item\">\n <dt>{item.label}</dt>\n <dd>\n <Show when={item.leading}>\n <span class=\"k2b-detail-properties__leading\">{item.leading}</span>\n </Show>\n <Show when={item.href} fallback={<span class=\"k2b-detail-properties__value\">{item.value}</span>}>\n {(href) => (\n <a class=\"k2b-detail-properties__value k2b-detail-properties__link\" href={href()}>\n {item.value}\n </a>\n )}\n </Show>\n </dd>\n </div>\n )}\n </For>\n </dl>\n </DetailPanel.Section>\n );\n}\n\n// ── Tags ────────────────────────────────────────────────────────────────\n\nexport type DetailTag = {\n id: string;\n label: string;\n /** Where the tag leads, such as everything with that tag. */\n href?: string;\n};\n\nexport type DetailTagsProps = {\n tags: readonly DetailTag[];\n /** Defaults to \"Tags\". */\n title?: string;\n /** Shown without tags, such as how to add one. */\n emptyHint?: JSX.Element;\n class?: string;\n};\n\n/** The object's tags as chips; a chip with `href` leads to everything with that tag. */\nexport function DetailTags(props: DetailTagsProps): JSX.Element {\n const t = useDetailSectionMessages();\n return (\n <DetailPanel.Section title={props.title ?? t().tags} icon=\"ti ti-hash\" count={props.tags.length} class={props.class}>\n <Show when={props.tags.length > 0} fallback={props.emptyHint ? <p class=\"k2b-detail-section-note\">{props.emptyHint}</p> : undefined}>\n <ul class=\"k2b-detail-tags\">\n <For each={props.tags}>\n {(tag) => (\n <li>\n <Show when={tag.href} fallback={<span class=\"k2b-detail-tag\">#{tag.label}</span>}>\n {(href) => (\n <a class=\"k2b-detail-tag\" href={href()}>\n #{tag.label}\n </a>\n )}\n </Show>\n </li>\n )}\n </For>\n </ul>\n </Show>\n </DetailPanel.Section>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["layout/DetailSections.tsx"],"sourcesContent":["import { children, createMemo, createSignal, For, type JSX, onCleanup, Show } from \"solid-js\";\nimport { Button } from \"../actions/Button\";\nimport type { DropdownItem } from \"../actions/Dropdown\";\nimport { Avatar, type AvatarShape } from \"../surfaces/Avatar\";\nimport { AvatarStack, type AvatarStackPerson } from \"../surfaces/AvatarStack\";\nimport { personColor } from \"../surfaces/person-color\";\nimport DetailPanel from \"./DetailPanel\";\nimport { useDetailPanelMessages } from \"./detail-panel-messages\";\nimport { useDetailSectionMessages } from \"./detail-sections-messages\";\n\n/*\n * Shared sections of an object's detail panel. Each one is a `DetailPanel.Section` with its icon, title, and count, so\n * its content starts on the title's text edge, and each keeps its height while its data changes. Apps pass data; the\n * order of sections is a convention (see the DetailPanel UI context).\n */\n\nconst listNames = (names: readonly string[], and: string): string =>\n names.length <= 1 ? (names[0] ?? \"\") : `${names.slice(0, -1).join(\", \")} ${and} ${names.at(-1)}`;\n\n// ── Presence ────────────────────────────────────────────────────────────\n\nexport type DetailPresencePerson = {\n /** Stable key, such as the account id. */\n id: string;\n name: string;\n /** A shorter name for the chip and the line below it, such as the first name. Defaults to `name`. */\n shortName?: string;\n src?: string | null;\n icon?: string;\n /** `square` for agents and service accounts. */\n shape?: AvatarShape;\n /** The person's color, the same as their cursor and comments. Defaults to `personColor(name)`. */\n color?: string;\n /** Writing shows a pen and the person's place; reading shows an eye. */\n activity?: \"writing\" | \"reading\";\n /** Where the person is, such as the heading of the section they write in. */\n place?: string;\n /** Short text at the end of the person's row in the full list, such as \"2 tabs\". */\n trailing?: JSX.Element;\n /** Goes to the person's place. */\n onSelect?: () => void;\n /** The person viewing: the fixed \"You\" chip at the end, never one of the others. */\n self?: boolean;\n};\n\n/** `offline` keeps the last known people, pale and without live dots; `unavailable` offers `onRetry`. */\nexport type DetailPresenceState = \"live\" | \"loading\" | \"offline\" | \"unavailable\";\n\nexport type DetailPresenceProps = {\n people: readonly DetailPresencePerson[];\n state?: DetailPresenceState;\n /**\n * The quiet line below the people when it does not say who writes where: alone (\"Whoever opens the note appears\n * here\"), offline (\"Offline · as of 19:24\"), or unavailable (\"Your changes are still being saved\").\n */\n note?: JSX.Element;\n onRetry?: () => void;\n /** One control at the end of the title row, such as \"Copy link\". */\n actions?: JSX.Element;\n /** Defaults to \"Here now\". */\n title?: string;\n /** One quiet line below the full list. */\n listHint?: JSX.Element;\n class?: string;\n};\n\nconst PresenceFace = (props: { person: DetailPresencePerson; live: boolean }): JSX.Element => (\n <span class=\"k2b-detail-presence__face\" data-live={props.live ? \"true\" : undefined}>\n <Avatar name={props.person.name} src={props.person.src} icon={props.person.icon} shape={props.person.shape} size=\"xs\" alt=\"\" />\n <span class=\"k2b-detail-presence__dot\" aria-hidden=\"true\" />\n </span>\n);\n\n/**\n * \"Here now\": who has the object open, what they do, and where. Always two lines tall in every state, so people\n * coming, going, or moving never shift the panel. Chips that do not fit wrap into a hidden line and count as \"+n\";\n * \"+n\" and \"You\" open the full list, which `AvatarStack` shows beside it or as a sheet on phones.\n */\nexport function DetailPresence(props: DetailPresenceProps): JSX.Element {\n const t = useDetailSectionMessages();\n const state = () => props.state ?? \"live\";\n const others = createMemo(() => props.people.filter((person) => !person.self));\n const self = createMemo(() => props.people.find((person) => person.self));\n const short = (person: DetailPresencePerson) => person.shortName ?? person.name;\n const color = (person: DetailPresencePerson) => person.color ?? personColor(person.name);\n const [hidden, setHidden] = createSignal(0);\n let chips: HTMLDivElement | undefined;\n\n // Chips that do not fit wrap into the clipped second line; they leave the tab order and count as \"+n\".\n const fit = () => {\n if (!chips) return;\n const all = Array.from(chips.children).filter((child): child is HTMLElement => child instanceof HTMLElement);\n const top = all[0]?.offsetTop ?? 0;\n let wrapped = 0;\n for (const chip of all) {\n const out = chip.offsetTop > top;\n chip.inert = out;\n if (out) wrapped += 1;\n }\n setHidden(wrapped);\n };\n // The strip mounts again after loading or an outage, so each mounted strip watches itself.\n const watchChips = (element: HTMLDivElement) => {\n chips = element;\n if (typeof ResizeObserver === \"undefined\") return;\n const resized = new ResizeObserver(fit);\n resized.observe(element);\n const changed = new MutationObserver(fit);\n changed.observe(element, { childList: true });\n queueMicrotask(fit);\n onCleanup(() => {\n resized.disconnect();\n changed.disconnect();\n });\n };\n\n const describe = (person: DetailPresencePerson) =>\n person.activity === \"writing\"\n ? t().personWriting({ name: person.name, place: person.place ?? \"\" })\n : t().personReading({ name: person.name });\n\n const listPeople = createMemo<AvatarStackPerson[]>(() =>\n props.people.map((person) => ({\n id: person.id,\n name: person.self ? t().you : person.name,\n src: person.src,\n icon: person.icon,\n shape: person.shape,\n self: person.self,\n detailIcon: person.self ? undefined : person.activity === \"writing\" ? \"ti ti-pencil\" : \"ti ti-eye\",\n detail: [person.self ? undefined : person.activity === \"writing\" ? t().writing : t().reading, person.place]\n .filter(Boolean)\n .join(\" · \"),\n trailing: person.trailing,\n onSelect: person.onSelect,\n })),\n );\n\n const where = (): JSX.Element => {\n if (state() === \"offline\" || others().length === 0) return props.note;\n const writers = others().filter((person) => person.activity === \"writing\");\n const readers = others().filter((person) => person.activity !== \"writing\");\n return (\n <>\n <For each={writers}>\n {(person, index) => (\n <>\n {index() > 0 ? \", \" : \"\"}\n <span class=\"k2b-detail-presence__swatch\" style={{ \"--k2b-person-color\": color(person) }} aria-hidden=\"true\" />\n <strong>{short(person)}</strong>\n <Show when={person.place}>\n {(place) => (\n <>\n {\" \"}\n {t().writesIn} {place()}\n </>\n )}\n </Show>\n </>\n )}\n </For>\n <Show when={writers.length > 0 && readers.length > 0}>{\" · \"}</Show>\n <Show when={readers.length > 0}>{t().readingAlong({ names: listNames(readers.map(short), t().and), count: readers.length })}</Show>\n </>\n );\n };\n\n const chip = (person: DetailPresencePerson): JSX.Element => {\n const content = (\n <>\n <PresenceFace person={person} live={state() === \"live\"} />\n {short(person)}\n <i\n class={person.activity === \"writing\" ? \"ti ti-pencil k2b-detail-presence__activity\" : \"ti ti-eye k2b-detail-presence__activity\"}\n data-activity={person.activity ?? \"reading\"}\n aria-hidden=\"true\"\n />\n </>\n );\n return (\n <Show\n when={person.onSelect && state() === \"live\"}\n fallback={\n <span class=\"k2b-detail-presence__chip\" style={{ \"--k2b-person-color\": color(person) }} title={describe(person)}>\n <span class=\"k2b-sr-only\">{describe(person)}</span>\n <span aria-hidden=\"true\" class=\"k2b-detail-presence__chip-content\">\n {content}\n </span>\n </span>\n }\n >\n <button\n type=\"button\"\n class=\"k2b-detail-presence__chip\"\n style={{ \"--k2b-person-color\": color(person) }}\n title={describe(person)}\n aria-label={t().jumpTo({ name: person.name, place: person.place ?? \"\" })}\n onClick={() => person.onSelect?.()}\n >\n <span aria-hidden=\"true\" class=\"k2b-detail-presence__chip-content\">\n {content}\n </span>\n </button>\n </Show>\n );\n };\n\n const count = () => ((state() === \"live\" || state() === \"offline\") && others().length > 0 ? others().length : undefined);\n const meta = () => (state() === \"live\" && others().length === 0 ? t().onlyYou : undefined);\n\n return (\n <DetailPanel.Section\n title={props.title ?? t().hereNow}\n icon=\"ti ti-users\"\n count={count()}\n meta={meta()}\n actions={props.actions}\n class={props.class}\n >\n <div class=\"k2b-detail-presence\" data-state={state()} aria-busy={state() === \"loading\" ? \"true\" : undefined}>\n <Show\n when={state() !== \"loading\" && state() !== \"unavailable\"}\n fallback={\n <Show\n when={state() === \"unavailable\"}\n fallback={\n <>\n <div class=\"k2b-detail-presence__strip\" aria-hidden=\"true\">\n <span class=\"k2b-detail-presence__skeleton\" />\n <span class=\"k2b-detail-presence__skeleton\" />\n <span class=\"k2b-detail-presence__skeleton\" />\n </div>\n <p class=\"k2b-detail-presence__where\">\n <span class=\"k2b-detail-presence__skeleton-line\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\" role=\"status\">\n {t().presenceLoading}\n </span>\n </p>\n </>\n }\n >\n <div class=\"k2b-detail-presence__strip k2b-detail-presence__problem\" role=\"status\">\n <i class=\"ti ti-alert-triangle\" aria-hidden=\"true\" />\n <span class=\"k2b-truncate-fade\">{t().presenceUnavailable}</span>\n <Show when={props.onRetry}>\n {(retry) => (\n <Button variant=\"text\" size=\"xs\" class=\"k2b-detail-presence__retry\" onClick={() => retry()()}>\n <i class=\"ti ti-refresh\" aria-hidden=\"true\" /> {t().retry}\n </Button>\n )}\n </Show>\n </div>\n <p class=\"k2b-detail-presence__where k2b-truncate-fade\">{props.note}</p>\n </Show>\n }\n >\n <div class=\"k2b-detail-presence__strip\">\n <div ref={watchChips} class=\"k2b-detail-presence__chips\">\n <For each={others()}>{(person) => chip(person)}</For>\n </div>\n <AvatarStack\n class=\"k2b-detail-presence__all\"\n people={listPeople()}\n title={props.title ?? t().hereNow}\n label={t().everyoneHere({ count: props.people.length })}\n hint={props.listHint}\n trigger={\n <>\n <span class=\"k2b-detail-presence__more\" data-empty={hidden() === 0 ? \"true\" : undefined}>\n +{hidden()}\n </span>\n <Show when={self()}>\n {(person) => (\n <span class=\"k2b-detail-presence__self\">\n <PresenceFace person={person()} live={false} />\n {t().you}\n </span>\n )}\n </Show>\n </>\n }\n />\n </div>\n <p class=\"k2b-detail-presence__where k2b-truncate-fade\">{where()}</p>\n </Show>\n </div>\n </DetailPanel.Section>\n );\n}\n\n/** A fixed slot at the end of a row for the people working there, such as an outline heading. Always the same width. */\nexport function DetailPresenceSlot(props: { people: readonly DetailPresencePerson[]; max?: number }): JSX.Element {\n const max = () => Math.max(1, props.max ?? 2);\n return (\n <span class=\"k2b-detail-presence-slot\" aria-hidden=\"true\">\n <For each={props.people.slice(0, max())}>\n {(person) => <Avatar name={person.name} src={person.src} icon={person.icon} shape={person.shape} size=\"xs\" alt=\"\" />}\n </For>\n <Show when={props.people.length > max()}>\n <span class=\"k2b-detail-presence-slot__more\">+{props.people.length - max()}</span>\n </Show>\n </span>\n );\n}\n\n// ── Access ──────────────────────────────────────────────────────────────\n\nexport type DetailAccessEntry = {\n id: string;\n name: string;\n /** Sets the avatar: a person's picture or initials, a group, a service, all signed-in people, or public. */\n kind?: \"person\" | \"group\" | \"service\" | \"everyone\" | \"public\";\n src?: string | null;\n /** One quiet word after the name, such as \"Service\". */\n detail?: JSX.Element;\n /** The role in words, such as \"Can edit\". */\n role: JSX.Element;\n /** The person viewing; listed as \"You\". */\n self?: boolean;\n};\n\nexport type DetailAccessProps = {\n entries: readonly DetailAccessEntry[];\n state?: \"ready\" | \"loading\" | \"error\";\n onRetry?: () => void;\n /** Rows before \"Show n more\". Defaults to 5. */\n limit?: number;\n /** A way to change access, only for people who may; others read the list. */\n manage?: { label: string; href?: string; onClick?: () => void };\n /** A quiet line below the list, such as \"Applies to the whole notebook\". */\n note?: JSX.Element;\n /** Defaults to \"Access\". */\n title?: string;\n defaultOpen?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n class?: string;\n};\n\nconst ACCESS_ICONS: Record<NonNullable<DetailAccessEntry[\"kind\"]>, string | undefined> = {\n person: undefined,\n service: undefined,\n group: \"ti ti-users-group\",\n everyone: \"ti ti-users\",\n public: \"ti ti-world\",\n};\n\n/**\n * Who has access and with which role, read-only. Closed it names the first entries; open it lists `limit` rows and\n * \"Show n more\". A list that may load later passes `state=\"loading\"` and keeps its place.\n */\nexport function DetailAccess(props: DetailAccessProps): JSX.Element {\n const t = useDetailSectionMessages();\n const panel = useDetailPanelMessages();\n const [all, setAll] = createSignal(false);\n const limit = () => Math.max(1, props.limit ?? 5);\n const state = () => props.state ?? \"ready\";\n const shown = () => (all() ? props.entries : props.entries.slice(0, limit()));\n const hiddenCount = () => Math.max(0, props.entries.length - limit());\n const nameOf = (entry: DetailAccessEntry) => (entry.self ? t().you : entry.name);\n const summary = () => {\n if (state() === \"loading\") return t().accessLoading;\n if (state() === \"error\") return t().accessFailed;\n const names = props.entries.slice(0, 2).map(nameOf);\n return names.length ? t().accessSummary({ names: names.join(\", \"), more: Math.max(0, props.entries.length - 2) }) : undefined;\n };\n const leading = (entry: DetailAccessEntry) => {\n const kind = entry.kind ?? \"person\";\n return (\n <Avatar\n name={entry.name}\n src={kind === \"person\" ? entry.src : undefined}\n icon={ACCESS_ICONS[kind]}\n shape={kind === \"person\" ? \"circle\" : \"square\"}\n size=\"xs\"\n alt=\"\"\n />\n );\n };\n return (\n <DetailPanel.Section\n title={props.title ?? t().access}\n icon=\"ti ti-lock-access\"\n count={state() === \"ready\" ? props.entries.length : undefined}\n collapsible\n summary={summary()}\n defaultOpen={props.defaultOpen}\n open={props.open}\n onOpenChange={props.onOpenChange}\n class={props.class}\n >\n <div class=\"k2b-detail-section-rows\" aria-busy={state() === \"loading\" ? \"true\" : undefined}>\n <Show when={state() === \"loading\"}>\n <For each={[0, 1, 2]}>\n {() => (\n <DetailPanel.Row leading={<span class=\"k2b-detail-row-skeleton__face\" />} title={<span class=\"k2b-detail-row-skeleton\" />} />\n )}\n </For>\n <span class=\"k2b-sr-only\" role=\"status\">\n {t().accessLoading}\n </span>\n </Show>\n <Show when={state() === \"error\"}>\n <div class=\"k2b-detail-section-error\" role=\"alert\">\n <i class=\"ti ti-alert-circle\" aria-hidden=\"true\" />\n <span>{t().accessFailed}</span>\n <Show when={props.onRetry}>\n {(retry) => (\n <Button variant=\"text\" size=\"xs\" onClick={() => retry()()}>\n {t().retry}\n </Button>\n )}\n </Show>\n </div>\n </Show>\n <Show when={state() === \"ready\"}>\n <For each={shown()}>\n {(entry) => <DetailPanel.Row leading={leading(entry)} title={nameOf(entry)} description={entry.detail} trailing={entry.role} />}\n </For>\n <Show when={hiddenCount() > 0}>\n <DetailPanel.Action\n type=\"button\"\n aria-expanded={all()}\n leading={<i class={all() ? \"ti ti-chevron-up\" : \"ti ti-chevron-down\"} aria-hidden=\"true\" />}\n title={all() ? panel().showLess : panel().showMore({ count: hiddenCount() })}\n onClick={() => setAll(!all())}\n />\n </Show>\n </Show>\n <Show when={props.manage}>\n {(manage) => (\n <Show\n when={manage().href}\n fallback={\n <DetailPanel.Action\n type=\"button\"\n leading={<i class=\"ti ti-settings\" aria-hidden=\"true\" />}\n title={manage().label}\n onClick={() => manage().onClick?.()}\n />\n }\n >\n {(href) => (\n <DetailPanel.Action href={href()} leading={<i class=\"ti ti-settings\" aria-hidden=\"true\" />} title={manage().label} />\n )}\n </Show>\n )}\n </Show>\n <Show when={props.note}>\n <p class=\"k2b-detail-section-note\">{props.note}</p>\n </Show>\n </div>\n </DetailPanel.Section>\n );\n}\n\n// ── Links ───────────────────────────────────────────────────────────────\n\nexport type DetailLinkItem = {\n id: string;\n title: string;\n href?: string;\n onClick?: (event: MouseEvent) => void;\n /** Defaults to a document. */\n icon?: string;\n /** Replaces the icon, such as a site's favicon. */\n leading?: JSX.Element;\n /** One quiet line below the title, such as where the item lives. */\n description?: JSX.Element;\n /** Quiet text at the end, such as the other notebook's name. */\n trailing?: JSX.Element;\n /** For a link to another site, such as `_blank` with `rel=\"noreferrer\"`. */\n target?: string;\n rel?: string;\n /** An item that cannot be opened right now, such as one the person may no longer read. */\n disabled?: boolean;\n} & (\n | { menuItems?: never; menuLabel?: never }\n | {\n /** Further commands on the item, such as \"Unlink\", only for people who may run them. */\n menuItems: readonly DropdownItem[];\n menuLabel: string;\n }\n);\n\nexport type DetailLinksProps = {\n /** What links here. */\n incoming: readonly DetailLinkItem[];\n /** What this object links to. */\n outgoing: readonly DetailLinkItem[];\n /** Rows per direction before \"Show n more\". Defaults to 5. */\n limit?: number;\n /** Defaults to \"Links\". */\n title?: string;\n defaultOpen?: boolean;\n /**\n * `loading` while links still load after the first paint: a placeholder row keeps their place. `error` keeps the\n * loaded rows and says that the rest failed, with `onRetry`.\n */\n state?: \"ready\" | \"loading\" | \"error\";\n onRetry?: () => void;\n /** Rows after the links, such as \"Add link\" or \"Load more\", only for people who may use them. */\n footer?: JSX.Element;\n class?: string;\n};\n\nconst LinkRow = (props: { item: DetailLinkItem }): JSX.Element => {\n const item = props.item;\n const menu = item.menuItems ? { menuItems: item.menuItems, menuLabel: item.menuLabel } : {};\n const shared = {\n leading: item.leading ?? <i class={item.icon ?? \"ti ti-file-text\"} aria-hidden=\"true\" />,\n title: item.title,\n description: item.description,\n trailing: item.trailing,\n ...menu,\n };\n return (\n <Show\n when={!item.disabled && item.href}\n fallback={<DetailPanel.Action type=\"button\" disabled={item.disabled} onClick={(event) => item.onClick?.(event)} {...shared} />}\n >\n {(href) => (\n <DetailPanel.Action\n href={href()}\n target={item.target}\n rel={item.rel}\n onClick={(event: MouseEvent) => item.onClick?.(event)}\n {...shared}\n />\n )}\n </Show>\n );\n};\n\nconst LinkGroup = (props: { label: string; items: readonly DetailLinkItem[]; limit: number }): JSX.Element => {\n const panel = useDetailPanelMessages();\n const [all, setAll] = createSignal(false);\n const hiddenCount = () => Math.max(0, props.items.length - props.limit);\n return (\n <div class=\"k2b-detail-section-group\">\n <div class=\"k2b-detail-section-label\">{props.label}</div>\n <For each={all() ? props.items : props.items.slice(0, props.limit)}>{(item) => <LinkRow item={item} />}</For>\n <Show when={hiddenCount() > 0}>\n <DetailPanel.Action\n type=\"button\"\n aria-expanded={all()}\n leading={<i class={all() ? \"ti ti-chevron-up\" : \"ti ti-chevron-down\"} aria-hidden=\"true\" />}\n title={all() ? panel().showLess : panel().showMore({ count: hiddenCount() })}\n onClick={() => setAll(!all())}\n />\n </Show>\n </div>\n );\n};\n\n/**\n * \"Linked from\" and \"Links to\" in one section. Without links it is one row: the title and \"None yet\", followed by the\n * `footer` when there is one.\n */\nexport function DetailLinks(props: DetailLinksProps): JSX.Element {\n const t = useDetailSectionMessages();\n const limit = () => Math.max(1, props.limit ?? 5);\n const state = () => props.state ?? \"ready\";\n const total = () => props.incoming.length + props.outgoing.length;\n // Resolve once: the empty state reads it as a condition and as content.\n const footer = children(() => props.footer);\n const summary = () => {\n if (state() === \"loading\") return t().linksLoading;\n if (state() === \"error\") return t().linksFailed;\n const names = (items: readonly DetailLinkItem[]) => ({\n names: listNames(\n items.slice(0, 2).map((item) => item.title),\n t().and,\n ),\n more: Math.max(0, items.length - 2),\n });\n return props.incoming.length ? t().linkedBySummary(names(props.incoming)) : t().linksToSummary(names(props.outgoing));\n };\n // Loading and failure take the row the next links would take, so the loaded rows above never move.\n const pending = () => (\n <>\n <Show when={state() === \"loading\"}>\n <div class=\"k2b-detail-section-rows\" aria-busy=\"true\">\n <DetailPanel.Row leading={<span class=\"k2b-detail-row-skeleton__face\" />} title={<span class=\"k2b-detail-row-skeleton\" />} />\n <span class=\"k2b-sr-only\" role=\"status\">\n {t().linksLoading}\n </span>\n </div>\n </Show>\n <Show when={state() === \"error\"}>\n <div class=\"k2b-detail-section-error\" role=\"alert\">\n <i class=\"ti ti-alert-circle\" aria-hidden=\"true\" />\n <span>{t().linksFailed}</span>\n <Show when={props.onRetry}>\n {(retry) => (\n <Button variant=\"text\" size=\"xs\" onClick={() => retry()()}>\n {t().retry}\n </Button>\n )}\n </Show>\n </div>\n </Show>\n </>\n );\n return (\n <Show\n when={total() > 0}\n fallback={\n <DetailPanel.Section\n title={props.title ?? t().links}\n icon=\"ti ti-arrows-exchange\"\n count={state() === \"ready\" ? 0 : undefined}\n class={props.class}\n >\n <Show when={state() !== \"ready\" || footer()}>\n <div class=\"k2b-detail-section-rows\">\n {pending()}\n {footer()}\n </div>\n </Show>\n </DetailPanel.Section>\n }\n >\n <DetailPanel.Section\n title={props.title ?? t().links}\n icon=\"ti ti-arrows-exchange\"\n count={state() === \"ready\" ? total() : undefined}\n collapsible\n defaultOpen={props.defaultOpen ?? true}\n summary={summary()}\n class={props.class}\n >\n <div class=\"k2b-detail-section-rows\">\n <Show when={props.incoming.length > 0}>\n <LinkGroup label={t().linkedBy({ count: props.incoming.length })} items={props.incoming} limit={limit()} />\n </Show>\n <Show when={props.outgoing.length > 0}>\n <LinkGroup label={t().linksTo({ count: props.outgoing.length })} items={props.outgoing} limit={limit()} />\n </Show>\n {pending()}\n {footer()}\n </div>\n </DetailPanel.Section>\n </Show>\n );\n}\n\n// ── Properties ──────────────────────────────────────────────────────────\n\nexport type DetailProperty = {\n id: string;\n label: JSX.Element;\n value: JSX.Element;\n /** An avatar or icon before the value. */\n leading?: JSX.Element;\n /** Makes the value a link, such as \"23 versions\" to the version history. */\n href?: string;\n};\n\nexport type DetailPropertiesProps = {\n items: readonly DetailProperty[];\n /** Defaults to \"Properties\". */\n title?: string;\n icon?: string;\n /** One line for the closed section, such as \"412 words · created 12 March by Jana Berger\". */\n summary?: JSX.Element;\n /** Open by default only when the properties are the object's main content. */\n defaultOpen?: boolean;\n /** Rows after the facts, such as a command that copies the object's ID. */\n children?: JSX.Element;\n class?: string;\n};\n\n/** Facts about the object as label and value rows, such as created, edited, size, and the way to its history. */\nexport function DetailProperties(props: DetailPropertiesProps): JSX.Element {\n const t = useDetailSectionMessages();\n return (\n <DetailPanel.Section\n title={props.title ?? t().properties}\n icon={props.icon ?? \"ti ti-info-square\"}\n collapsible\n defaultOpen={props.defaultOpen}\n summary={props.summary}\n class={props.class}\n >\n <dl class=\"k2b-detail-properties\">\n <For each={props.items}>\n {(item) => (\n <div class=\"k2b-detail-properties__item\">\n <dt>{item.label}</dt>\n <dd>\n <Show when={item.leading}>\n <span class=\"k2b-detail-properties__leading\">{item.leading}</span>\n </Show>\n <Show when={item.href} fallback={<span class=\"k2b-detail-properties__value\">{item.value}</span>}>\n {(href) => (\n <a class=\"k2b-detail-properties__value k2b-detail-properties__link\" href={href()}>\n {item.value}\n </a>\n )}\n </Show>\n </dd>\n </div>\n )}\n </For>\n </dl>\n {props.children}\n </DetailPanel.Section>\n );\n}\n\n// ── Tags ────────────────────────────────────────────────────────────────\n\nexport type DetailTag = {\n id: string;\n label: string;\n /** Where the tag leads, such as everything with that tag. */\n href?: string;\n};\n\nexport type DetailTagsProps = {\n tags: readonly DetailTag[];\n /** Defaults to \"Tags\". */\n title?: string;\n /** Shown without tags, such as how to add one. */\n emptyHint?: JSX.Element;\n class?: string;\n};\n\n/** The object's tags as chips; a chip with `href` leads to everything with that tag. */\nexport function DetailTags(props: DetailTagsProps): JSX.Element {\n const t = useDetailSectionMessages();\n return (\n <DetailPanel.Section title={props.title ?? t().tags} icon=\"ti ti-hash\" count={props.tags.length} class={props.class}>\n <Show when={props.tags.length > 0} fallback={props.emptyHint ? <p class=\"k2b-detail-section-note\">{props.emptyHint}</p> : undefined}>\n <ul class=\"k2b-detail-tags\">\n <For each={props.tags}>\n {(tag) => (\n <li>\n <Show when={tag.href} fallback={<span class=\"k2b-detail-tag\">#{tag.label}</span>}>\n {(href) => (\n <a class=\"k2b-detail-tag\" href={href()}>\n #{tag.label}\n </a>\n )}\n </Show>\n </li>\n )}\n </For>\n </ul>\n </Show>\n </DetailPanel.Section>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -48,6 +48,19 @@ const persistentToastInset = body => {
48
48
  return Math.max(0, Math.min(area.height, area.bottom - top));
49
49
  };
50
50
 
51
+ /** On the root while its content is a screen of its own; the footer steps aside. */
52
+ const SCREEN = "data-k2b-screen";
53
+
54
+ /**
55
+ * Marks the shell around `from` as showing a screen of its own, or not, after the first paint; the server renders
56
+ * the first state with the `screen` prop. Does nothing outside a shell.
57
+ */
58
+ const setMobileShellScreen = (from, screen) => {
59
+ const root = from.closest(".k2b-mobile-shell");
60
+ if (!root) return;
61
+ if (screen) root.setAttribute(SCREEN, "");else root.removeAttribute(SCREEN);
62
+ };
63
+
51
64
  /** Marks the link whose page is loading; the tab bar shows it as selected. */
52
65
  const PENDING = "data-k2b-pending";
53
66
  /** On a link: the title of the page it opens. Such a link switches the shell to that page's frame at the first touch. */
@@ -230,7 +243,7 @@ export function observeMobileShell(root) {
230
243
  function MobileShellRoot(props) {
231
244
  let root;
232
245
  onMount(() => onCleanup(observeMobileShell(root)));
233
- return [_$ssr(_tmpl$, _$ssrAttribute("class", props.class ? `k2b-mobile-shell ${_$escape(props.class, true)}` : "k2b-mobile-shell", false) + _$ssrAttribute("data-k2b-content-heads", props.scroll === false ? "" : _$escape(undefined, true), false), _$escape(props.sidebar), _$escape(props.header), _$escape(_$createComponent(Show, {
246
+ return [_$ssr(_tmpl$, _$ssrAttribute("class", props.class ? `k2b-mobile-shell ${_$escape(props.class, true)}` : "k2b-mobile-shell", false) + _$ssrAttribute("data-k2b-content-heads", props.scroll === false ? "" : _$escape(undefined, true), false) + _$ssrAttribute("data-k2b-screen", props.screen ? "" : _$escape(undefined, true), false), _$escape(props.sidebar), _$escape(props.header), _$escape(_$createComponent(Show, {
234
247
  get when() {
235
248
  return props.scroll !== false;
236
249
  },
@@ -358,7 +371,8 @@ function MobileShellSidebar(props) {
358
371
  */
359
372
  export const MobileShell = Object.assign(MobileShellRoot, {
360
373
  Header: MobileShellHeader,
361
- Sidebar: MobileShellSidebar
374
+ Sidebar: MobileShellSidebar,
375
+ setScreen: setMobileShellScreen
362
376
  });
363
377
  export default MobileShell;
364
378
  //# sourceMappingURL=MobileShell.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["layout/MobileShell.tsx"],"sourcesContent":["import { For, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { IconButton, IconButtonLink } from \"../actions/Button\";\nimport ScrollArea from \"./ScrollArea\";\nimport { installScrollFades } from \"./scroll-fade\";\nimport type { TabBarItem } from \"./TabBar\";\n\nexport type MobileShellProps = {\n /** Usually `MobileShell.Header`; it sits above the scroll area and pads the top safe area. */\n header?: JSX.Element;\n /** Usually a `TabBar`; it sits below the scroll area and pads the bottom safe area itself. */\n footer?: JSX.Element;\n /**\n * Usually `MobileShell.Sidebar` with the footer's destinations and more. From 48rem of window width it stands at\n * the start edge and the footer goes; below, it is not shown. The server renders both, so CSS alone decides.\n */\n sidebar?: JSX.Element;\n /** The page content, inside the shell's only scroll area. */\n children: JSX.Element;\n /**\n * `false` for content that brings its own heads and scroll areas, such as `AppWorkspace.Main` levels: it fills the\n * main area without the shell's scroll area, and the header shows only as the frame of the next page while a tapped\n * tab's page loads.\n */\n scroll?: boolean;\n class?: string;\n};\n\nexport type MobileShellHeaderProps = {\n title: string;\n /** The title while the shell shows its sidebar, which already names the app; `title` by default. */\n sidebarTitle?: string;\n /**\n * A Back control before the title: a link with `href`, otherwise a button. `withSidebar: false` hides it while the\n * shell shows its sidebar, for a way back to a destination the sidebar lists.\n */\n back?: { href?: string; onClick?: () => void; label: string; withSidebar?: boolean };\n /** Controls after the title, such as a menu. */\n actions?: JSX.Element;\n};\n\n/**\n * On the document element while a shell is the page: `\"sidebar\"` when it shows its sidebar, otherwise empty. A host\n * that renders the shell on the server writes it into its `<html>` too, so the first paint already has it.\n */\nconst SHELL_ATTRIBUTE = \"data-k2b-mobile-shell\";\n/** On the document element while a shell is mounted and a modal dialog is open. */\nconst MODAL_ATTRIBUTE = \"data-k2b-mobile-shell-modal\";\n/** Read by the toast rail, which is portalled outside the shell, so it lives on the body. */\nconst FOOTER_HEIGHT = \"--k2b-mobile-shell-footer-height\";\n/** How much of the scroll area a persistent toast covers; local to the shell. */\nconst TOAST_INSET = \"--k2b-mobile-shell-toast-inset\";\n\n/**\n * The visible part of the toast rail when it holds a toast without a timer (`duration: 0`, running progress, or a\n * custom slot), so the last row of the scroll area can still scroll above it. A rail that sits elsewhere, such as\n * above a dialog, covers nothing.\n */\nconst persistentToastInset = (body: HTMLElement): number => {\n if (document.querySelector(\"dialog:modal\")) return 0;\n const cards = [...document.querySelectorAll<HTMLElement>(\"[data-k2b-toast-container] [data-k2b-toast]:not([data-closing])\")];\n if (!cards.some((card) => card.dataset.persistent === \"true\")) return 0;\n const area = body.getBoundingClientRect();\n const top = Math.min(...cards.map((card) => card.getBoundingClientRect().top));\n return Math.max(0, Math.min(area.height, area.bottom - top));\n};\n\n/** Marks the link whose page is loading; the tab bar shows it as selected. */\nconst PENDING = \"data-k2b-pending\";\n/** On a link: the title of the page it opens. Such a link switches the shell to that page's frame at the first touch. */\nconst PAGE_TITLE = \"data-k2b-title\";\n/** On the root while the shell shows the frame of the page that is loading. */\nconst SWITCHING = \"data-k2b-switching\";\n/** On the header title while the shell switches: the loading page's title, which the title shows instead. */\nconst NEXT_TITLE = \"data-k2b-next-title\";\n\n/** The link a click or press follows as a page load of this origin, or null when it does something else. */\nconst pageLink = (root: HTMLElement, event: MouseEvent): HTMLAnchorElement | null => {\n if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return null;\n const link = event.target instanceof Element ? event.target.closest<HTMLAnchorElement>(\"a[href]\") : null;\n if (!link || !root.contains(link) || link.hasAttribute(\"download\") || (link.target && link.target !== \"_self\")) return null;\n const url = new URL(link.href);\n if (url.origin !== location.origin) return null;\n // A jump inside the page loads nothing.\n if (url.hash && url.pathname === location.pathname && url.search === location.search) return null;\n return link;\n};\n\n/**\n * Taps on the shell's links. iOS shows `:active` only while the page listens to touches, so a tap gets its pressed\n * state at once. A link's page keeps loading while the old page stays visible; a second tap on it would cancel that\n * load and start it over, so it is ignored. A link that names its page's title, such as a tab, shows that page's\n * frame at the first touch instead of at the end of the tap: its title and an empty content area, until the page\n * arrives. Returns the cleanup.\n */\nconst observeLinkTaps = (root: HTMLElement): (() => void) => {\n /** The link marked as the next page. */\n let pending: string | undefined;\n /** Whether its page is loading; a pressed tab waits for its click. */\n let loading = false;\n const clear = () => {\n pending = undefined;\n loading = false;\n for (const link of root.querySelectorAll(`[${PENDING}]`)) link.removeAttribute(PENDING);\n root.removeAttribute(SWITCHING);\n root.querySelector(\".k2b-mobile-shell__title\")?.removeAttribute(NEXT_TITLE);\n };\n const mark = (link: HTMLAnchorElement) => {\n clear();\n pending = link.href;\n link.setAttribute(PENDING, \"\");\n const title = link.getAttribute(PAGE_TITLE);\n const heading = root.querySelector(\".k2b-mobile-shell__title\");\n if (title === null || !heading) return;\n heading.setAttribute(NEXT_TITLE, title);\n root.setAttribute(SWITCHING, \"\");\n };\n const touch = () => {};\n // A press on a tab shows its page's frame while the finger is still down. The page itself loads with the click\n // that ends the tap, as for any link: only the end of a touch counts as the person's action, and a load that\n // started before it could let the browser's Back skip this page.\n const press = (event: PointerEvent) => {\n if (!event.isPrimary) return;\n const link = pageLink(root, event);\n if (!link?.hasAttribute(PAGE_TITLE) || (link.href === pending && loading)) return;\n mark(link);\n };\n // A press that the browser takes over, such as one that turns into a scroll, ends without a click and takes its\n // frame back.\n const cancel = (event: PointerEvent) => {\n if (event.isPrimary && !loading) clear();\n };\n // On the window, so it runs after every handler of the click, including delegated ones that prevent it.\n const click = (event: MouseEvent) => {\n const link = pageLink(root, event);\n if (link && link.href === pending && loading) {\n event.preventDefault();\n return;\n }\n // Any other tap ends the wait, also for a link that answered with a download instead of a page.\n clear();\n if (!link) return;\n mark(link);\n loading = true;\n };\n // iOS sends no click for a tap on content without an action, so the end of a tap anywhere else ends the wait as\n // well. A touch that scrolls ends without a pointerup and keeps a load's wait.\n const release = (event: PointerEvent) => {\n if (pending === undefined) return;\n const link = event.target instanceof Element ? event.target.closest<HTMLAnchorElement>(\"a[href]\") : null;\n if (link?.href !== pending) clear();\n };\n // A page restored from the back/forward cache shows the state it was left in.\n const show = (event: PageTransitionEvent) => {\n if (event.persisted) clear();\n };\n document.addEventListener(\"touchstart\", touch, { passive: true });\n window.addEventListener(\"pointerdown\", press);\n window.addEventListener(\"pointercancel\", cancel);\n window.addEventListener(\"pointerup\", release);\n window.addEventListener(\"click\", click);\n window.addEventListener(\"pageshow\", show);\n return () => {\n document.removeEventListener(\"touchstart\", touch);\n window.removeEventListener(\"pointerdown\", press);\n window.removeEventListener(\"pointercancel\", cancel);\n window.removeEventListener(\"pointerup\", release);\n window.removeEventListener(\"click\", click);\n window.removeEventListener(\"pageshow\", show);\n clear();\n };\n};\n\n/**\n * Keeps a mounted shell working: the footer height on the body, which the portalled toast rail reads, the room a\n * persistent toast takes from the scroll area, the scroll area's edge fade, and immediate feedback for link taps.\n * The fade is the only cue at the footer's edge, which has no rule. `MobileShell` calls it itself;\n * a page that renders the shell on the server without hydrating it calls it once in the browser. Returns the\n * cleanup.\n */\nexport function observeMobileShell(root: HTMLElement): () => void {\n const main = root.querySelector<HTMLElement>(\":scope > .k2b-mobile-shell__main\");\n const body = main?.querySelector<HTMLElement>(\":scope > .k2b-mobile-shell__body\");\n if (!main) return () => {};\n const stopLinkTaps = observeLinkTaps(root);\n // The document says that a shell is the page, for the controls and toasts portalled outside it. An attribute, not\n // `html:has(.k2b-mobile-shell)`: a `:has()` on the document restyles the whole page on every change inside it.\n const documentRoot = root.ownerDocument.documentElement;\n const previousShell = documentRoot.getAttribute(SHELL_ATTRIBUTE);\n documentRoot.setAttribute(SHELL_ATTRIBUTE, root.querySelector(\":scope > .k2b-mobile-shell__sidebar\") ? \"sidebar\" : \"\");\n // Content with its own scroll areas keeps its own fades; the room a toast takes applies to the whole main area.\n const stopScrollFades = body ? installScrollFades(body) : () => {};\n let frame = 0;\n let owner: HTMLElement | null = null;\n let resize: ResizeObserver | undefined;\n const watchOwner = () => {\n const next = root.querySelector<HTMLElement>(\"[data-k2b-shell-bottom]\");\n if (next === owner) return;\n if (owner) resize?.unobserve(owner);\n owner = next;\n if (owner) resize?.observe(owner);\n };\n const measure = () => {\n frame = 0;\n watchOwner();\n const rootBottom = root.getBoundingClientRect().bottom;\n // Content that owns the bottom edge, such as a chat's composer, counts as the footer, so toasts stay above it.\n const owned = owner?.getClientRects().length ? rootBottom - owner.getBoundingClientRect().top : 0;\n const footer = Math.max(0, rootBottom - main.getBoundingClientRect().bottom, owned);\n document.body.style.setProperty(FOOTER_HEIGHT, `${footer}px`);\n root.style.setProperty(TOAST_INSET, `${persistentToastInset(body ?? main)}px`);\n // A modal dialog takes the bottom edge back for its footer; the toast rules read this, not `html:has(dialog:modal)`.\n documentRoot.toggleAttribute(MODAL_ATTRIBUTE, document.querySelector(\"dialog:modal\") !== null);\n };\n const schedule = () => {\n if (!frame) frame = requestAnimationFrame(measure);\n };\n // The footer can appear, disappear, or change height; the main area takes whatever it leaves. Content that owns the\n // bottom edge, such as a composer, grows and shrinks on its own.\n resize = new ResizeObserver(schedule);\n resize.observe(root);\n resize.observe(main);\n measure();\n // Toasts arrive and leave anywhere in the document, and their slots grow and collapse in a transition.\n const mutations = new MutationObserver(schedule);\n mutations.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"data-state\", \"data-closing\", \"data-persistent\", \"open\"],\n });\n document.addEventListener(\"transitionend\", schedule, true);\n return () => {\n if (frame) cancelAnimationFrame(frame);\n resize.disconnect();\n mutations.disconnect();\n document.removeEventListener(\"transitionend\", schedule, true);\n document.body.style.removeProperty(FOOTER_HEIGHT);\n documentRoot.removeAttribute(MODAL_ATTRIBUTE);\n if (previousShell === null) documentRoot.removeAttribute(SHELL_ATTRIBUTE);\n else documentRoot.setAttribute(SHELL_ATTRIBUTE, previousShell);\n stopLinkTaps();\n stopScrollFades();\n };\n}\n\nfunction MobileShellRoot(props: MobileShellProps): JSX.Element {\n let root!: HTMLDivElement;\n\n onMount(() => onCleanup(observeMobileShell(root)));\n return (\n <>\n <div\n ref={root}\n class={props.class ? `k2b-mobile-shell ${props.class}` : \"k2b-mobile-shell\"}\n data-k2b-content-heads={props.scroll === false ? \"\" : undefined}\n >\n {props.sidebar}\n {props.header}\n <main class=\"k2b-mobile-shell__main\">\n <Show when={props.scroll !== false} fallback={props.children}>\n <ScrollArea class=\"k2b-mobile-shell__body\">{props.children}</ScrollArea>\n </Show>\n </main>\n {props.footer}\n </div>\n {/* No pinch zoom on the whole page, portalled dialogs and menus included, also before hydration. iOS ignores\n `user-scalable=no`; it honours touch-action. It lives here, not behind `html:has(.k2b-mobile-shell) *`, which\n would restyle the document on every `:has()` change. Zero specificity, so a component's own touch-action,\n such as a drag handle's `none`, still wins. */}\n <style innerHTML=\":where(html *) { touch-action: pan-x pan-y; }\" />\n </>\n );\n}\n\nfunction MobileShellHeader(props: MobileShellHeaderProps): JSX.Element {\n return (\n <header class=\"k2b-mobile-shell__header\">\n <Show when={props.back}>\n {(back) => (\n <Show\n when={back().href}\n fallback={\n <IconButton\n class=\"k2b-mobile-shell__back\"\n data-with-sidebar={back().withSidebar === false ? \"false\" : undefined}\n label={back().label}\n tooltip={false}\n onClick={() => back().onClick?.()}\n >\n <i class=\"ti ti-chevron-left\" aria-hidden=\"true\" />\n </IconButton>\n }\n >\n {(href) => (\n <IconButtonLink\n class=\"k2b-mobile-shell__back\"\n data-with-sidebar={back().withSidebar === false ? \"false\" : undefined}\n href={href()}\n label={back().label}\n tooltip={false}\n onClick={() => back().onClick?.()}\n >\n <i class=\"ti ti-chevron-left\" aria-hidden=\"true\" />\n </IconButtonLink>\n )}\n </Show>\n )}\n </Show>\n <h1 class=\"k2b-mobile-shell__title\">\n <Show when={props.sidebarTitle !== undefined && props.sidebarTitle !== props.title} fallback={props.title}>\n <span class=\"k2b-mobile-shell__title-narrow\">{props.title}</span>\n <span class=\"k2b-mobile-shell__title-wide\">{props.sidebarTitle}</span>\n </Show>\n </h1>\n <Show when={props.actions}>\n <div class=\"k2b-mobile-shell__actions\">{props.actions}</div>\n </Show>\n </header>\n );\n}\n\nexport type MobileShellSidebarItem = TabBarItem & {\n /**\n * A quiet count after the label, such as open tasks: a number (0 shows nothing) or an element that renders one. The\n * item's `badge`, which calls for attention, takes its place.\n */\n count?: number | JSX.Element;\n};\n\nexport type MobileShellSidebarProps = {\n /** Accessible name of the navigation landmark; usually the tab bar's. */\n label: string;\n /** The app's name in the sidebar's head. */\n title: string;\n /** Address of the app's logo before the name; decorative, the name says it. */\n logo?: string;\n /** Destinations at the top, such as Start. */\n items: readonly MobileShellSidebarItem[];\n /** Named groups below them, such as the apps; a group without items is left out. */\n sections?: readonly { title: string; items: readonly MobileShellSidebarItem[] }[];\n /** Destinations at the bottom edge, such as Settings. */\n footer?: readonly MobileShellSidebarItem[];\n};\n\nfunction SidebarLink(props: { item: MobileShellSidebarItem }): JSX.Element {\n return (\n <a\n href={props.item.href}\n aria-current={props.item.current ? \"page\" : undefined}\n data-tab={props.item.id}\n data-k2b-title={props.item.title ?? props.item.label}\n >\n <i class={props.item.icon} aria-hidden=\"true\" />\n <span class=\"k2b-truncate-fade\">{props.item.label}</span>\n <Show when={props.item.badge ?? props.item.count}>{(mark) => <span class=\"k2b-mobile-shell__sidebar-count\">{mark()}</span>}</Show>\n </a>\n );\n}\n\n/**\n * The navigation of a touch app on a wide screen, in `MobileShell`'s `sidebar`: the app's name, then its destinations\n * as 44 px rows with icon and label, the open one in the action colour. A press shows the item's page frame at once,\n * as on a tab, and the row of a loading page pulses.\n */\nfunction MobileShellSidebar(props: MobileShellSidebarProps): JSX.Element {\n const list = (items: readonly MobileShellSidebarItem[]) => (\n <ul>\n <For each={items}>\n {(item) => (\n <li>\n <SidebarLink item={item} />\n </li>\n )}\n </For>\n </ul>\n );\n return (\n <nav class=\"k2b-mobile-shell__sidebar\" aria-label={props.label}>\n <div class=\"k2b-mobile-shell__sidebar-head\">\n <Show when={props.logo}>{(logo) => <img src={logo()} alt=\"\" width=\"32\" height=\"32\" />}</Show>\n <span class=\"k2b-truncate-fade\">{props.title}</span>\n </div>\n <div class=\"k2b-mobile-shell__sidebar-body\">\n {list(props.items)}\n <For each={(props.sections ?? []).filter((section) => section.items.length > 0)}>\n {(section) => (\n <section>\n <h2>{section.title}</h2>\n {list(section.items)}\n </section>\n )}\n </For>\n </div>\n <Show when={props.footer?.length}>\n <div class=\"k2b-mobile-shell__sidebar-foot\">{list(props.footer ?? [])}</div>\n </Show>\n </nav>\n );\n}\n\n/**\n * The full-screen frame of a phone app: a header, one scroll area, and an optional footer such as a `TabBar`. With a\n * `sidebar`, a window of 48rem and wider shows the sidebar at the start edge instead of the footer, and the toast rail\n * stays in the area beside it. While it is mounted, the document itself never scrolls, pinch zoom and rubber-banding\n * are off, and the toast rail sits above the footer. Mount one per page, as the page's layout.\n */\nexport const MobileShell = Object.assign(MobileShellRoot, { Header: MobileShellHeader, Sidebar: MobileShellSidebar });\n\nexport default MobileShell;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["layout/MobileShell.tsx"],"sourcesContent":["import { For, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { IconButton, IconButtonLink } from \"../actions/Button\";\nimport ScrollArea from \"./ScrollArea\";\nimport { installScrollFades } from \"./scroll-fade\";\nimport type { TabBarItem } from \"./TabBar\";\n\nexport type MobileShellProps = {\n /** Usually `MobileShell.Header`; it sits above the scroll area and pads the top safe area. */\n header?: JSX.Element;\n /** Usually a `TabBar`; it sits below the scroll area and pads the bottom safe area itself. */\n footer?: JSX.Element;\n /**\n * Usually `MobileShell.Sidebar` with the footer's destinations and more. From 48rem of window width it stands at\n * the start edge and the footer goes; below, it is not shown. The server renders both, so CSS alone decides.\n */\n sidebar?: JSX.Element;\n /** The page content, inside the shell's only scroll area. */\n children: JSX.Element;\n /**\n * `false` for content that brings its own heads and scroll areas, such as `AppWorkspace.Main` levels: it fills the\n * main area without the shell's scroll area, and the header shows only as the frame of the next page while a tapped\n * tab's page loads.\n */\n scroll?: boolean;\n /**\n * The content is a screen of its own, such as an open chat on a phone: the footer steps aside, so the content\n * reaches the bottom edge and pads its safe area itself. Content that opens or leaves such a screen in place calls\n * `MobileShell.setScreen`.\n */\n screen?: boolean;\n class?: string;\n};\n\nexport type MobileShellHeaderProps = {\n title: string;\n /** The title while the shell shows its sidebar, which already names the app; `title` by default. */\n sidebarTitle?: string;\n /**\n * A Back control before the title: a link with `href`, otherwise a button. `withSidebar: false` hides it while the\n * shell shows its sidebar, for a way back to a destination the sidebar lists.\n */\n back?: { href?: string; onClick?: () => void; label: string; withSidebar?: boolean };\n /** Controls after the title, such as a menu. */\n actions?: JSX.Element;\n};\n\n/**\n * On the document element while a shell is the page: `\"sidebar\"` when it shows its sidebar, otherwise empty. A host\n * that renders the shell on the server writes it into its `<html>` too, so the first paint already has it.\n */\nconst SHELL_ATTRIBUTE = \"data-k2b-mobile-shell\";\n/** On the document element while a shell is mounted and a modal dialog is open. */\nconst MODAL_ATTRIBUTE = \"data-k2b-mobile-shell-modal\";\n/** Read by the toast rail, which is portalled outside the shell, so it lives on the body. */\nconst FOOTER_HEIGHT = \"--k2b-mobile-shell-footer-height\";\n/** How much of the scroll area a persistent toast covers; local to the shell. */\nconst TOAST_INSET = \"--k2b-mobile-shell-toast-inset\";\n\n/**\n * The visible part of the toast rail when it holds a toast without a timer (`duration: 0`, running progress, or a\n * custom slot), so the last row of the scroll area can still scroll above it. A rail that sits elsewhere, such as\n * above a dialog, covers nothing.\n */\nconst persistentToastInset = (body: HTMLElement): number => {\n if (document.querySelector(\"dialog:modal\")) return 0;\n const cards = [...document.querySelectorAll<HTMLElement>(\"[data-k2b-toast-container] [data-k2b-toast]:not([data-closing])\")];\n if (!cards.some((card) => card.dataset.persistent === \"true\")) return 0;\n const area = body.getBoundingClientRect();\n const top = Math.min(...cards.map((card) => card.getBoundingClientRect().top));\n return Math.max(0, Math.min(area.height, area.bottom - top));\n};\n\n/** On the root while its content is a screen of its own; the footer steps aside. */\nconst SCREEN = \"data-k2b-screen\";\n\n/**\n * Marks the shell around `from` as showing a screen of its own, or not, after the first paint; the server renders\n * the first state with the `screen` prop. Does nothing outside a shell.\n */\nconst setMobileShellScreen = (from: Element, screen: boolean): void => {\n const root = from.closest(\".k2b-mobile-shell\");\n if (!root) return;\n if (screen) root.setAttribute(SCREEN, \"\");\n else root.removeAttribute(SCREEN);\n};\n\n/** Marks the link whose page is loading; the tab bar shows it as selected. */\nconst PENDING = \"data-k2b-pending\";\n/** On a link: the title of the page it opens. Such a link switches the shell to that page's frame at the first touch. */\nconst PAGE_TITLE = \"data-k2b-title\";\n/** On the root while the shell shows the frame of the page that is loading. */\nconst SWITCHING = \"data-k2b-switching\";\n/** On the header title while the shell switches: the loading page's title, which the title shows instead. */\nconst NEXT_TITLE = \"data-k2b-next-title\";\n\n/** The link a click or press follows as a page load of this origin, or null when it does something else. */\nconst pageLink = (root: HTMLElement, event: MouseEvent): HTMLAnchorElement | null => {\n if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return null;\n const link = event.target instanceof Element ? event.target.closest<HTMLAnchorElement>(\"a[href]\") : null;\n if (!link || !root.contains(link) || link.hasAttribute(\"download\") || (link.target && link.target !== \"_self\")) return null;\n const url = new URL(link.href);\n if (url.origin !== location.origin) return null;\n // A jump inside the page loads nothing.\n if (url.hash && url.pathname === location.pathname && url.search === location.search) return null;\n return link;\n};\n\n/**\n * Taps on the shell's links. iOS shows `:active` only while the page listens to touches, so a tap gets its pressed\n * state at once. A link's page keeps loading while the old page stays visible; a second tap on it would cancel that\n * load and start it over, so it is ignored. A link that names its page's title, such as a tab, shows that page's\n * frame at the first touch instead of at the end of the tap: its title and an empty content area, until the page\n * arrives. Returns the cleanup.\n */\nconst observeLinkTaps = (root: HTMLElement): (() => void) => {\n /** The link marked as the next page. */\n let pending: string | undefined;\n /** Whether its page is loading; a pressed tab waits for its click. */\n let loading = false;\n const clear = () => {\n pending = undefined;\n loading = false;\n for (const link of root.querySelectorAll(`[${PENDING}]`)) link.removeAttribute(PENDING);\n root.removeAttribute(SWITCHING);\n root.querySelector(\".k2b-mobile-shell__title\")?.removeAttribute(NEXT_TITLE);\n };\n const mark = (link: HTMLAnchorElement) => {\n clear();\n pending = link.href;\n link.setAttribute(PENDING, \"\");\n const title = link.getAttribute(PAGE_TITLE);\n const heading = root.querySelector(\".k2b-mobile-shell__title\");\n if (title === null || !heading) return;\n heading.setAttribute(NEXT_TITLE, title);\n root.setAttribute(SWITCHING, \"\");\n };\n const touch = () => {};\n // A press on a tab shows its page's frame while the finger is still down. The page itself loads with the click\n // that ends the tap, as for any link: only the end of a touch counts as the person's action, and a load that\n // started before it could let the browser's Back skip this page.\n const press = (event: PointerEvent) => {\n if (!event.isPrimary) return;\n const link = pageLink(root, event);\n if (!link?.hasAttribute(PAGE_TITLE) || (link.href === pending && loading)) return;\n mark(link);\n };\n // A press that the browser takes over, such as one that turns into a scroll, ends without a click and takes its\n // frame back.\n const cancel = (event: PointerEvent) => {\n if (event.isPrimary && !loading) clear();\n };\n // On the window, so it runs after every handler of the click, including delegated ones that prevent it.\n const click = (event: MouseEvent) => {\n const link = pageLink(root, event);\n if (link && link.href === pending && loading) {\n event.preventDefault();\n return;\n }\n // Any other tap ends the wait, also for a link that answered with a download instead of a page.\n clear();\n if (!link) return;\n mark(link);\n loading = true;\n };\n // iOS sends no click for a tap on content without an action, so the end of a tap anywhere else ends the wait as\n // well. A touch that scrolls ends without a pointerup and keeps a load's wait.\n const release = (event: PointerEvent) => {\n if (pending === undefined) return;\n const link = event.target instanceof Element ? event.target.closest<HTMLAnchorElement>(\"a[href]\") : null;\n if (link?.href !== pending) clear();\n };\n // A page restored from the back/forward cache shows the state it was left in.\n const show = (event: PageTransitionEvent) => {\n if (event.persisted) clear();\n };\n document.addEventListener(\"touchstart\", touch, { passive: true });\n window.addEventListener(\"pointerdown\", press);\n window.addEventListener(\"pointercancel\", cancel);\n window.addEventListener(\"pointerup\", release);\n window.addEventListener(\"click\", click);\n window.addEventListener(\"pageshow\", show);\n return () => {\n document.removeEventListener(\"touchstart\", touch);\n window.removeEventListener(\"pointerdown\", press);\n window.removeEventListener(\"pointercancel\", cancel);\n window.removeEventListener(\"pointerup\", release);\n window.removeEventListener(\"click\", click);\n window.removeEventListener(\"pageshow\", show);\n clear();\n };\n};\n\n/**\n * Keeps a mounted shell working: the footer height on the body, which the portalled toast rail reads, the room a\n * persistent toast takes from the scroll area, the scroll area's edge fade, and immediate feedback for link taps.\n * The fade is the only cue at the footer's edge, which has no rule. `MobileShell` calls it itself;\n * a page that renders the shell on the server without hydrating it calls it once in the browser. Returns the\n * cleanup.\n */\nexport function observeMobileShell(root: HTMLElement): () => void {\n const main = root.querySelector<HTMLElement>(\":scope > .k2b-mobile-shell__main\");\n const body = main?.querySelector<HTMLElement>(\":scope > .k2b-mobile-shell__body\");\n if (!main) return () => {};\n const stopLinkTaps = observeLinkTaps(root);\n // The document says that a shell is the page, for the controls and toasts portalled outside it. An attribute, not\n // `html:has(.k2b-mobile-shell)`: a `:has()` on the document restyles the whole page on every change inside it.\n const documentRoot = root.ownerDocument.documentElement;\n const previousShell = documentRoot.getAttribute(SHELL_ATTRIBUTE);\n documentRoot.setAttribute(SHELL_ATTRIBUTE, root.querySelector(\":scope > .k2b-mobile-shell__sidebar\") ? \"sidebar\" : \"\");\n // Content with its own scroll areas keeps its own fades; the room a toast takes applies to the whole main area.\n const stopScrollFades = body ? installScrollFades(body) : () => {};\n let frame = 0;\n let owner: HTMLElement | null = null;\n let resize: ResizeObserver | undefined;\n const watchOwner = () => {\n const next = root.querySelector<HTMLElement>(\"[data-k2b-shell-bottom]\");\n if (next === owner) return;\n if (owner) resize?.unobserve(owner);\n owner = next;\n if (owner) resize?.observe(owner);\n };\n const measure = () => {\n frame = 0;\n watchOwner();\n const rootBottom = root.getBoundingClientRect().bottom;\n // Content that owns the bottom edge, such as a chat's composer, counts as the footer, so toasts stay above it.\n const owned = owner?.getClientRects().length ? rootBottom - owner.getBoundingClientRect().top : 0;\n const footer = Math.max(0, rootBottom - main.getBoundingClientRect().bottom, owned);\n document.body.style.setProperty(FOOTER_HEIGHT, `${footer}px`);\n root.style.setProperty(TOAST_INSET, `${persistentToastInset(body ?? main)}px`);\n // A modal dialog takes the bottom edge back for its footer; the toast rules read this, not `html:has(dialog:modal)`.\n documentRoot.toggleAttribute(MODAL_ATTRIBUTE, document.querySelector(\"dialog:modal\") !== null);\n };\n const schedule = () => {\n if (!frame) frame = requestAnimationFrame(measure);\n };\n // The footer can appear, disappear, or change height; the main area takes whatever it leaves. Content that owns the\n // bottom edge, such as a composer, grows and shrinks on its own.\n resize = new ResizeObserver(schedule);\n resize.observe(root);\n resize.observe(main);\n measure();\n // Toasts arrive and leave anywhere in the document, and their slots grow and collapse in a transition.\n const mutations = new MutationObserver(schedule);\n mutations.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"data-state\", \"data-closing\", \"data-persistent\", \"open\"],\n });\n document.addEventListener(\"transitionend\", schedule, true);\n return () => {\n if (frame) cancelAnimationFrame(frame);\n resize.disconnect();\n mutations.disconnect();\n document.removeEventListener(\"transitionend\", schedule, true);\n document.body.style.removeProperty(FOOTER_HEIGHT);\n documentRoot.removeAttribute(MODAL_ATTRIBUTE);\n if (previousShell === null) documentRoot.removeAttribute(SHELL_ATTRIBUTE);\n else documentRoot.setAttribute(SHELL_ATTRIBUTE, previousShell);\n stopLinkTaps();\n stopScrollFades();\n };\n}\n\nfunction MobileShellRoot(props: MobileShellProps): JSX.Element {\n let root!: HTMLDivElement;\n\n onMount(() => onCleanup(observeMobileShell(root)));\n return (\n <>\n <div\n ref={root}\n class={props.class ? `k2b-mobile-shell ${props.class}` : \"k2b-mobile-shell\"}\n data-k2b-content-heads={props.scroll === false ? \"\" : undefined}\n data-k2b-screen={props.screen ? \"\" : undefined}\n >\n {props.sidebar}\n {props.header}\n <main class=\"k2b-mobile-shell__main\">\n <Show when={props.scroll !== false} fallback={props.children}>\n <ScrollArea class=\"k2b-mobile-shell__body\">{props.children}</ScrollArea>\n </Show>\n </main>\n {props.footer}\n </div>\n {/* No pinch zoom on the whole page, portalled dialogs and menus included, also before hydration. iOS ignores\n `user-scalable=no`; it honours touch-action. It lives here, not behind `html:has(.k2b-mobile-shell) *`, which\n would restyle the document on every `:has()` change. Zero specificity, so a component's own touch-action,\n such as a drag handle's `none`, still wins. */}\n <style innerHTML=\":where(html *) { touch-action: pan-x pan-y; }\" />\n </>\n );\n}\n\nfunction MobileShellHeader(props: MobileShellHeaderProps): JSX.Element {\n return (\n <header class=\"k2b-mobile-shell__header\">\n <Show when={props.back}>\n {(back) => (\n <Show\n when={back().href}\n fallback={\n <IconButton\n class=\"k2b-mobile-shell__back\"\n data-with-sidebar={back().withSidebar === false ? \"false\" : undefined}\n label={back().label}\n tooltip={false}\n onClick={() => back().onClick?.()}\n >\n <i class=\"ti ti-chevron-left\" aria-hidden=\"true\" />\n </IconButton>\n }\n >\n {(href) => (\n <IconButtonLink\n class=\"k2b-mobile-shell__back\"\n data-with-sidebar={back().withSidebar === false ? \"false\" : undefined}\n href={href()}\n label={back().label}\n tooltip={false}\n onClick={() => back().onClick?.()}\n >\n <i class=\"ti ti-chevron-left\" aria-hidden=\"true\" />\n </IconButtonLink>\n )}\n </Show>\n )}\n </Show>\n <h1 class=\"k2b-mobile-shell__title\">\n <Show when={props.sidebarTitle !== undefined && props.sidebarTitle !== props.title} fallback={props.title}>\n <span class=\"k2b-mobile-shell__title-narrow\">{props.title}</span>\n <span class=\"k2b-mobile-shell__title-wide\">{props.sidebarTitle}</span>\n </Show>\n </h1>\n <Show when={props.actions}>\n <div class=\"k2b-mobile-shell__actions\">{props.actions}</div>\n </Show>\n </header>\n );\n}\n\nexport type MobileShellSidebarItem = TabBarItem & {\n /**\n * A quiet count after the label, such as open tasks: a number (0 shows nothing) or an element that renders one. The\n * item's `badge`, which calls for attention, takes its place.\n */\n count?: number | JSX.Element;\n};\n\nexport type MobileShellSidebarProps = {\n /** Accessible name of the navigation landmark; usually the tab bar's. */\n label: string;\n /** The app's name in the sidebar's head. */\n title: string;\n /** Address of the app's logo before the name; decorative, the name says it. */\n logo?: string;\n /** Destinations at the top, such as Start. */\n items: readonly MobileShellSidebarItem[];\n /** Named groups below them, such as the apps; a group without items is left out. */\n sections?: readonly { title: string; items: readonly MobileShellSidebarItem[] }[];\n /** Destinations at the bottom edge, such as Settings. */\n footer?: readonly MobileShellSidebarItem[];\n};\n\nfunction SidebarLink(props: { item: MobileShellSidebarItem }): JSX.Element {\n return (\n <a\n href={props.item.href}\n aria-current={props.item.current ? \"page\" : undefined}\n data-tab={props.item.id}\n data-k2b-title={props.item.title ?? props.item.label}\n >\n <i class={props.item.icon} aria-hidden=\"true\" />\n <span class=\"k2b-truncate-fade\">{props.item.label}</span>\n <Show when={props.item.badge ?? props.item.count}>{(mark) => <span class=\"k2b-mobile-shell__sidebar-count\">{mark()}</span>}</Show>\n </a>\n );\n}\n\n/**\n * The navigation of a touch app on a wide screen, in `MobileShell`'s `sidebar`: the app's name, then its destinations\n * as 44 px rows with icon and label, the open one in the action colour. A press shows the item's page frame at once,\n * as on a tab, and the row of a loading page pulses.\n */\nfunction MobileShellSidebar(props: MobileShellSidebarProps): JSX.Element {\n const list = (items: readonly MobileShellSidebarItem[]) => (\n <ul>\n <For each={items}>\n {(item) => (\n <li>\n <SidebarLink item={item} />\n </li>\n )}\n </For>\n </ul>\n );\n return (\n <nav class=\"k2b-mobile-shell__sidebar\" aria-label={props.label}>\n <div class=\"k2b-mobile-shell__sidebar-head\">\n <Show when={props.logo}>{(logo) => <img src={logo()} alt=\"\" width=\"32\" height=\"32\" />}</Show>\n <span class=\"k2b-truncate-fade\">{props.title}</span>\n </div>\n <div class=\"k2b-mobile-shell__sidebar-body\">\n {list(props.items)}\n <For each={(props.sections ?? []).filter((section) => section.items.length > 0)}>\n {(section) => (\n <section>\n <h2>{section.title}</h2>\n {list(section.items)}\n </section>\n )}\n </For>\n </div>\n <Show when={props.footer?.length}>\n <div class=\"k2b-mobile-shell__sidebar-foot\">{list(props.footer ?? [])}</div>\n </Show>\n </nav>\n );\n}\n\n/**\n * The full-screen frame of a phone app: a header, one scroll area, and an optional footer such as a `TabBar`. With a\n * `sidebar`, a window of 48rem and wider shows the sidebar at the start edge instead of the footer, and the toast rail\n * stays in the area beside it. While it is mounted, the document itself never scrolls, pinch zoom and rubber-banding\n * are off, and the toast rail sits above the footer. Mount one per page, as the page's layout.\n */\nexport const MobileShell = Object.assign(MobileShellRoot, {\n Header: MobileShellHeader,\n Sidebar: MobileShellSidebar,\n setScreen: setMobileShellScreen,\n});\n\nexport default MobileShell;\n"],"mappings":"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","ignoreList":[]}
@@ -56,6 +56,8 @@ const detailSectionMessages = i18n.define({
56
56
  names,
57
57
  more
58
58
  }) => more > 0 ? `Links to ${names} and ${more} more` : `Links to ${names}`,
59
+ linksLoading: "Loading links",
60
+ linksFailed: "Could not load all links",
59
61
  properties: "Properties",
60
62
  tags: "Tags"
61
63
  },
@@ -110,6 +112,8 @@ const detailSectionMessages = i18n.define({
110
112
  names,
111
113
  more
112
114
  }) => more > 0 ? `Verweist auf ${names} und ${more} weitere` : `Verweist auf ${names}`,
115
+ linksLoading: "Lädt Verknüpfungen",
116
+ linksFailed: "Nicht alle Verknüpfungen konnten geladen werden",
113
117
  properties: "Eigenschaften",
114
118
  tags: "Tags"
115
119
  }
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["layout/detail-sections-messages.ts"],"sourcesContent":["import { i18n } from \"@k2b/stdlib\";\nimport { useLocale } from \"../intl/locale\";\n\n/** Titles and sentences of the shared detail sections: presence, access, links, properties, and tags. */\nconst detailSectionMessages = i18n.define({\n baseLocale: \"en\",\n messages: {\n en: {\n hereNow: \"Here now\",\n onlyYou: \"Only you\",\n you: \"You\",\n writesIn: \"in\",\n writing: \"writing\",\n reading: \"reading\",\n readingAlong: ({ names, count }: { names: string; count: number }) =>\n count > 2 ? `${count} reading along` : `${names} ${count === 1 ? \"is\" : \"are\"} reading along`,\n and: \"and\",\n jumpTo: ({ name, place }: { name: string; place: string }) => `${name}, writing in “${place}”. Jump there`,\n personWriting: ({ name, place }: { name: string; place: string }) => (place ? `${name}, writing in “${place}”` : `${name}, writing`),\n personReading: ({ name }: { name: string }) => `${name}, reading`,\n everyoneHere: ({ count }: { count: number }) => `Here now: all ${count}, with you`,\n presenceLoading: \"Loading who is here\",\n presenceUnavailable: \"Presence is unavailable right now\",\n retry: \"Try again\",\n access: \"Access\",\n accessLoading: \"Loading who has access\",\n accessFailed: \"Could not load who has access\",\n accessSummary: ({ names, more }: { names: string; more: number }) => (more > 0 ? `${names} and ${more} more` : names),\n links: \"Links\",\n linkedBy: ({ count }: { count: number }) => `Linked from ${count}`,\n linksTo: ({ count }: { count: number }) => `Links to ${count}`,\n linkedBySummary: ({ names, more }: { names: string; more: number }) =>\n more > 0 ? `Linked from ${names} and ${more} more` : `Linked from ${names}`,\n linksToSummary: ({ names, more }: { names: string; more: number }) =>\n more > 0 ? `Links to ${names} and ${more} more` : `Links to ${names}`,\n properties: \"Properties\",\n tags: \"Tags\",\n },\n de: {\n hereNow: \"Gerade hier\",\n onlyYou: \"Nur du\",\n you: \"Du\",\n writesIn: \"in\",\n writing: \"schreibt\",\n reading: \"liest\",\n readingAlong: ({ names, count }) => (count > 2 ? `${count} lesen mit` : `${names} ${count === 1 ? \"liest\" : \"lesen\"} mit`),\n and: \"und\",\n jumpTo: ({ name, place }) => `${name}, schreibt in „${place}“. Zur Stelle springen`,\n personWriting: ({ name, place }) => (place ? `${name}, schreibt in „${place}“` : `${name}, schreibt`),\n personReading: ({ name }) => `${name}, liest`,\n everyoneHere: ({ count }) => `Gerade hier: alle ${count}, mit dir`,\n presenceLoading: \"Lädt, wer gerade hier ist\",\n presenceUnavailable: \"Anwesenheit gerade nicht verfügbar\",\n retry: \"Erneut versuchen\",\n access: \"Zugriff\",\n accessLoading: \"Lädt, wer Zugriff hat\",\n accessFailed: \"Zugriff konnte nicht geladen werden\",\n accessSummary: ({ names, more }) => (more > 0 ? `${names} und ${more} weitere` : names),\n links: \"Verknüpfungen\",\n linkedBy: ({ count }) => `Verlinkt von ${count}`,\n linksTo: ({ count }) => `Verweist auf ${count}`,\n linkedBySummary: ({ names, more }) => (more > 0 ? `Verlinkt von ${names} und ${more} weiteren` : `Verlinkt von ${names}`),\n linksToSummary: ({ names, more }) => (more > 0 ? `Verweist auf ${names} und ${more} weitere` : `Verweist auf ${names}`),\n properties: \"Eigenschaften\",\n tags: \"Tags\",\n },\n },\n});\n\nexport type DetailSectionMessages = ReturnType<(typeof detailSectionMessages)[\"resolve\"]>[\"t\"];\n\nexport const useDetailSectionMessages = (): (() => DetailSectionMessages) => {\n const locale = useLocale();\n return () => detailSectionMessages.resolve([locale()]).t;\n};\n\nexport const checkDetailSectionMessages = () => detailSectionMessages.check();\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["layout/detail-sections-messages.ts"],"sourcesContent":["import { i18n } from \"@k2b/stdlib\";\nimport { useLocale } from \"../intl/locale\";\n\n/** Titles and sentences of the shared detail sections: presence, access, links, properties, and tags. */\nconst detailSectionMessages = i18n.define({\n baseLocale: \"en\",\n messages: {\n en: {\n hereNow: \"Here now\",\n onlyYou: \"Only you\",\n you: \"You\",\n writesIn: \"in\",\n writing: \"writing\",\n reading: \"reading\",\n readingAlong: ({ names, count }: { names: string; count: number }) =>\n count > 2 ? `${count} reading along` : `${names} ${count === 1 ? \"is\" : \"are\"} reading along`,\n and: \"and\",\n jumpTo: ({ name, place }: { name: string; place: string }) => `${name}, writing in “${place}”. Jump there`,\n personWriting: ({ name, place }: { name: string; place: string }) => (place ? `${name}, writing in “${place}”` : `${name}, writing`),\n personReading: ({ name }: { name: string }) => `${name}, reading`,\n everyoneHere: ({ count }: { count: number }) => `Here now: all ${count}, with you`,\n presenceLoading: \"Loading who is here\",\n presenceUnavailable: \"Presence is unavailable right now\",\n retry: \"Try again\",\n access: \"Access\",\n accessLoading: \"Loading who has access\",\n accessFailed: \"Could not load who has access\",\n accessSummary: ({ names, more }: { names: string; more: number }) => (more > 0 ? `${names} and ${more} more` : names),\n links: \"Links\",\n linkedBy: ({ count }: { count: number }) => `Linked from ${count}`,\n linksTo: ({ count }: { count: number }) => `Links to ${count}`,\n linkedBySummary: ({ names, more }: { names: string; more: number }) =>\n more > 0 ? `Linked from ${names} and ${more} more` : `Linked from ${names}`,\n linksToSummary: ({ names, more }: { names: string; more: number }) =>\n more > 0 ? `Links to ${names} and ${more} more` : `Links to ${names}`,\n linksLoading: \"Loading links\",\n linksFailed: \"Could not load all links\",\n properties: \"Properties\",\n tags: \"Tags\",\n },\n de: {\n hereNow: \"Gerade hier\",\n onlyYou: \"Nur du\",\n you: \"Du\",\n writesIn: \"in\",\n writing: \"schreibt\",\n reading: \"liest\",\n readingAlong: ({ names, count }) => (count > 2 ? `${count} lesen mit` : `${names} ${count === 1 ? \"liest\" : \"lesen\"} mit`),\n and: \"und\",\n jumpTo: ({ name, place }) => `${name}, schreibt in „${place}“. Zur Stelle springen`,\n personWriting: ({ name, place }) => (place ? `${name}, schreibt in „${place}“` : `${name}, schreibt`),\n personReading: ({ name }) => `${name}, liest`,\n everyoneHere: ({ count }) => `Gerade hier: alle ${count}, mit dir`,\n presenceLoading: \"Lädt, wer gerade hier ist\",\n presenceUnavailable: \"Anwesenheit gerade nicht verfügbar\",\n retry: \"Erneut versuchen\",\n access: \"Zugriff\",\n accessLoading: \"Lädt, wer Zugriff hat\",\n accessFailed: \"Zugriff konnte nicht geladen werden\",\n accessSummary: ({ names, more }) => (more > 0 ? `${names} und ${more} weitere` : names),\n links: \"Verknüpfungen\",\n linkedBy: ({ count }) => `Verlinkt von ${count}`,\n linksTo: ({ count }) => `Verweist auf ${count}`,\n linkedBySummary: ({ names, more }) => (more > 0 ? `Verlinkt von ${names} und ${more} weiteren` : `Verlinkt von ${names}`),\n linksToSummary: ({ names, more }) => (more > 0 ? `Verweist auf ${names} und ${more} weitere` : `Verweist auf ${names}`),\n linksLoading: \"Lädt Verknüpfungen\",\n linksFailed: \"Nicht alle Verknüpfungen konnten geladen werden\",\n properties: \"Eigenschaften\",\n tags: \"Tags\",\n },\n },\n});\n\nexport type DetailSectionMessages = ReturnType<(typeof detailSectionMessages)[\"resolve\"]>[\"t\"];\n\nexport const useDetailSectionMessages = (): (() => DetailSectionMessages) => {\n const locale = useLocale();\n return () => detailSectionMessages.resolve([locale()]).t;\n};\n\nexport const checkDetailSectionMessages = () => detailSectionMessages.check();\n"],"mappings":"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","ignoreList":[]}
@@ -1,6 +1,7 @@
1
1
  export { AnchoredPopover } from "./AnchoredPopover";
2
2
  export { default as AppOverview } from "./AppOverview";
3
3
  export { appWorkspaceDetailElementId, default as AppWorkspace } from "./AppWorkspace";
4
+ export { AppWorkspaceSidebarItemStatus } from "./AppWorkspaceSidebarItemStatus";
4
5
  export { watchAppHostWidth } from "./app-host-width";
5
6
  export { installAppWorkspaceController, parkWorkspaceDetailDrawers } from "./app-workspace-controller";
6
7
  export { APP_WORKSPACE_DETAIL_DEFAULT, APP_WORKSPACE_DETAIL_MAX, APP_WORKSPACE_DETAIL_MIN, APP_WORKSPACE_DRAWER_DEFAULT, APP_WORKSPACE_DRAWER_MAX, APP_WORKSPACE_DRAWER_MIN, APP_WORKSPACE_MAIN_MIN, APP_WORKSPACE_MAIN_MIN_HEIGHT, APP_WORKSPACE_PANE_DEFAULT, APP_WORKSPACE_PANE_MAX, APP_WORKSPACE_PANE_MIN, APP_WORKSPACE_SIDEBAR_COLLAPSE_THRESHOLD, APP_WORKSPACE_SIDEBAR_COLLAPSED, APP_WORKSPACE_SIDEBAR_DEFAULT, APP_WORKSPACE_SIDEBAR_MAX, APP_WORKSPACE_SIDEBAR_MIN, appWorkspaceLayoutStyle, appWorkspacePanelVariable, appWorkspaceResizeLimits, normalizeAppWorkspaceLayoutState, parseAppWorkspaceLayoutState, resolveAppWorkspaceSidebarWidth, safeAppWorkspacePanelId, serializeAppWorkspaceLayoutState, shouldCollapseAppWorkspaceSidebar } from "./app-workspace-state";
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["layout/index.ts"],"sourcesContent":["export { AnchoredPopover, type AnchoredPopoverProps } from \"./AnchoredPopover\";\nexport type {\n AppOverviewCardsProps,\n AppOverviewEmptyStateProps,\n AppOverviewPanelProps,\n AppOverviewProps,\n} from \"./AppOverview\";\nexport { default as AppOverview } from \"./AppOverview\";\nexport type {\n AppWorkspaceBottomDrawerHeight,\n AppWorkspaceBottomDrawerProps,\n AppWorkspaceContentProps,\n AppWorkspaceDetailProps,\n AppWorkspaceDetailWidth,\n AppWorkspaceHeadProps,\n AppWorkspaceMainPaneProps,\n AppWorkspaceMainProps,\n AppWorkspaceNavTreeItemProps,\n AppWorkspaceNavTreeMove,\n AppWorkspaceNavTreeProps,\n AppWorkspaceProps,\n AppWorkspaceSidebarAccessoryVisibility,\n AppWorkspaceSidebarBodyProps,\n AppWorkspaceSidebarIconActionProps,\n AppWorkspaceSidebarIconActionTone,\n AppWorkspaceSidebarIconGridProps,\n AppWorkspaceSidebarItemActionProps,\n AppWorkspaceSidebarItemActionsProps,\n AppWorkspaceSidebarItemIconProps,\n AppWorkspaceSidebarItemLabelProps,\n AppWorkspaceSidebarItemMetaProps,\n AppWorkspaceSidebarItemProps,\n AppWorkspaceSidebarItemStatusProps,\n AppWorkspaceSidebarItemTone,\n AppWorkspaceSidebarProps,\n AppWorkspaceSidebarSectionProps,\n AppWorkspaceSidebarVisibility,\n AppWorkspaceWidthShare,\n} from \"./AppWorkspace\";\nexport { appWorkspaceDetailElementId, default as AppWorkspace } from \"./AppWorkspace\";\nexport { watchAppHostWidth } from \"./app-host-width\";\nexport type { AppWorkspaceControllerOptions } from \"./app-workspace-controller\";\nexport { installAppWorkspaceController, parkWorkspaceDetailDrawers } from \"./app-workspace-controller\";\nexport type {\n AppWorkspaceLayoutState,\n AppWorkspaceResizeKind,\n} from \"./app-workspace-state\";\nexport {\n APP_WORKSPACE_DETAIL_DEFAULT,\n APP_WORKSPACE_DETAIL_MAX,\n APP_WORKSPACE_DETAIL_MIN,\n APP_WORKSPACE_DRAWER_DEFAULT,\n APP_WORKSPACE_DRAWER_MAX,\n APP_WORKSPACE_DRAWER_MIN,\n APP_WORKSPACE_MAIN_MIN,\n APP_WORKSPACE_MAIN_MIN_HEIGHT,\n APP_WORKSPACE_PANE_DEFAULT,\n APP_WORKSPACE_PANE_MAX,\n APP_WORKSPACE_PANE_MIN,\n APP_WORKSPACE_SIDEBAR_COLLAPSE_THRESHOLD,\n APP_WORKSPACE_SIDEBAR_COLLAPSED,\n APP_WORKSPACE_SIDEBAR_DEFAULT,\n APP_WORKSPACE_SIDEBAR_MAX,\n APP_WORKSPACE_SIDEBAR_MIN,\n appWorkspaceLayoutStyle,\n appWorkspacePanelVariable,\n appWorkspaceResizeLimits,\n normalizeAppWorkspaceLayoutState,\n parseAppWorkspaceLayoutState,\n resolveAppWorkspaceSidebarWidth,\n safeAppWorkspacePanelId,\n serializeAppWorkspaceLayoutState,\n shouldCollapseAppWorkspaceSidebar,\n} from \"./app-workspace-state\";\nexport { type BottomSheetProps, bottomSheetAdaptiveOptions, bottomSheetOptions, default as BottomSheet } from \"./BottomSheet\";\nexport type { DataPanelProps } from \"./DataPanel\";\nexport { DataPanel } from \"./DataPanel\";\nexport type {\n DetailPanelActionButtonProps,\n DetailPanelActionLinkProps,\n DetailPanelActionProps,\n DetailPanelActionSecondary,\n DetailPanelBodyProps,\n DetailPanelGroupProps,\n DetailPanelHeaderProps,\n DetailPanelProps,\n DetailPanelRowProps,\n DetailPanelSectionProps,\n DetailPanelSummaryProps,\n DetailPanelTone,\n} from \"./DetailPanel\";\nexport { default as DetailPanel } from \"./DetailPanel\";\nexport type {\n DetailAccessEntry,\n DetailAccessProps,\n DetailLinkItem,\n DetailLinksProps,\n DetailPresencePerson,\n DetailPresenceProps,\n DetailPresenceState,\n DetailPropertiesProps,\n DetailProperty,\n DetailTag,\n DetailTagsProps,\n} from \"./DetailSections\";\nexport { DetailAccess, DetailLinks, DetailPresence, DetailPresenceSlot, DetailProperties, DetailTags } from \"./DetailSections\";\nexport { DETAILS_ICON, DetailsToggle, type DetailsToggleProps } from \"./DetailsToggle\";\nexport type { DiscussionComposerProps, DiscussionItemProps, DiscussionListProps, DiscussionProps } from \"./Discussion\";\nexport { default as Discussion } from \"./Discussion\";\nexport type {\n FloatingWindowClose,\n FloatingWindowProps,\n OpenFloatingWindowOptions,\n} from \"./FloatingWindow\";\nexport {\n default as FloatingWindow,\n type FloatingWindowRect,\n fitFloatingWindowRect,\n openFloatingWindow,\n} from \"./FloatingWindow\";\nexport type { MobileShellHeaderProps, MobileShellProps, MobileShellSidebarItem, MobileShellSidebarProps } from \"./MobileShell\";\nexport { default as MobileShell, observeMobileShell } from \"./MobileShell\";\nexport { default as Navigation, type NavigationProps } from \"./Navigation\";\nexport {\n createNavigation,\n findNavigationItem,\n type NavigationController,\n type NavigationItem,\n type NavigationOptions,\n type NavigationStatus,\n} from \"./navigation-model\";\nexport type { PageTitleProps, PageTrailLink, PageTrailState } from \"./PageTitle\";\nexport { followPageTrail, PAGE_TRAIL_EVENT, PageTitle, PageTrailProvider, readPageTrail, setPageTrail, usePageTrail } from \"./PageTitle\";\nexport type {\n PanelDialogBodyProps,\n PanelDialogFooterProps,\n PanelDialogHeaderProps,\n PanelDialogProps,\n PanelDialogSectionProps,\n PanelDialogSurface,\n PanelDialogTabOption,\n PanelDialogTabsProps,\n} from \"./PanelDialog\";\nexport {\n confirmDiscardIfDirty,\n default as PanelDialog,\n panelDialogFixedOptions,\n panelDialogFixedPanelClass,\n panelDialogOptions,\n panelDialogPanelClass,\n panelDialogWideOptions,\n panelDialogWidePanelClass,\n panelDialogWorkspaceOptions,\n panelDialogWorkspacePanelClass,\n} from \"./PanelDialog\";\nexport type { PanelHeaderProps } from \"./PanelHeader\";\nexport { PanelHeader } from \"./PanelHeader\";\nexport type { PanesItem, PanesProps } from \"./Panes\";\nexport { default as Panes } from \"./Panes\";\nexport type { PullToRefreshProps, PullToRefreshState } from \"./PullToRefresh\";\nexport { default as PullToRefresh } from \"./PullToRefresh\";\nexport { installPageTitleController } from \"./page-title-controller\";\nexport type {\n AddPanesItemOptions,\n PanesDirection,\n PanesGroup,\n PanesIntent,\n PanesLayout,\n PanesNode,\n PanesPath,\n PanesPathSegment,\n PanesSide,\n PanesSplit,\n} from \"./panes-layout\";\nexport {\n activatePanesItem,\n addPanesItem,\n applyPanesIntent,\n createPanesLayout,\n isPanesItemVisible,\n PANES_LAYOUT_VERSION,\n parsePanesLayout,\n reconcilePanesLayout,\n removePanesItem,\n resizePanesSplit,\n} from \"./panes-layout\";\nexport { default as ResizeSeparator, type ResizeSeparatorProps } from \"./ResizeSeparator\";\nexport { attachResizeSeparator, type ResizeSeparatorOptions } from \"./resize-separator\";\nexport type { ScrollAreaProps } from \"./ScrollArea\";\nexport { default as ScrollArea } from \"./ScrollArea\";\nexport type {\n SaveStatusProps,\n SaveStatusState,\n SettingsFieldControlProps,\n SettingsFieldProps,\n SettingsFieldWidth,\n SettingsGroupActionProps,\n SettingsGroupProps,\n SettingsPageProps,\n SettingsPanelFooterProps,\n SettingsSaveBarProps,\n SettingsSectionProps,\n} from \"./Settings\";\nexport {\n readSettingsError,\n SaveStatus,\n SettingsField,\n SettingsGroup,\n SettingsPage,\n SettingsPanelFooter,\n SettingsSaveBar,\n SettingsSection,\n sameSettingValue,\n} from \"./Settings\";\nexport type {\n SettingsCollectionActionProps,\n SettingsCollectionItemActionsProps,\n SettingsCollectionItemProps,\n SettingsCollectionItemReorderProps,\n SettingsCollectionItemStatusProps,\n SettingsCollectionProps,\n} from \"./SettingsCollection\";\nexport { default as SettingsCollection } from \"./SettingsCollection\";\nexport type {\n SettingsModalFooterProps,\n SettingsModalGroupProps,\n SettingsModalProps,\n SettingsModalTabProps,\n SettingsModalTabTone,\n} from \"./SettingsModal\";\nexport { default as SettingsModal } from \"./SettingsModal\";\nexport {\n APP_WORKSPACE_SWITCHER_SEARCH_FROM,\n type AppWorkspaceSidebarSwitcherProps,\n type AppWorkspaceSwitcherAction,\n type AppWorkspaceSwitcherOption,\n} from \"./SidebarSwitcher\";\nexport { measureScrollFade } from \"./scroll-fade\";\nexport type { TabBarItem, TabBarProps } from \"./TabBar\";\nexport { default as TabBar } from \"./TabBar\";\nexport type { TableOfContentsItem, TableOfContentsProps } from \"./TableOfContents\";\nexport { TableOfContents } from \"./TableOfContents\";\n"],"mappings":"AAAA,SAAS,eAAe,QAAmC,mBAAmB;AAO9E,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAgCtD,SAAS,2BAA2B,EAAE,OAAO,IAAI,YAAY,QAAQ,gBAAgB;AACrF,SAAS,iBAAiB,QAAQ,kBAAkB;AAEpD,SAAS,6BAA6B,EAAE,0BAA0B,QAAQ,4BAA4B;AAKtG,SACE,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,6BAA6B,EAC7B,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,wCAAwC,EACxC,+BAA+B,EAC/B,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,wBAAwB,EACxB,gCAAgC,EAChC,4BAA4B,EAC5B,+BAA+B,EAC/B,uBAAuB,EACvB,gCAAgC,EAChC,iCAAiC,QAC5B,uBAAuB;AAC9B,SAAgC,0BAA0B,EAAE,kBAAkB,EAAE,OAAO,IAAI,WAAW,QAAQ,eAAe;AAE7H,SAAS,SAAS,QAAQ,aAAa;AAevC,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AActD,SAAS,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,UAAU,QAAQ,kBAAkB;AAC9H,SAAS,YAAY,EAAE,aAAa,QAAiC,iBAAiB;AAEtF,SAAS,OAAO,IAAI,UAAU,QAAQ,cAAc;AAMpD,SACE,OAAO,IAAI,cAAc,EAEzB,qBAAqB,EACrB,kBAAkB,QACb,kBAAkB;AAEzB,SAAS,OAAO,IAAI,WAAW,EAAE,kBAAkB,QAAQ,eAAe;AAC1E,SAAS,OAAO,IAAI,UAAU,QAA8B,cAAc;AAC1E,SACE,gBAAgB,EAChB,kBAAkB,QAKb,oBAAoB;AAE3B,SAAS,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,QAAQ,aAAa;AAWxI,SACE,qBAAqB,EACrB,OAAO,IAAI,WAAW,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,EAC3B,8BAA8B,QACzB,eAAe;AAEtB,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,OAAO,IAAI,KAAK,QAAQ,SAAS;AAE1C,SAAS,OAAO,IAAI,aAAa,QAAQ,iBAAiB;AAC1D,SAAS,0BAA0B,QAAQ,yBAAyB;AAapE,SACE,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,gBAAgB,QACX,gBAAgB;AACvB,SAAS,OAAO,IAAI,eAAe,QAAmC,mBAAmB;AACzF,SAAS,qBAAqB,QAAqC,oBAAoB;AAEvF,SAAS,OAAO,IAAI,UAAU,QAAQ,cAAc;AAcpD,SACE,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,gBAAgB,QACX,YAAY;AASnB,SAAS,OAAO,IAAI,kBAAkB,QAAQ,sBAAsB;AAQpE,SAAS,OAAO,IAAI,aAAa,QAAQ,iBAAiB;AAC1D,SACE,kCAAkC,QAI7B,mBAAmB;AAC1B,SAAS,iBAAiB,QAAQ,eAAe;AAEjD,SAAS,OAAO,IAAI,MAAM,QAAQ,UAAU;AAE5C,SAAS,eAAe,QAAQ,mBAAmB","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["layout/index.ts"],"sourcesContent":["export { AnchoredPopover, type AnchoredPopoverProps } from \"./AnchoredPopover\";\nexport type {\n AppOverviewCardsProps,\n AppOverviewEmptyStateProps,\n AppOverviewPanelProps,\n AppOverviewProps,\n} from \"./AppOverview\";\nexport { default as AppOverview } from \"./AppOverview\";\nexport type {\n AppWorkspaceBottomDrawerHeight,\n AppWorkspaceBottomDrawerProps,\n AppWorkspaceContentProps,\n AppWorkspaceDetailProps,\n AppWorkspaceDetailWidth,\n AppWorkspaceHeadProps,\n AppWorkspaceMainPaneProps,\n AppWorkspaceMainProps,\n AppWorkspaceNavTreeItemProps,\n AppWorkspaceNavTreeMove,\n AppWorkspaceNavTreeProps,\n AppWorkspaceProps,\n AppWorkspaceSidebarAccessoryVisibility,\n AppWorkspaceSidebarBodyProps,\n AppWorkspaceSidebarIconActionProps,\n AppWorkspaceSidebarIconActionTone,\n AppWorkspaceSidebarIconGridProps,\n AppWorkspaceSidebarItemActionProps,\n AppWorkspaceSidebarItemActionsProps,\n AppWorkspaceSidebarItemIconProps,\n AppWorkspaceSidebarItemLabelProps,\n AppWorkspaceSidebarItemMetaProps,\n AppWorkspaceSidebarItemProps,\n AppWorkspaceSidebarItemStatusProps,\n AppWorkspaceSidebarItemTone,\n AppWorkspaceSidebarProps,\n AppWorkspaceSidebarSectionProps,\n AppWorkspaceSidebarVisibility,\n AppWorkspaceWidthShare,\n} from \"./AppWorkspace\";\nexport { appWorkspaceDetailElementId, default as AppWorkspace } from \"./AppWorkspace\";\nexport { AppWorkspaceSidebarItemStatus } from \"./AppWorkspaceSidebarItemStatus\";\nexport { watchAppHostWidth } from \"./app-host-width\";\nexport type { AppWorkspaceControllerOptions } from \"./app-workspace-controller\";\nexport { installAppWorkspaceController, parkWorkspaceDetailDrawers } from \"./app-workspace-controller\";\nexport type {\n AppWorkspaceLayoutState,\n AppWorkspaceResizeKind,\n} from \"./app-workspace-state\";\nexport {\n APP_WORKSPACE_DETAIL_DEFAULT,\n APP_WORKSPACE_DETAIL_MAX,\n APP_WORKSPACE_DETAIL_MIN,\n APP_WORKSPACE_DRAWER_DEFAULT,\n APP_WORKSPACE_DRAWER_MAX,\n APP_WORKSPACE_DRAWER_MIN,\n APP_WORKSPACE_MAIN_MIN,\n APP_WORKSPACE_MAIN_MIN_HEIGHT,\n APP_WORKSPACE_PANE_DEFAULT,\n APP_WORKSPACE_PANE_MAX,\n APP_WORKSPACE_PANE_MIN,\n APP_WORKSPACE_SIDEBAR_COLLAPSE_THRESHOLD,\n APP_WORKSPACE_SIDEBAR_COLLAPSED,\n APP_WORKSPACE_SIDEBAR_DEFAULT,\n APP_WORKSPACE_SIDEBAR_MAX,\n APP_WORKSPACE_SIDEBAR_MIN,\n appWorkspaceLayoutStyle,\n appWorkspacePanelVariable,\n appWorkspaceResizeLimits,\n normalizeAppWorkspaceLayoutState,\n parseAppWorkspaceLayoutState,\n resolveAppWorkspaceSidebarWidth,\n safeAppWorkspacePanelId,\n serializeAppWorkspaceLayoutState,\n shouldCollapseAppWorkspaceSidebar,\n} from \"./app-workspace-state\";\nexport { type BottomSheetProps, bottomSheetAdaptiveOptions, bottomSheetOptions, default as BottomSheet } from \"./BottomSheet\";\nexport type { DataPanelProps } from \"./DataPanel\";\nexport { DataPanel } from \"./DataPanel\";\nexport type {\n DetailPanelActionButtonProps,\n DetailPanelActionLinkProps,\n DetailPanelActionProps,\n DetailPanelActionSecondary,\n DetailPanelBodyProps,\n DetailPanelGroupProps,\n DetailPanelHeaderProps,\n DetailPanelProps,\n DetailPanelRowProps,\n DetailPanelSectionProps,\n DetailPanelSummaryProps,\n DetailPanelTone,\n} from \"./DetailPanel\";\nexport { default as DetailPanel } from \"./DetailPanel\";\nexport type {\n DetailAccessEntry,\n DetailAccessProps,\n DetailLinkItem,\n DetailLinksProps,\n DetailPresencePerson,\n DetailPresenceProps,\n DetailPresenceState,\n DetailPropertiesProps,\n DetailProperty,\n DetailTag,\n DetailTagsProps,\n} from \"./DetailSections\";\nexport { DetailAccess, DetailLinks, DetailPresence, DetailPresenceSlot, DetailProperties, DetailTags } from \"./DetailSections\";\nexport { DETAILS_ICON, DetailsToggle, type DetailsToggleProps } from \"./DetailsToggle\";\nexport type { DiscussionComposerProps, DiscussionItemProps, DiscussionListProps, DiscussionProps } from \"./Discussion\";\nexport { default as Discussion } from \"./Discussion\";\nexport type {\n FloatingWindowClose,\n FloatingWindowProps,\n OpenFloatingWindowOptions,\n} from \"./FloatingWindow\";\nexport {\n default as FloatingWindow,\n type FloatingWindowRect,\n fitFloatingWindowRect,\n openFloatingWindow,\n} from \"./FloatingWindow\";\nexport type { MobileShellHeaderProps, MobileShellProps, MobileShellSidebarItem, MobileShellSidebarProps } from \"./MobileShell\";\nexport { default as MobileShell, observeMobileShell } from \"./MobileShell\";\nexport { default as Navigation, type NavigationProps } from \"./Navigation\";\nexport {\n createNavigation,\n findNavigationItem,\n type NavigationController,\n type NavigationItem,\n type NavigationOptions,\n type NavigationStatus,\n} from \"./navigation-model\";\nexport type { PageTitleProps, PageTrailLink, PageTrailState } from \"./PageTitle\";\nexport { followPageTrail, PAGE_TRAIL_EVENT, PageTitle, PageTrailProvider, readPageTrail, setPageTrail, usePageTrail } from \"./PageTitle\";\nexport type {\n PanelDialogBodyProps,\n PanelDialogFooterProps,\n PanelDialogHeaderProps,\n PanelDialogProps,\n PanelDialogSectionProps,\n PanelDialogSurface,\n PanelDialogTabOption,\n PanelDialogTabsProps,\n} from \"./PanelDialog\";\nexport {\n confirmDiscardIfDirty,\n default as PanelDialog,\n panelDialogFixedOptions,\n panelDialogFixedPanelClass,\n panelDialogOptions,\n panelDialogPanelClass,\n panelDialogWideOptions,\n panelDialogWidePanelClass,\n panelDialogWorkspaceOptions,\n panelDialogWorkspacePanelClass,\n} from \"./PanelDialog\";\nexport type { PanelHeaderProps } from \"./PanelHeader\";\nexport { PanelHeader } from \"./PanelHeader\";\nexport type { PanesItem, PanesProps } from \"./Panes\";\nexport { default as Panes } from \"./Panes\";\nexport type { PullToRefreshProps, PullToRefreshState } from \"./PullToRefresh\";\nexport { default as PullToRefresh } from \"./PullToRefresh\";\nexport { installPageTitleController } from \"./page-title-controller\";\nexport type {\n AddPanesItemOptions,\n PanesDirection,\n PanesGroup,\n PanesIntent,\n PanesLayout,\n PanesNode,\n PanesPath,\n PanesPathSegment,\n PanesSide,\n PanesSplit,\n} from \"./panes-layout\";\nexport {\n activatePanesItem,\n addPanesItem,\n applyPanesIntent,\n createPanesLayout,\n isPanesItemVisible,\n PANES_LAYOUT_VERSION,\n parsePanesLayout,\n reconcilePanesLayout,\n removePanesItem,\n resizePanesSplit,\n} from \"./panes-layout\";\nexport { default as ResizeSeparator, type ResizeSeparatorProps } from \"./ResizeSeparator\";\nexport { attachResizeSeparator, type ResizeSeparatorOptions } from \"./resize-separator\";\nexport type { ScrollAreaProps } from \"./ScrollArea\";\nexport { default as ScrollArea } from \"./ScrollArea\";\nexport type {\n SaveStatusProps,\n SaveStatusState,\n SettingsFieldControlProps,\n SettingsFieldProps,\n SettingsFieldWidth,\n SettingsGroupActionProps,\n SettingsGroupProps,\n SettingsPageProps,\n SettingsPanelFooterProps,\n SettingsSaveBarProps,\n SettingsSectionProps,\n} from \"./Settings\";\nexport {\n readSettingsError,\n SaveStatus,\n SettingsField,\n SettingsGroup,\n SettingsPage,\n SettingsPanelFooter,\n SettingsSaveBar,\n SettingsSection,\n sameSettingValue,\n} from \"./Settings\";\nexport type {\n SettingsCollectionActionProps,\n SettingsCollectionItemActionsProps,\n SettingsCollectionItemProps,\n SettingsCollectionItemReorderProps,\n SettingsCollectionItemStatusProps,\n SettingsCollectionProps,\n} from \"./SettingsCollection\";\nexport { default as SettingsCollection } from \"./SettingsCollection\";\nexport type {\n SettingsModalFooterProps,\n SettingsModalGroupProps,\n SettingsModalProps,\n SettingsModalTabProps,\n SettingsModalTabTone,\n} from \"./SettingsModal\";\nexport { default as SettingsModal } from \"./SettingsModal\";\nexport {\n APP_WORKSPACE_SWITCHER_SEARCH_FROM,\n type AppWorkspaceSidebarSwitcherProps,\n type AppWorkspaceSwitcherAction,\n type AppWorkspaceSwitcherOption,\n} from \"./SidebarSwitcher\";\nexport { measureScrollFade } from \"./scroll-fade\";\nexport type { TabBarItem, TabBarProps } from \"./TabBar\";\nexport { default as TabBar } from \"./TabBar\";\nexport type { TableOfContentsItem, TableOfContentsProps } from \"./TableOfContents\";\nexport { TableOfContents } from \"./TableOfContents\";\n"],"mappings":"AAAA,SAAS,eAAe,QAAmC,mBAAmB;AAO9E,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAgCtD,SAAS,2BAA2B,EAAE,OAAO,IAAI,YAAY,QAAQ,gBAAgB;AACrF,SAAS,6BAA6B,QAAQ,iCAAiC;AAC/E,SAAS,iBAAiB,QAAQ,kBAAkB;AAEpD,SAAS,6BAA6B,EAAE,0BAA0B,QAAQ,4BAA4B;AAKtG,SACE,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,6BAA6B,EAC7B,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,wCAAwC,EACxC,+BAA+B,EAC/B,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,wBAAwB,EACxB,gCAAgC,EAChC,4BAA4B,EAC5B,+BAA+B,EAC/B,uBAAuB,EACvB,gCAAgC,EAChC,iCAAiC,QAC5B,uBAAuB;AAC9B,SAAgC,0BAA0B,EAAE,kBAAkB,EAAE,OAAO,IAAI,WAAW,QAAQ,eAAe;AAE7H,SAAS,SAAS,QAAQ,aAAa;AAevC,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AActD,SAAS,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,UAAU,QAAQ,kBAAkB;AAC9H,SAAS,YAAY,EAAE,aAAa,QAAiC,iBAAiB;AAEtF,SAAS,OAAO,IAAI,UAAU,QAAQ,cAAc;AAMpD,SACE,OAAO,IAAI,cAAc,EAEzB,qBAAqB,EACrB,kBAAkB,QACb,kBAAkB;AAEzB,SAAS,OAAO,IAAI,WAAW,EAAE,kBAAkB,QAAQ,eAAe;AAC1E,SAAS,OAAO,IAAI,UAAU,QAA8B,cAAc;AAC1E,SACE,gBAAgB,EAChB,kBAAkB,QAKb,oBAAoB;AAE3B,SAAS,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,QAAQ,aAAa;AAWxI,SACE,qBAAqB,EACrB,OAAO,IAAI,WAAW,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,EAC3B,8BAA8B,QACzB,eAAe;AAEtB,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,OAAO,IAAI,KAAK,QAAQ,SAAS;AAE1C,SAAS,OAAO,IAAI,aAAa,QAAQ,iBAAiB;AAC1D,SAAS,0BAA0B,QAAQ,yBAAyB;AAapE,SACE,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,gBAAgB,QACX,gBAAgB;AACvB,SAAS,OAAO,IAAI,eAAe,QAAmC,mBAAmB;AACzF,SAAS,qBAAqB,QAAqC,oBAAoB;AAEvF,SAAS,OAAO,IAAI,UAAU,QAAQ,cAAc;AAcpD,SACE,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,gBAAgB,QACX,YAAY;AASnB,SAAS,OAAO,IAAI,kBAAkB,QAAQ,sBAAsB;AAQpE,SAAS,OAAO,IAAI,aAAa,QAAQ,iBAAiB;AAC1D,SACE,kCAAkC,QAI7B,mBAAmB;AAC1B,SAAS,iBAAiB,QAAQ,eAAe;AAEjD,SAAS,OAAO,IAAI,MAAM,QAAQ,UAAU;AAE5C,SAAS,eAAe,QAAQ,mBAAmB","ignoreList":[]}