@k2b/ui 0.45.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/actions/Dropdown.js +8 -1
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/FilterChip.js +11 -5
- package/dist/browser/actions/FilterChip.js.map +1 -1
- package/dist/browser/actions/ViewTabs.js +225 -93
- package/dist/browser/actions/ViewTabs.js.map +1 -1
- package/dist/browser/content/FileGrid.js +125 -99
- package/dist/browser/content/FileGrid.js.map +1 -1
- package/dist/browser/inputs/choice.js +36 -9
- package/dist/browser/inputs/choice.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +30 -26
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/DetailPanel.js +130 -108
- package/dist/browser/layout/DetailPanel.js.map +1 -1
- package/dist/browser/layout/DetailSections.js +1019 -0
- package/dist/browser/layout/DetailSections.js.map +1 -0
- package/dist/browser/layout/DetailsToggle.js +32 -0
- package/dist/browser/layout/DetailsToggle.js.map +1 -0
- package/dist/browser/layout/Discussion.js +3 -0
- package/dist/browser/layout/Discussion.js.map +1 -1
- package/dist/browser/layout/MobileShell.js +116 -94
- package/dist/browser/layout/MobileShell.js.map +1 -1
- package/dist/browser/layout/PageTitle.js +33 -10
- package/dist/browser/layout/PageTitle.js.map +1 -1
- package/dist/browser/layout/app-workspace-controller.js +12 -0
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/layout/detail-sections-messages.js +123 -0
- package/dist/browser/layout/detail-sections-messages.js.map +1 -0
- package/dist/browser/layout/index.js +2 -0
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/surfaces/Avatar.js +3 -1
- package/dist/browser/surfaces/Avatar.js.map +1 -1
- package/dist/browser/surfaces/AvatarStack.js +95 -61
- package/dist/browser/surfaces/AvatarStack.js.map +1 -1
- package/dist/browser/surfaces/ChangeList.js +77 -0
- package/dist/browser/surfaces/ChangeList.js.map +1 -0
- package/dist/browser/surfaces/index.js +2 -1
- package/dist/browser/surfaces/index.js.map +1 -1
- package/dist/browser/text-editor/TextEditor.js +19 -8
- package/dist/browser/text-editor/TextEditor.js.map +1 -1
- package/dist/ssr/actions/Dropdown.js +6 -0
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/FilterChip.js +1 -1
- package/dist/ssr/actions/FilterChip.js.map +1 -1
- package/dist/ssr/actions/ViewTabs.js +144 -37
- package/dist/ssr/actions/ViewTabs.js.map +1 -1
- package/dist/ssr/content/FileGrid.js +36 -22
- package/dist/ssr/content/FileGrid.js.map +1 -1
- package/dist/ssr/inputs/choice.js +36 -9
- package/dist/ssr/inputs/choice.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +27 -27
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/DetailPanel.js +17 -0
- package/dist/ssr/layout/DetailPanel.js.map +1 -1
- package/dist/ssr/layout/DetailSections.js +762 -0
- package/dist/ssr/layout/DetailSections.js.map +1 -0
- package/dist/ssr/layout/DetailsToggle.js +29 -0
- package/dist/ssr/layout/DetailsToggle.js.map +1 -0
- package/dist/ssr/layout/Discussion.js +3 -0
- package/dist/ssr/layout/Discussion.js.map +1 -1
- package/dist/ssr/layout/MobileShell.js +45 -28
- package/dist/ssr/layout/MobileShell.js.map +1 -1
- package/dist/ssr/layout/PageTitle.js +29 -6
- package/dist/ssr/layout/PageTitle.js.map +1 -1
- package/dist/ssr/layout/app-workspace-controller.js +12 -0
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/layout/detail-sections-messages.js +123 -0
- package/dist/ssr/layout/detail-sections-messages.js.map +1 -0
- package/dist/ssr/layout/index.js +2 -0
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/surfaces/Avatar.js +3 -1
- package/dist/ssr/surfaces/Avatar.js.map +1 -1
- package/dist/ssr/surfaces/AvatarStack.js +61 -32
- package/dist/ssr/surfaces/AvatarStack.js.map +1 -1
- package/dist/ssr/surfaces/ChangeList.js +37 -0
- package/dist/ssr/surfaces/ChangeList.js.map +1 -0
- package/dist/ssr/surfaces/index.js +2 -1
- package/dist/ssr/surfaces/index.js.map +1 -1
- package/dist/ssr/text-editor/TextEditor.js +19 -8
- package/dist/ssr/text-editor/TextEditor.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/FilterChip.d.ts +4 -0
- package/dist/types/actions/ViewTabs.d.ts +11 -1
- package/dist/types/content/FileGrid.d.ts +6 -0
- package/dist/types/inputs/choice.d.ts +9 -3
- package/dist/types/layout/DetailPanel.d.ts +9 -0
- package/dist/types/layout/DetailSections.d.ts +156 -0
- package/dist/types/layout/DetailsToggle.d.ts +13 -0
- package/dist/types/layout/PageTitle.d.ts +7 -0
- package/dist/types/layout/detail-sections-messages.d.ts +59 -0
- package/dist/types/layout/index.d.ts +4 -1
- package/dist/types/surfaces/Avatar.d.ts +3 -0
- package/dist/types/surfaces/AvatarStack.d.ts +20 -1
- package/dist/types/surfaces/ChangeList.d.ts +20 -0
- package/dist/types/surfaces/index.d.ts +5 -3
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["layout/PageTitle.tsx"],"sourcesContent":["import { createContext, createRoot, createSignal, createUniqueId, For, type JSX, onCleanup, onMount, Show, useContext } from \"solid-js\";\nimport { Dynamic, insert, isServer } from \"solid-js/web\";\nimport { IconButtonLink } from \"../actions/Button\";\nimport { installPageTitleController, PAGE_TITLE_CONTROLLER_ATTRIBUTE } from \"./page-title-controller\";\nimport { useWorkspaceMessages } from \"./workspace-messages\";\n\n/** A page above the current one. Only pages someone can go back to are levels, so each has a link. */\nexport type PageTrailLink = { title: string; href: string };\n/** The current page and the pages above it, nearest last. */\nexport type PageTrailState = { title: string; ancestors: PageTrailLink[] };\n\nexport type PageTitleProps = {\n trail: PageTrailState;\n /** Quiet text after the title, for example a count. */\n subtitle?: JSX.Element;\n /** Defaults to `\"h1\"`. Chrome that repeats a title the page already shows uses `\"p\"`. */\n as?: \"h1\" | \"h2\" | \"p\";\n /**\n * Marks a title drawn by surrounding chrome, such as the workspace head or a\n * host shell. It steps back when the page renders its own `PageTitle`, so a\n * page has one title with one way up.\n */\n fallback?: boolean;\n class?: string;\n};\n\n/** Window event a host dispatches after publishing a new page trail. */\nexport const PAGE_TRAIL_EVENT = \"k2b:page-trail\";\nconst SOURCE_SELECTOR = \"script[data-k2b-page-trail]\";\n\nconst isTrail = (value: unknown): value is PageTrailState => {\n if (!value || typeof value !== \"object\") return false;\n const trail = value as Partial<PageTrailState>;\n return (\n typeof trail.title === \"string\" &&\n Array.isArray(trail.ancestors) &&\n trail.ancestors.every((link) => typeof link?.title === \"string\" && typeof link?.href === \"string\")\n );\n};\n\n/** The trail a host published for this document, or `undefined` outside a browser or without one. */\nexport const readPageTrail = (): PageTrailState | undefined => {\n if (typeof document === \"undefined\") return undefined;\n const source = document.querySelector(SOURCE_SELECTOR);\n if (!source?.textContent) return undefined;\n try {\n const value: unknown = JSON.parse(source.textContent);\n return isTrail(value) ? value : undefined;\n } catch {\n return undefined;\n }\n};\n\n/** `<` is escaped so a title can never end the script element it travels in. */\nconst serializeTrail = (trail: PageTrailState): string => JSON.stringify(trail).replace(/</g, \"\\\\u003c\");\n\n/**\n * Publishes a new trail for the document in the browser, for example after an\n * in-page navigation. Workspace heads and page titles that read the host's\n * trail follow it.\n */\nexport const setPageTrail = (trail: PageTrailState): void => {\n if (typeof document === \"undefined\") return;\n let source = document.querySelector(SOURCE_SELECTOR);\n if (!source) {\n source = document.createElement(\"script\");\n source.setAttribute(\"type\", \"application/json\");\n source.setAttribute(\"data-k2b-page-trail\", \"\");\n document.body.append(source);\n }\n source.textContent = serializeTrail(trail);\n window.dispatchEvent(new Event(PAGE_TRAIL_EVENT));\n};\n\nconst PageTrailContext = createContext<() => PageTrailState | undefined>();\n\n/**\n * Gives a host's page trail to everything below it. During server rendering\n * the context carries it; the provider also publishes it into the document,\n * where browser-rendered parts such as islands read it. Below a provider that\n * renders in the browser, its `trail` prop is the source: update the prop.\n */\nexport function PageTrailProvider(props: { trail: PageTrailState | undefined; children: JSX.Element }): JSX.Element {\n return (\n <PageTrailContext.Provider value={() => props.trail}>\n <Show when={props.trail}>\n {(trail) => <script type=\"application/json\" data-k2b-page-trail=\"\" innerHTML={serializeTrail(trail())} />}\n </Show>\n {props.children}\n </PageTrailContext.Provider>\n );\n}\n\n/** The host's page trail: from the provider while rendering below it, otherwise from the document. */\nexport const usePageTrail = (): (() => PageTrailState | undefined) => {\n const context = useContext(PageTrailContext);\n if (context) return context;\n if (typeof window === \"undefined\") return () => undefined;\n const [trail, setTrail] = createSignal(readPageTrail());\n const update = () => setTrail(readPageTrail());\n window.addEventListener(PAGE_TRAIL_EVENT, update);\n onCleanup(() => window.removeEventListener(PAGE_TRAIL_EVENT, update));\n return trail;\n};\n\n/**\n * A page title with its way up. The number of pages above decides the form:\n * none shows the title alone; one puts \"‹ Parent\" above it; more put a path\n * row above it whose middle collapses into \"…\" only when it does not fit.\n * Both rows share the same height, so the title never moves between depths.\n * On phones a back arrow left of the title replaces the row above.\n */\nexport function PageTitle(props: PageTitleProps): JSX.Element {\n const messages = useWorkspaceMessages();\n // A title rendered on the server from the host's trail follows the host's later trails (see `followPageTrail`).\n const host = isServer ? useContext(PageTrailContext) : undefined;\n const menuId = `k2b-page-title-menu-${createUniqueId()}`;\n const ancestors = () => props.trail.ancestors;\n const parent = () => ancestors().at(-1);\n let root: HTMLDivElement | undefined;\n // A host may control every title in the document at once; a title outside\n // one still collapses its path.\n onMount(() => {\n if (!root || root.closest(`[${PAGE_TITLE_CONTROLLER_ATTRIBUTE}]`)) return;\n onCleanup(installPageTitleController(root));\n });\n return (\n <div\n ref={root}\n class={`k2b-page-title ${props.class ?? \"\"}`}\n data-depth={ancestors().length}\n data-fallback={props.fallback ? \"\" : undefined}\n data-k2b-server={isServer && props.trail === host?.() ? \"\" : undefined}\n >\n <Show when={parent()}>\n {(up) => (\n <IconButtonLink\n class=\"k2b-page-title__back\"\n href={up().href}\n label={messages().backTo({ page: up().title })}\n data-k2b-page-trail-link=\"\"\n data-k2b-page-trail-up=\"\"\n >\n <i class=\"ti ti-chevron-left\" aria-hidden=\"true\" />\n </IconButtonLink>\n )}\n </Show>\n <div class=\"k2b-page-title__copy\">\n <Show when={ancestors().length === 1 && parent()}>\n {(up) => (\n <nav class=\"k2b-page-title__trail\" aria-label={messages().path}>\n <a\n class=\"k2b-page-title__up\"\n href={up().href}\n aria-label={messages().backTo({ page: up().title })}\n data-k2b-page-trail-link=\"\"\n data-k2b-page-trail-up=\"\"\n >\n <i class=\"ti ti-chevron-left\" aria-hidden=\"true\" />\n <span class=\"k2b-page-title__label\">{up().title}</span>\n </a>\n </nav>\n )}\n </Show>\n <Show when={ancestors().length > 1}>\n <nav class=\"k2b-page-title__trail\" aria-label={messages().path}>\n <ol class=\"k2b-page-title__path\">\n <For each={ancestors()}>\n {(link, index) => (\n <>\n <Show when={index() === 1}>\n <li class=\"k2b-page-title__more\" hidden>\n <i class=\"ti ti-chevron-right\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"k2b-page-title__more-button\" popovertarget={menuId} aria-label={messages().moreLevels}>\n …\n </button>\n </li>\n </Show>\n <li class=\"k2b-page-title__crumb\" data-index={index()}>\n <Show when={index() > 0}>\n <i class=\"ti ti-chevron-right\" aria-hidden=\"true\" />\n </Show>\n <a\n href={link.href}\n data-k2b-page-trail-link=\"\"\n data-k2b-page-trail-up={index() === ancestors().length - 1 ? \"\" : undefined}\n class=\"k2b-page-title__label\"\n >\n {link.title}\n </a>\n </li>\n </>\n )}\n </For>\n </ol>\n <div id={menuId} popover=\"auto\" class=\"k2b-dropdown__menu k2b-page-title__menu\">\n <For each={ancestors()}>\n {(link, index) => (\n <a class=\"k2b-dropdown__item\" href={link.href} data-index={index()} data-k2b-page-trail-link=\"\" hidden>\n {link.title}\n </a>\n )}\n </For>\n </div>\n </nav>\n </Show>\n <Dynamic component={props.as ?? \"h1\"} class=\"k2b-page-title__title\">\n <span class=\"k2b-page-title__text\">{props.trail.title}</span>\n <Show when={props.subtitle}>\n <small class=\"k2b-page-title__subtitle\">{props.subtitle}</small>\n </Show>\n </Dynamic>\n </div>\n </div>\n );\n}\n\n/**\n * Keeps server-rendered titles of the host's trail current: a workspace head\n * that never hydrates, its heading, and an app's own header title from the\n * host's trail.\n * When the host publishes a new trail, for example after `setPageTrail()`,\n * each such title is replaced in place by a live one with the same element,\n * class, and subtitle, and a head learns whether it now has a page above it.\n * Titles inside islands render in the browser anyway. Returns the disposer.\n */\nexport const followPageTrail = (root: ParentNode = document): (() => void) => {\n const disposers = new Map<Text, () => void>();\n const upgrade = () => {\n for (const [place, dispose] of disposers) {\n if (place.isConnected) continue;\n dispose();\n disposers.delete(place);\n }\n const trail = readPageTrail();\n for (const element of root.querySelectorAll<HTMLElement>(\".k2b-page-title[data-k2b-server]\")) {\n const row = element.parentElement;\n if (!row || element.closest(\"solid-island, solid-client\")) continue;\n const tag = element.querySelector(\".k2b-page-title__title\")?.localName;\n const as = tag === \"p\" || tag === \"h2\" ? tag : \"h1\";\n const fallback = element.hasAttribute(\"data-fallback\");\n const extra = [...element.classList].filter((name) => name !== \"k2b-page-title\").join(\" \") || undefined;\n const subtitle = element.querySelector(\".k2b-page-title__subtitle\");\n const subtitleNodes = subtitle ? [...subtitle.childNodes] : undefined;\n // A link focused in the server title keeps focus in the live one: same kind, then same address.\n const active = document.activeElement;\n const focused =\n active && element.contains(active)\n ? {\n kind: [\"k2b-page-title__up\", \"k2b-page-title__back\"].find((name) => active.classList.contains(name)),\n href: active.getAttribute(\"href\"),\n }\n : undefined;\n // The live title takes the server title's place, before whatever follows it in the row.\n const place = document.createTextNode(\"\");\n row.insertBefore(place, element);\n element.remove();\n disposers.set(\n place,\n createRoot((dispose) => {\n const live = usePageTrail();\n insert(\n row,\n () => (\n <Show when={live()}>\n {(current) => <PageTitle trail={current()} as={as} fallback={fallback} class={extra} subtitle={subtitleNodes} />}\n </Show>\n ),\n place,\n );\n return dispose;\n }),\n );\n const upgraded = place.previousSibling;\n if (focused && upgraded instanceof HTMLElement && upgraded.classList.contains(\"k2b-page-title\")) {\n const links = focused.kind ? [...upgraded.querySelectorAll<HTMLElement>(`a.${focused.kind}`)] : [];\n const link =\n links.find((candidate) => candidate.getAttribute(\"href\") === focused.href) ??\n links[0] ??\n upgraded.querySelector<HTMLElement>(\"a[data-k2b-page-trail-up]\");\n link?.focus({ preventScroll: true });\n }\n }\n // A server-rendered workspace heading carries only the title.\n for (const heading of root.querySelectorAll<HTMLElement>(\"[data-k2b-page-trail-title][data-k2b-server]\"))\n if (trail && !heading.closest(\"solid-island, solid-client\")) heading.textContent = trail.title;\n // The row's `data-trail` decides whether it shows; it follows the depth. A\n // workspace head holds its title in its lead.\n for (const row of root.querySelectorAll<HTMLElement>(\n \"[data-trail]:has(> .k2b-page-title[data-fallback]), [data-trail]:has(> .k2b-app-workspace__head-lead > .k2b-page-title[data-fallback])\",\n ))\n if (!row.closest(\"solid-island, solid-client\")) row.dataset.trail = trail?.ancestors.length ? \"up\" : \"title\";\n };\n window.addEventListener(PAGE_TRAIL_EVENT, upgrade);\n return () => {\n window.removeEventListener(PAGE_TRAIL_EVENT, upgrade);\n for (const dispose of disposers.values()) dispose();\n disposers.clear();\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,EAAY,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,QAAQ,UAAU;AACvI,SAAS,OAAO,EAAE,MAAM,EAAE,QAAQ,QAAQ,cAAc;AACxD,SAAS,cAAc,QAAQ,mBAAmB;AAClD,SAAS,0BAA0B,EAAE,+BAA+B,QAAQ,yBAAyB;AACrG,SAAS,oBAAoB,QAAQ,sBAAsB;;AAE3D;;AAEA;;AAkBA;AACA,OAAO,MAAM,gBAAgB,GAAG,gBAAgB;AAChD,MAAM,eAAe,GAAG,6BAA6B;AAErD,MAAM,OAAO,GAAI,KAAc,IAA8B;EAC3D,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,OAAO,KAAK;EACrD,MAAM,KAAK,GAAG,KAAgC;EAC9C,OACE,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAC/B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,IAC9B,KAAK,CAAC,SAAS,CAAC,KAAK,CAAE,IAAI,IAAK,OAAO,IAAI,EAAE,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAI,EAAE,IAAI,KAAK,QAAQ,CAAC;AAEtG,CAAC;;AAED;AACA,OAAO,MAAM,aAAa,GAAG,MAAkC;EAC7D,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,OAAO,SAAS;EACrD,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAC;EACtD,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,SAAS;EAC1C,IAAI;IACF,MAAM,KAAc,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC;IACrD,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,SAAS;EAC3C,CAAC,CAAC,MAAM;IACN,OAAO,SAAS;EAClB;AACF,CAAC;;AAED;AACA,MAAM,cAAc,GAAI,KAAqB,IAAa,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;;AAExG;AACA;AACA;AACA;AACA;AACA,OAAO,MAAM,YAAY,GAAI,KAAqB,IAAW;EAC3D,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;EACrC,IAAI,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAC;EACpD,IAAI,CAAC,MAAM,EAAE;IACX,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;IACzC,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAC/C,MAAM,CAAC,YAAY,CAAC,qBAAqB,EAAE,EAAE,CAAC;IAC9C,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;EAC9B;EACA,MAAM,CAAC,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC;EAC1C,MAAM,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,gBAAgB,GAAG,aAAa,CAAmC,CAAC;;AAE1E;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAAS,iBAAiB,CAAC,KAAmE,EAAe;EAClH,yBACG,gBAAgB,CAAC,QAAQ;IAAC,KAAK,EAAE,MAAM,KAAK,CAAC,KAAK;IAAA;MAAA,0BAChD,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,KAAK;QAAA;QAAA,UACnB,KAAK;UAAA;UAAA,gDAAuE,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;UAAA;QAAA;MAAI,iBAE1G,KAAK,CAAC,QAAQ;IAAA;EAAA;AAGrB;;AAEA;AACA,OAAO,MAAM,YAAY,GAAG,MAA0C;EACpE,MAAM,OAAO,GAAG,UAAU,CAAC,gBAAgB,CAAC;EAC5C,IAAI,OAAO,EAAE,OAAO,OAAO;EAC3B,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,OAAO,MAAM,SAAS;EACzD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC;EACvD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;EAC9C,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,CAAC;EACjD,SAAS,CAAC,MAAM,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;EACrE,OAAO,KAAK;AACd,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAAS,SAAS,CAAC,KAAqB,EAAe;EAC5D,MAAM,QAAQ,GAAG,oBAAoB,CAAC,CAAC;EACvC;EACA,MAAM,IAAI,GAAG,QAAQ,GAAG,UAAU,CAAC,gBAAgB,CAAC,GAAG,SAAS;EAChE,MAAM,MAAM,GAAG,uBAAuB,cAAc,CAAC,CAAC,EAAE;EACxD,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,SAAS;EAC7C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EACvC,IAAI,IAAgC;EACpC;EACA;EACA,OAAO,CAAC,MAAM;IACZ,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,+BAA+B,GAAG,CAAC,EAAE;IACnE,SAAS,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC;EAC7C,CAAC,CAAC;EACF;IAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;IAAA,YAES,IAAI;IAAA,oDAAJ,IAAI;IAAA,kCAMR,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,MAAM,CAAC,CAAC;MAAA;MAAA,UAChB,EAAE,sBACD,cAAc;QAAA;QAAA,IAEb,IAAI;UAAA,OAAE,EAAE,CAAC,CAAC,CAAC,IAAI;QAAA;QAAA,IACf,KAAK;UAAA,OAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;UAAM,CAAC,CAAC;QAAA;QAAA;QAAA;QAAA;UAAA;QAAA;MAAA;IAMjD;IAAA,kCAGA,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,sBAAS,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,OAAI,MAAM,CAAC,CAAC;MAAA;MAAA,UAC5C,EAAE;QAAA;UAAA;UAAA;UAAA;QAAA,uBAUuC,EAAE,CAAC,CAAC,CAAC,KAAK;QAAA;UAAA,WATJ,QAAQ,CAAC,CAAC,CAAC,IAAI;YAAA,OAGpD,EAAE,CAAC,CAAC,CAAC,IAAI;YAAA,OACH,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;cAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;YAAM,CAAC,CAAC;UAAA;UAAA;UAAA;UAAA;QAAA;UAAA;UAAA;UAAA;QAAA;QAAA;MAAA;IAQxD;IAAA,kCAEF,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,SAAS,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;MAAA;MAAA;QAAA;UAAA;UAAA;QAAA,kCAG3B,GAAG;UAAA,IAAC,IAAI;YAAA,OAAE,SAAS,CAAC,CAAC;UAAA;UAAA,UACnB,CAAC,IAAI,EAAE,KAAK,wBAER,IAAI;YAAA,IAAC,IAAI;cAAA,OAAE,KAAK,CAAC,CAAC,KAAK,CAAC;YAAA;YAAA;cAAA;gBAAA;gBAAA;cAAA,wCAGoD,MAAM;cAAA,oDAAc,QAAQ,CAAC,CAAC,CAAC,UAAU;cAAA;YAAA;UAAA;YAAA;cAAA;cAAA;cAAA;YAAA,mCAMnH,IAAI;cAAA,IAAC,IAAI;gBAAA,OAAE,KAAK,CAAC,CAAC,GAAG,CAAC;cAAA;cAAA;gBAAA;cAAA;YAAA;YAAA,uBASpB,IAAI,CAAC,KAAK;YAAA;cAAA,WAV+B,KAAK,CAAC,CAAC;gBAAA,OAK3C,IAAI,CAAC,IAAI;gBAAA,OAES,KAAK,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,SAAS;cAAA;cAAA;cAAA;cAAA;YAAA;cAAA;cAAA;cAAA;YAAA;YAAA;UAAA;QAOlF;QAAA,4BAGI,MAAM;QAAA,kCACZ,GAAG;UAAA,IAAC,IAAI;YAAA,OAAE,SAAS,CAAC,CAAC;UAAA;UAAA,UACnB,CAAC,IAAI,EAAE,KAAK;YAAA;YAAA,uBAER,IAAI,CAAC,KAAK;YAAA;cAAA,WADuB,IAAI,CAAC,IAAI;gBAAA,QAAc,KAAK,CAAC,CAAC;cAAA;cAAA;cAAA;YAAA;cAAA;cAAA;YAAA;YAAA;UAAA;QAGnE;QAAA,mDApCwC,QAAQ,CAAC,CAAC,CAAC,IAAI;QAAA;MAAA;IAAA;IAAA,kCAyC/D,OAAO;MAAA,IAAC,SAAS;QAAA,OAAE,KAAK,CAAC,EAAE,IAAI,IAAI;MAAA;MAAA;MAAA;QAAA;UAAA;UAAA,sBACE,KAAK,CAAC,KAAK,CAAC,KAAK;UAAA;QAAA,wBACpD,IAAI;UAAA,IAAC,IAAI;YAAA,OAAE,KAAK,CAAC,QAAQ;UAAA;UAAA;YAAA;YAAA,sBACiB,KAAK,CAAC,QAAQ;YAAA;UAAA;QAAA;MAAA;IAAA;IAAA;MAAA,UAhFtD,kBAAkB,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE;QAAA,OAChC,SAAS,CAAC,CAAC,CAAC,MAAM;QAAA,OACf,KAAK,CAAC,QAAQ,GAAG,EAAE,GAAG,SAAS;QAAA,OAC7B,QAAQ,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,SAAS;MAAA;MAAA;MAAA;MAAA;MAAA;IAAA;MAAA;MAAA;MAAA;MAAA;IAAA;IAAA;EAAA;AAmF5E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAM,eAAe,GAAG,CAAC,IAAgB,GAAG,QAAQ,KAAmB;EAC5E,MAAM,SAAS,GAAG,IAAI,GAAG,CAAmB,CAAC;EAC7C,MAAM,OAAO,GAAG,MAAM;IACpB,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,SAAS,EAAE;MACxC,IAAI,KAAK,CAAC,WAAW,EAAE;MACvB,OAAO,CAAC,CAAC;MACT,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC;IACzB;IACA,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC;IAC7B,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,gBAAgB,CAAc,kCAAkC,CAAC,EAAE;MAC5F,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa;MACjC,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,4BAA4B,CAAC,EAAE;MAC3D,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,wBAAwB,CAAC,EAAE,SAAS;MACtE,MAAM,EAAE,GAAG,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,IAAI,GAAG,GAAG,GAAG,IAAI;MACnD,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC;MACtD,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,CAAE,IAAI,IAAK,IAAI,KAAK,gBAAgB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS;MACvG,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC,2BAA2B,CAAC;MACnE,MAAM,aAAa,GAAG,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,SAAS;MACrE;MACA,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa;MACrC,MAAM,OAAO,GACX,MAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,GAC9B;QACE,IAAI,EAAE,CAAC,oBAAoB,EAAE,sBAAsB,CAAC,CAAC,IAAI,CAAE,IAAI,IAAK,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpG,IAAI,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM;MAClC,CAAC,GACD,SAAS;MACf;MACA,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;MACzC,GAAG,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC;MAChC,OAAO,CAAC,MAAM,CAAC,CAAC;MAChB,SAAS,CAAC,GAAG,CACX,KAAK,EACL,UAAU,CAAE,OAAO,IAAK;QACtB,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC;QAC3B,MAAM,CACJ,GAAG,EACH,wBACG,IAAI;UAAA,IAAC,IAAI;YAAA,OAAE,IAAI,CAAC,CAAC;UAAA;UAAA,UACd,OAAO,sBAAM,SAAS;YAAA,IAAC,KAAK;cAAA,OAAE,OAAO,CAAC,CAAC;YAAA;YAAE,EAAE,EAAE,EAAE;YAAE,QAAQ,EAAE,QAAQ;YAAA,SAAS,KAAK;YAAE,QAAQ,EAAE;UAAa;QAAI,EAEnH,EACD,KACF,CAAC;QACD,OAAO,OAAO;MAChB,CAAC,CACH,CAAC;MACD,MAAM,QAAQ,GAAG,KAAK,CAAC,eAAe;MACtC,IAAI,OAAO,IAAI,QAAQ,YAAY,WAAW,IAAI,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE;QAC/F,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,gBAAgB,CAAc,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE;QAClG,MAAM,IAAI,GACR,KAAK,CAAC,IAAI,CAAE,SAAS,IAAK,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,IAC1E,KAAK,CAAC,CAAC,CAAC,IACR,QAAQ,CAAC,aAAa,CAAc,2BAA2B,CAAC;QAClE,IAAI,EAAE,KAAK,CAAC;UAAE,aAAa,EAAE;QAAK,CAAC,CAAC;MACtC;IACF;IACA;IACA,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,gBAAgB,CAAc,8CAA8C,CAAC,EACtG,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,4BAA4B,CAAC,EAAE,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC,KAAK;IAChG;IACA;IACA,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,gBAAgB,CACrC,wIACF,CAAC,EACC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,4BAA4B,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,GAAG,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,GAAG,OAAO;EAChH,CAAC;EACD,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,OAAO,CAAC;EAClD,OAAO,MAAM;IACX,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACrD,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACnD,SAAS,CAAC,KAAK,CAAC,CAAC;EACnB,CAAC;AACH,CAAC","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["layout/PageTitle.tsx"],"sourcesContent":["import { createContext, createRoot, createSignal, createUniqueId, For, type JSX, onCleanup, onMount, Show, useContext } from \"solid-js\";\nimport { Dynamic, insert, isServer } from \"solid-js/web\";\nimport { IconButtonLink } from \"../actions/Button\";\nimport { installPageTitleController, PAGE_TITLE_CONTROLLER_ATTRIBUTE } from \"./page-title-controller\";\nimport { useWorkspaceMessages } from \"./workspace-messages\";\n\n/** A page above the current one. Only pages someone can go back to are levels, so each has a link. */\nexport type PageTrailLink = { title: string; href: string };\n/** The current page and the pages above it, nearest last. */\nexport type PageTrailState = { title: string; ancestors: PageTrailLink[] };\n\nexport type PageTitleProps = {\n trail: PageTrailState;\n /** Quiet text after the title, for example a count. */\n subtitle?: JSX.Element;\n /** Defaults to `\"h1\"`. Chrome that repeats a title the page already shows uses `\"p\"`. */\n as?: \"h1\" | \"h2\" | \"p\";\n /**\n * Marks a title drawn by surrounding chrome, such as the workspace head or a\n * host shell. It steps back when the page renders its own `PageTitle`, so a\n * page has one title with one way up.\n */\n fallback?: boolean;\n class?: string;\n};\n\n/** Window event a host dispatches after publishing a new page trail. */\nexport const PAGE_TRAIL_EVENT = \"k2b:page-trail\";\nconst SOURCE_SELECTOR = \"script[data-k2b-page-trail]\";\n\nconst isTrail = (value: unknown): value is PageTrailState => {\n if (!value || typeof value !== \"object\") return false;\n const trail = value as Partial<PageTrailState>;\n return (\n typeof trail.title === \"string\" &&\n Array.isArray(trail.ancestors) &&\n trail.ancestors.every((link) => typeof link?.title === \"string\" && typeof link?.href === \"string\")\n );\n};\n\n/** The trail a host published for this document, or `undefined` outside a browser or without one. */\nexport const readPageTrail = (): PageTrailState | undefined => {\n if (typeof document === \"undefined\") return undefined;\n const source = document.querySelector(SOURCE_SELECTOR);\n if (!source?.textContent) return undefined;\n try {\n const value: unknown = JSON.parse(source.textContent);\n return isTrail(value) ? value : undefined;\n } catch {\n return undefined;\n }\n};\n\n/** `<` is escaped so a title can never end the script element it travels in. */\nconst serializeTrail = (trail: PageTrailState): string => JSON.stringify(trail).replace(/</g, \"\\\\u003c\");\n\n/**\n * Publishes a new trail for the document in the browser, for example after an\n * in-page navigation. Workspace heads and page titles that read the host's\n * trail follow it.\n */\nexport const setPageTrail = (trail: PageTrailState): void => {\n if (typeof document === \"undefined\") return;\n let source = document.querySelector(SOURCE_SELECTOR);\n if (!source) {\n source = document.createElement(\"script\");\n source.setAttribute(\"type\", \"application/json\");\n source.setAttribute(\"data-k2b-page-trail\", \"\");\n document.body.append(source);\n }\n source.textContent = serializeTrail(trail);\n window.dispatchEvent(new Event(PAGE_TRAIL_EVENT));\n};\n\nconst PageTrailContext = createContext<() => PageTrailState | undefined>();\nconst OwnTitleContext = createContext<() => void>();\n/** The element around a page whose `data-k2b-own-title` says that the page shows its own `PageTitle`. */\nconst OWN_TITLE_HOST = \"data-k2b-title-host\";\nconst syncOwnTitle = (host: HTMLElement) =>\n host.toggleAttribute(\"data-k2b-own-title\", host.querySelector(\".k2b-page-title:not([data-fallback])\") !== null);\n\n/**\n * Gives a host's page trail to everything below it. During server rendering\n * the context carries it; the provider also publishes it into the document,\n * where browser-rendered parts such as islands read it. Below a provider that\n * renders in the browser, its `trail` prop is the source: update the prop.\n *\n * `onOwnTitle` runs on the server for each `PageTitle` below that is not a\n * fallback. The host then sets `data-k2b-own-title` on an element around the\n * page, inside the `k2b-ui` root, so the chrome's fallback titles step back.\n * With `data-k2b-title-host` on that element, titles that mount or leave in\n * the browser keep the attribute current.\n */\nexport function PageTrailProvider(props: {\n trail: PageTrailState | undefined;\n onOwnTitle?: () => void;\n children: JSX.Element;\n}): JSX.Element {\n return (\n <PageTrailContext.Provider value={() => props.trail}>\n <OwnTitleContext.Provider value={() => props.onOwnTitle?.()}>\n <Show when={props.trail}>\n {(trail) => <script type=\"application/json\" data-k2b-page-trail=\"\" innerHTML={serializeTrail(trail())} />}\n </Show>\n {props.children}\n </OwnTitleContext.Provider>\n </PageTrailContext.Provider>\n );\n}\n\n/** The host's page trail: from the provider while rendering below it, otherwise from the document. */\nexport const usePageTrail = (): (() => PageTrailState | undefined) => {\n const context = useContext(PageTrailContext);\n if (context) return context;\n if (typeof window === \"undefined\") return () => undefined;\n const [trail, setTrail] = createSignal(readPageTrail());\n const update = () => setTrail(readPageTrail());\n window.addEventListener(PAGE_TRAIL_EVENT, update);\n onCleanup(() => window.removeEventListener(PAGE_TRAIL_EVENT, update));\n return trail;\n};\n\n/**\n * A page title with its way up. The number of pages above decides the form:\n * none shows the title alone; one puts \"‹ Parent\" above it; more put a path\n * row above it whose middle collapses into \"…\" only when it does not fit.\n * Both rows share the same height, so the title never moves between depths.\n * On phones a back arrow left of the title replaces the row above.\n */\nexport function PageTitle(props: PageTitleProps): JSX.Element {\n const messages = useWorkspaceMessages();\n // A title rendered on the server from the host's trail follows the host's later trails (see `followPageTrail`).\n const host = isServer ? useContext(PageTrailContext) : undefined;\n if (isServer && !props.fallback) useContext(OwnTitleContext)?.();\n const menuId = `k2b-page-title-menu-${createUniqueId()}`;\n const ancestors = () => props.trail.ancestors;\n const parent = () => ancestors().at(-1);\n let root: HTMLDivElement | undefined;\n // A host may control every title in the document at once; a title outside\n // one still collapses its path.\n onMount(() => {\n // A title that the page shows after loading, such as one a client-side step brings, marks its host as well.\n // Without a host that marks its page, the `k2b-ui` root stands for it.\n const titleHost = props.fallback ? null : (root?.closest<HTMLElement>(`[${OWN_TITLE_HOST}]`) ?? root?.closest<HTMLElement>(\".k2b-ui\"));\n if (titleHost) {\n syncOwnTitle(titleHost);\n onCleanup(() => queueMicrotask(() => syncOwnTitle(titleHost)));\n }\n if (!root || root.closest(`[${PAGE_TITLE_CONTROLLER_ATTRIBUTE}]`)) return;\n onCleanup(installPageTitleController(root));\n });\n return (\n <div\n ref={root}\n class={`k2b-page-title ${props.class ?? \"\"}`}\n data-depth={ancestors().length}\n data-fallback={props.fallback ? \"\" : undefined}\n data-k2b-server={isServer && props.trail === host?.() ? \"\" : undefined}\n >\n <Show when={parent()}>\n {(up) => (\n <IconButtonLink\n class=\"k2b-page-title__back\"\n href={up().href}\n label={messages().backTo({ page: up().title })}\n data-k2b-page-trail-link=\"\"\n data-k2b-page-trail-up=\"\"\n >\n <i class=\"ti ti-chevron-left\" aria-hidden=\"true\" />\n </IconButtonLink>\n )}\n </Show>\n <div class=\"k2b-page-title__copy\">\n <Show when={ancestors().length === 1 && parent()}>\n {(up) => (\n <nav class=\"k2b-page-title__trail\" aria-label={messages().path}>\n <a\n class=\"k2b-page-title__up\"\n href={up().href}\n aria-label={messages().backTo({ page: up().title })}\n data-k2b-page-trail-link=\"\"\n data-k2b-page-trail-up=\"\"\n >\n <i class=\"ti ti-chevron-left\" aria-hidden=\"true\" />\n <span class=\"k2b-page-title__label\">{up().title}</span>\n </a>\n </nav>\n )}\n </Show>\n <Show when={ancestors().length > 1}>\n <nav class=\"k2b-page-title__trail\" aria-label={messages().path}>\n <ol class=\"k2b-page-title__path\">\n <For each={ancestors()}>\n {(link, index) => (\n <>\n <Show when={index() === 1}>\n <li class=\"k2b-page-title__more\" hidden>\n <i class=\"ti ti-chevron-right\" aria-hidden=\"true\" />\n <button type=\"button\" class=\"k2b-page-title__more-button\" popovertarget={menuId} aria-label={messages().moreLevels}>\n …\n </button>\n </li>\n </Show>\n <li class=\"k2b-page-title__crumb\" data-index={index()}>\n <Show when={index() > 0}>\n <i class=\"ti ti-chevron-right\" aria-hidden=\"true\" />\n </Show>\n <a\n href={link.href}\n data-k2b-page-trail-link=\"\"\n data-k2b-page-trail-up={index() === ancestors().length - 1 ? \"\" : undefined}\n class=\"k2b-page-title__label\"\n >\n {link.title}\n </a>\n </li>\n </>\n )}\n </For>\n </ol>\n <div id={menuId} popover=\"auto\" class=\"k2b-dropdown__menu k2b-page-title__menu\">\n <For each={ancestors()}>\n {(link, index) => (\n <a class=\"k2b-dropdown__item\" href={link.href} data-index={index()} data-k2b-page-trail-link=\"\" hidden>\n {link.title}\n </a>\n )}\n </For>\n </div>\n </nav>\n </Show>\n <Dynamic component={props.as ?? \"h1\"} class=\"k2b-page-title__title\">\n <span class=\"k2b-page-title__text\">{props.trail.title}</span>\n <Show when={props.subtitle}>\n <small class=\"k2b-page-title__subtitle\">{props.subtitle}</small>\n </Show>\n </Dynamic>\n </div>\n </div>\n );\n}\n\n/**\n * Keeps server-rendered titles of the host's trail current: a workspace head\n * that never hydrates, its heading, and an app's own header title from the\n * host's trail.\n * When the host publishes a new trail, for example after `setPageTrail()`,\n * each such title is replaced in place by a live one with the same element,\n * class, and subtitle, and a head learns whether it now has a page above it.\n * Titles inside islands render in the browser anyway. Returns the disposer.\n */\nexport const followPageTrail = (root: ParentNode = document): (() => void) => {\n const disposers = new Map<Text, () => void>();\n const upgrade = () => {\n for (const [place, dispose] of disposers) {\n if (place.isConnected) continue;\n dispose();\n disposers.delete(place);\n }\n const trail = readPageTrail();\n for (const element of root.querySelectorAll<HTMLElement>(\".k2b-page-title[data-k2b-server]\")) {\n const row = element.parentElement;\n if (!row || element.closest(\"solid-island, solid-client\")) continue;\n const tag = element.querySelector(\".k2b-page-title__title\")?.localName;\n const as = tag === \"p\" || tag === \"h2\" ? tag : \"h1\";\n const fallback = element.hasAttribute(\"data-fallback\");\n const extra = [...element.classList].filter((name) => name !== \"k2b-page-title\").join(\" \") || undefined;\n const subtitle = element.querySelector(\".k2b-page-title__subtitle\");\n const subtitleNodes = subtitle ? [...subtitle.childNodes] : undefined;\n // A link focused in the server title keeps focus in the live one: same kind, then same address.\n const active = document.activeElement;\n const focused =\n active && element.contains(active)\n ? {\n kind: [\"k2b-page-title__up\", \"k2b-page-title__back\"].find((name) => active.classList.contains(name)),\n href: active.getAttribute(\"href\"),\n }\n : undefined;\n // The live title takes the server title's place, before whatever follows it in the row.\n const place = document.createTextNode(\"\");\n row.insertBefore(place, element);\n element.remove();\n disposers.set(\n place,\n createRoot((dispose) => {\n const live = usePageTrail();\n insert(\n row,\n () => (\n <Show when={live()}>\n {(current) => <PageTitle trail={current()} as={as} fallback={fallback} class={extra} subtitle={subtitleNodes} />}\n </Show>\n ),\n place,\n );\n return dispose;\n }),\n );\n const upgraded = place.previousSibling;\n if (focused && upgraded instanceof HTMLElement && upgraded.classList.contains(\"k2b-page-title\")) {\n const links = focused.kind ? [...upgraded.querySelectorAll<HTMLElement>(`a.${focused.kind}`)] : [];\n const link =\n links.find((candidate) => candidate.getAttribute(\"href\") === focused.href) ??\n links[0] ??\n upgraded.querySelector<HTMLElement>(\"a[data-k2b-page-trail-up]\");\n link?.focus({ preventScroll: true });\n }\n }\n // A server-rendered workspace heading carries only the title.\n for (const heading of root.querySelectorAll<HTMLElement>(\"[data-k2b-page-trail-title][data-k2b-server]\"))\n if (trail && !heading.closest(\"solid-island, solid-client\")) heading.textContent = trail.title;\n // The row's `data-trail` decides whether it shows; it follows the depth. A\n // workspace head holds its title in its lead.\n for (const row of root.querySelectorAll<HTMLElement>(\n \"[data-trail]:has(> .k2b-page-title[data-fallback]), [data-trail]:has(> .k2b-app-workspace__head-lead > .k2b-page-title[data-fallback])\",\n ))\n if (!row.closest(\"solid-island, solid-client\")) row.dataset.trail = trail?.ancestors.length ? \"up\" : \"title\";\n };\n window.addEventListener(PAGE_TRAIL_EVENT, upgrade);\n return () => {\n window.removeEventListener(PAGE_TRAIL_EVENT, upgrade);\n for (const dispose of disposers.values()) dispose();\n disposers.clear();\n };\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -47,6 +47,7 @@ const SELECTION_MARK_SELECTOR = '[aria-selected="true"], [aria-current]:not([ari
|
|
|
47
47
|
const IGNORED_SELECTION_MARK_SELECTOR = "[data-calendar-day-key]";
|
|
48
48
|
const clamp = (value, min, max) => Math.round(Math.min(max, Math.max(min, value)));
|
|
49
49
|
const eventElement = event => event.target instanceof Element ? event.target : null;
|
|
50
|
+
const PREVIEW_FOCUS_SELECTOR = ".k2b-app-workspace__sidebar-preview-trigger:not([data-row-trigger])";
|
|
50
51
|
const resizeHandle = event => eventElement(event)?.closest(HANDLE_SELECTOR) ?? null;
|
|
51
52
|
const resizeKind = handle => {
|
|
52
53
|
const value = handle.dataset.appWorkspaceResize;
|
|
@@ -1733,7 +1734,16 @@ export const installAppWorkspaceController = (options = {}) => {
|
|
|
1733
1734
|
* arriving at a handle was announced whatever `aria-valuenow`/`valuemax` the
|
|
1734
1735
|
* last drag left behind.
|
|
1735
1736
|
*/
|
|
1737
|
+
// A keyboard-focused action preview covers the row's last action, so the actions before it say so. CSS cannot ask
|
|
1738
|
+
// this through `:has()` from the actions' buttons without restyling every button of the page on each DOM change.
|
|
1739
|
+
const syncPreviewFocus = event => {
|
|
1740
|
+
const trigger = eventElement(event)?.closest(PREVIEW_FOCUS_SELECTOR);
|
|
1741
|
+
const actions = trigger?.previousElementSibling;
|
|
1742
|
+
if (!trigger || !actions?.matches(".k2b-app-workspace__sidebar-item-actions")) return;
|
|
1743
|
+
if (event.type === "focusin" && trigger.matches(":focus-visible")) actions.setAttribute("data-preview-focus", "");else actions.removeAttribute("data-preview-focus");
|
|
1744
|
+
};
|
|
1736
1745
|
const onFocusIn = event => {
|
|
1746
|
+
syncPreviewFocus(event);
|
|
1737
1747
|
const handle = resizeHandle(event);
|
|
1738
1748
|
const kind = handle ? resizeKind(handle) : null;
|
|
1739
1749
|
const root = handle ? workspaceRoot(handle) : null;
|
|
@@ -1889,6 +1899,7 @@ export const installAppWorkspaceController = (options = {}) => {
|
|
|
1889
1899
|
phone?.addEventListener("change", syncPhonePages);
|
|
1890
1900
|
eventRoot.addEventListener("keydown", onKeyDown);
|
|
1891
1901
|
eventRoot.addEventListener("focusin", onFocusIn);
|
|
1902
|
+
eventRoot.addEventListener("focusout", syncPreviewFocus);
|
|
1892
1903
|
window.addEventListener("resize", onResize);
|
|
1893
1904
|
syncPhonePages();
|
|
1894
1905
|
syncObservedRoots();
|
|
@@ -1966,6 +1977,7 @@ export const installAppWorkspaceController = (options = {}) => {
|
|
|
1966
1977
|
phone?.removeEventListener("change", syncHostState);
|
|
1967
1978
|
eventRoot.removeEventListener("keydown", onKeyDown);
|
|
1968
1979
|
eventRoot.removeEventListener("focusin", onFocusIn);
|
|
1980
|
+
eventRoot.removeEventListener("focusout", syncPreviewFocus);
|
|
1969
1981
|
window.removeEventListener("resize", onResize);
|
|
1970
1982
|
};
|
|
1971
1983
|
};
|