@k2b/ui 0.24.0 → 0.26.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/README.md +2 -2
- package/dist/browser/actions/Dropdown.js +67 -52
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/GestureMenu.js +5 -5
- package/dist/browser/actions/GestureMenu.js.map +1 -1
- package/dist/browser/actions/SpotlightSearch.js +13 -6
- package/dist/browser/actions/SpotlightSearch.js.map +1 -1
- package/dist/browser/actions/Toolbar.js +75 -1
- package/dist/browser/actions/Toolbar.js.map +1 -1
- package/dist/browser/content/Calendar.js +1539 -911
- package/dist/browser/content/Calendar.js.map +1 -1
- package/dist/browser/content/CalendarDayView.js +5 -4
- package/dist/browser/content/CalendarDayView.js.map +1 -1
- package/dist/browser/content/CalendarWeekView.js +5 -4
- package/dist/browser/content/CalendarWeekView.js.map +1 -1
- package/dist/browser/content/Kbd.js +51 -0
- package/dist/browser/content/Kbd.js.map +1 -0
- package/dist/browser/content/LabelChip.js +38 -0
- package/dist/browser/content/LabelChip.js.map +1 -0
- package/dist/browser/content/MarkdownView.js +2 -1
- package/dist/browser/content/MarkdownView.js.map +1 -1
- package/dist/browser/content/Steps.js +34 -0
- package/dist/browser/content/Steps.js.map +1 -0
- package/dist/browser/content/Timeline.js +3 -3
- package/dist/browser/content/Timeline.js.map +1 -1
- package/dist/browser/content/VirtualFeed.js +33 -1
- package/dist/browser/content/VirtualFeed.js.map +1 -1
- package/dist/browser/content/calendar-dialogs.js +32 -60
- package/dist/browser/content/calendar-dialogs.js.map +1 -1
- package/dist/browser/content/calendar-month-scroll.js +80 -0
- package/dist/browser/content/calendar-month-scroll.js.map +1 -0
- package/dist/browser/content/calendar-time-view.js +0 -1
- package/dist/browser/content/calendar-time-view.js.map +1 -1
- package/dist/browser/content/index.js +4 -1
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/content/markdown-info-blocks.js +33 -5
- package/dist/browser/content/markdown-info-blocks.js.map +1 -1
- package/dist/browser/feedback/prompts.js +17 -3
- package/dist/browser/feedback/prompts.js.map +1 -1
- package/dist/browser/index.js +1 -0
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/inputs/Combobox.js +22 -3
- package/dist/browser/inputs/Combobox.js.map +1 -1
- package/dist/browser/inputs/QrScanner.js +2 -1
- package/dist/browser/inputs/QrScanner.js.map +1 -1
- package/dist/browser/intl/index.js +1 -0
- package/dist/browser/intl/index.js.map +1 -1
- package/dist/browser/intl/shortcut-messages.js +77 -0
- package/dist/browser/intl/shortcut-messages.js.map +1 -0
- package/dist/browser/intl/shortcut.js +123 -0
- package/dist/browser/intl/shortcut.js.map +1 -0
- package/dist/browser/layout/AppWorkspace.js +355 -338
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/TableOfContents.js +115 -0
- package/dist/browser/layout/TableOfContents.js.map +1 -0
- package/dist/browser/layout/app-workspace-controller.js +7 -50
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/layout/index.js +1 -0
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/layout/scroll-fade.js +14 -9
- package/dist/browser/layout/scroll-fade.js.map +1 -1
- package/dist/browser/layout/sidebar-scroll-memory.js +38 -0
- package/dist/browser/layout/sidebar-scroll-memory.js.map +1 -0
- package/dist/browser/layout/table-of-contents-messages.js +19 -0
- package/dist/browser/layout/table-of-contents-messages.js.map +1 -0
- package/dist/browser/motion.js +7 -0
- package/dist/browser/motion.js.map +1 -0
- package/dist/browser/surfaces/LinkCard.js +40 -24
- package/dist/browser/surfaces/LinkCard.js.map +1 -1
- package/dist/ssr/actions/Dropdown.js +11 -5
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/GestureMenu.js +5 -5
- package/dist/ssr/actions/GestureMenu.js.map +1 -1
- package/dist/ssr/actions/SpotlightSearch.js +9 -3
- package/dist/ssr/actions/SpotlightSearch.js.map +1 -1
- package/dist/ssr/actions/Toolbar.js +67 -1
- package/dist/ssr/actions/Toolbar.js.map +1 -1
- package/dist/ssr/content/Calendar.js +864 -312
- package/dist/ssr/content/Calendar.js.map +1 -1
- package/dist/ssr/content/CalendarDayView.js +5 -4
- package/dist/ssr/content/CalendarDayView.js.map +1 -1
- package/dist/ssr/content/CalendarWeekView.js +5 -4
- package/dist/ssr/content/CalendarWeekView.js.map +1 -1
- package/dist/ssr/content/Kbd.js +38 -0
- package/dist/ssr/content/Kbd.js.map +1 -0
- package/dist/ssr/content/LabelChip.js +21 -0
- package/dist/ssr/content/LabelChip.js.map +1 -0
- package/dist/ssr/content/MarkdownView.js +2 -1
- package/dist/ssr/content/MarkdownView.js.map +1 -1
- package/dist/ssr/content/Steps.js +14 -0
- package/dist/ssr/content/Steps.js.map +1 -0
- package/dist/ssr/content/Timeline.js +3 -3
- package/dist/ssr/content/Timeline.js.map +1 -1
- package/dist/ssr/content/VirtualFeed.js +33 -1
- package/dist/ssr/content/VirtualFeed.js.map +1 -1
- package/dist/ssr/content/calendar-dialogs.js +12 -32
- package/dist/ssr/content/calendar-dialogs.js.map +1 -1
- package/dist/ssr/content/calendar-month-scroll.js +80 -0
- package/dist/ssr/content/calendar-month-scroll.js.map +1 -0
- package/dist/ssr/content/calendar-time-view.js +0 -1
- package/dist/ssr/content/calendar-time-view.js.map +1 -1
- package/dist/ssr/content/index.js +4 -1
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/content/markdown-info-blocks.js +33 -5
- package/dist/ssr/content/markdown-info-blocks.js.map +1 -1
- package/dist/ssr/feedback/prompts.js +17 -3
- package/dist/ssr/feedback/prompts.js.map +1 -1
- package/dist/ssr/index.js +1 -0
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/inputs/Combobox.js +18 -3
- package/dist/ssr/inputs/Combobox.js.map +1 -1
- package/dist/ssr/inputs/QrScanner.js +2 -1
- package/dist/ssr/inputs/QrScanner.js.map +1 -1
- package/dist/ssr/intl/index.js +1 -0
- package/dist/ssr/intl/index.js.map +1 -1
- package/dist/ssr/intl/shortcut-messages.js +77 -0
- package/dist/ssr/intl/shortcut-messages.js.map +1 -0
- package/dist/ssr/intl/shortcut.js +123 -0
- package/dist/ssr/intl/shortcut.js.map +1 -0
- package/dist/ssr/layout/AppWorkspace.js +77 -72
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/TableOfContents.js +79 -0
- package/dist/ssr/layout/TableOfContents.js.map +1 -0
- package/dist/ssr/layout/app-workspace-controller.js +7 -50
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/layout/index.js +1 -0
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/layout/scroll-fade.js +14 -9
- package/dist/ssr/layout/scroll-fade.js.map +1 -1
- package/dist/ssr/layout/sidebar-scroll-memory.js +38 -0
- package/dist/ssr/layout/sidebar-scroll-memory.js.map +1 -0
- package/dist/ssr/layout/table-of-contents-messages.js +19 -0
- package/dist/ssr/layout/table-of-contents-messages.js.map +1 -0
- package/dist/ssr/motion.js +7 -0
- package/dist/ssr/motion.js.map +1 -0
- package/dist/ssr/surfaces/LinkCard.js +26 -10
- package/dist/ssr/surfaces/LinkCard.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/Dropdown.d.ts +12 -0
- package/dist/types/actions/SpotlightSearch.d.ts +2 -0
- package/dist/types/content/Calendar.d.ts +16 -6
- package/dist/types/content/Kbd.d.ts +16 -0
- package/dist/types/content/LabelChip.d.ts +12 -0
- package/dist/types/content/MarkdownView.d.ts +2 -1
- package/dist/types/content/Steps.d.ts +12 -0
- package/dist/types/content/VirtualFeed.d.ts +8 -0
- package/dist/types/content/calendar-dialogs.d.ts +0 -2
- package/dist/types/content/calendar-month-scroll.d.ts +25 -0
- package/dist/types/content/calendar-time-view.d.ts +0 -1
- package/dist/types/content/index.d.ts +7 -1
- package/dist/types/content/markdown-info-blocks.d.ts +21 -4
- package/dist/types/feedback/prompts.d.ts +8 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/inputs/Combobox.d.ts +1 -0
- package/dist/types/intl/index.d.ts +2 -0
- package/dist/types/intl/shortcut-messages.d.ts +35 -0
- package/dist/types/intl/shortcut.d.ts +29 -0
- package/dist/types/layout/AppWorkspace.d.ts +3 -1
- package/dist/types/layout/TableOfContents.d.ts +24 -0
- package/dist/types/layout/index.d.ts +2 -0
- package/dist/types/layout/scroll-fade.d.ts +2 -0
- package/dist/types/layout/sidebar-scroll-memory.d.ts +6 -0
- package/dist/types/layout/table-of-contents-messages.d.ts +4 -0
- package/dist/types/motion.d.ts +6 -0
- package/dist/types/surfaces/LinkCard.d.ts +3 -0
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["content/MarkdownView.tsx"],"sourcesContent":["import { Marked, Renderer, type Tokens } from \"marked\";\nimport { useLocale } from \"../intl/locale\";\nimport { markdownInfoBlocks } from \"./markdown-info-blocks\";\nimport { markdownLinkReference, renderMarkdownLink } from \"./markdown-links\";\n\ntype CommonProps = MarkdownRenderOptions & {\n /** Optional additional CSS classes */\n class?: string;\n /**\n * Visual heading scale. Markdown heading levels and document structure stay\n * unchanged.\n */\n headingScale?: \"compact\" | \"normal\" | \"large\";\n};\n\nexport type MarkdownViewProps = CommonProps &\n (\n | {\n /** Untrusted Markdown. Raw HTML and unsafe link protocols are escaped. */\n markdown: string;\n /** Exact standalone text tokens to emphasize without changing Markdown parsing or trusted-HTML boundaries. */\n inlineTokens?: readonly string[];\n trustedHtml?: never;\n }\n | {\n /** Explicitly trusted, already-rendered HTML. The caller owns sanitization. */\n trustedHtml: string;\n markdown?: never;\n inlineTokens?: never;\n }\n );\n\nexport type MarkdownRenderOptions = {\n inlineTokens?: readonly string[];\n /** Whether to render images. False renders alt text without resource requests. Defaults to true. */\n allowImages?: boolean;\n /** Optional protocol allowlist, including trailing colons. Relative URLs resolve as HTTPS. */\n linkProtocols?: readonly string[];\n linkTarget?: \"_blank\";\n /** Locale for the screen-reader names of untitled info blocks. `MarkdownView` passes the inherited render locale. */\n locale?: string;\n};\n\nexport const escapeHtml = (value: string): string =>\n value.replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\").replaceAll('\"', \""\").replaceAll(\"'\", \"'\");\n\nconst safeUrl = (value: string): string | null => {\n const normalized = value.trim().replace(/[\\u0000-\\u001f\\u007f-\\u009f\\s]+/g, \"\");\n if (/^(?:javascript|vbscript|data):/i.test(normalized)) return null;\n return value;\n};\n\nconst normalizeInlineTokens = (tokens: readonly string[] | undefined): string[] =>\n [...new Set(tokens?.filter(Boolean) ?? [])].sort((left, right) => right.length - left.length);\n\nconst isStandaloneInlineToken = (text: string, start: number, value: string): boolean => {\n const before = text[start - 1];\n if (before && /[a-zA-Z0-9_.%+\\-]/.test(before)) return false;\n const end = start + value.length;\n const after = text[end];\n if (after && /[a-zA-Z0-9_@]/.test(after)) return false;\n return !(after === \".\" && /[a-zA-Z0-9_]/.test(text[end + 1] ?? \"\"));\n};\n\nexport const createSafeRenderer = (options: MarkdownRenderOptions = {}): Renderer => {\n const renderer = new Renderer();\n const inlineTokens = normalizeInlineTokens(options.inlineTokens);\n const baseText = renderer.text.bind(renderer);\n // marked flags text that follows an inline <pre>, <code>, <kbd> or <script>\n // tag as already escaped, because it expects that tag to reach the output as\n // HTML. The tag is escaped here, so the text after it is escaped as well.\n const renderText: Renderer[\"text\"] = (token) => baseText(token.type === \"text\" && token.escaped ? { ...token, escaped: false } : token);\n const renderTable = renderer.table.bind(renderer);\n renderer.table = (token: Tokens.Table) => {\n const table = renderTable(token);\n const content = token.header.every((cell) => !cell.text.trim()) ? table.replace(/<thead>[\\s\\S]*?<\\/thead>\\n?/, \"\") : table;\n return `<div class=\"k2b-content-markdown__table\" tabindex=\"0\">${content}</div>`;\n };\n renderer.html = ({ text }: Tokens.HTML | Tokens.Tag) => escapeHtml(text);\n renderer.link = function ({ href, title, tokens }: Tokens.Link) {\n const body = this.parser.parseInline(tokens);\n const url = safeUrl(href);\n if (!url) return body;\n if (options.linkProtocols) {\n try {\n if (!options.linkProtocols.includes(new URL(url, \"https://markdown.invalid/\").protocol)) return body;\n } catch {\n return body;\n }\n }\n return renderMarkdownLink({\n href: url,\n html: body,\n title: title ?? undefined,\n target: options.linkTarget,\n reference: markdownLinkReference(url),\n locale: options.locale,\n });\n };\n renderer.image = ({ href, title, text }: Tokens.Image) => {\n const url = safeUrl(href);\n if (!url || options.allowImages === false) return escapeHtml(text);\n const titleAttribute = title ? ` title=\"${escapeHtml(title)}\"` : \"\";\n return `<img src=\"${escapeHtml(url)}\" alt=\"${escapeHtml(text)}\"${titleAttribute}>`;\n };\n renderer.text = (token) => {\n if (inlineTokens.length === 0 || token.type === \"escape\" || (\"tokens\" in token && token.tokens)) return renderText(token);\n const parts: string[] = [];\n let plainStart = 0;\n let cursor = 0;\n while (cursor < token.text.length) {\n const inlineToken = inlineTokens.find(\n (candidate) => token.text.startsWith(candidate, cursor) && isStandaloneInlineToken(token.text, cursor, candidate),\n );\n if (!inlineToken) {\n cursor += 1;\n continue;\n }\n if (plainStart < cursor) {\n const text = token.text.slice(plainStart, cursor);\n parts.push(renderText({ ...token, raw: text, text }));\n }\n parts.push(\n `<span class=\"k2b-content-markdown__inline-token\">${renderText({ ...token, raw: inlineToken, text: inlineToken })}</span>`,\n );\n cursor += inlineToken.length;\n plainStart = cursor;\n }\n if (plainStart === 0) return renderText(token);\n if (plainStart < token.text.length) {\n const text = token.text.slice(plainStart);\n parts.push(renderText({ ...token, raw: text, text }));\n }\n return parts.join(\"\");\n };\n return renderer;\n};\n\nexport const renderSafeMarkdown = (markdown: string, options: MarkdownRenderOptions = {}): string =>\n createSafeMarked(options.locale).parse(markdown, { async: false, renderer: createSafeRenderer(options) }) as string;\n\n/**\n * Internal to the package: the Markdown grammar of `renderSafeMarkdown`, for a component that renders with an adjusted\n * safe renderer or reads the tokens, as `MessageRow` does.\n */\nexport const createSafeMarked = (locale?: string): Marked => new Marked(markdownInfoBlocks({ locale }));\n\n/**\n * Markdown View Component (SSR)\n *\n * Renders untrusted Markdown safely by default. Raw HTML and unsafe link\n * protocols are escaped. Info blocks (`:::note`, `:::info`, `:::success`,\n * `:::warning`, `:::danger`) render as the calm `NoticeCard`. Already-rendered\n * HTML requires the deliberately named `trustedHtml` boundary; the caller owns\n * sanitization in that mode.\n *\n * @example\n * ```tsx\n * import { MarkdownView } from \"@k2b/ui\";\n *\n * <MarkdownView markdown={source} />;\n * ```\n *\n * @example Compact headings, e.g. inside comments or file previews:\n * ```tsx\n * <MarkdownView markdown={source} headingScale=\"compact\" />;\n * ```\n */\nexport default function MarkdownView(props: MarkdownViewProps) {\n const locale = useLocale();\n const html = () =>\n props.markdown !== undefined\n ? renderSafeMarkdown(props.markdown, {\n inlineTokens: props.inlineTokens,\n allowImages: props.allowImages,\n linkProtocols: props.linkProtocols,\n linkTarget: props.linkTarget,\n locale: locale(),\n })\n : props.trustedHtml;\n return (\n <div\n class={`k2b-content-markdown ${props.class ?? \"\"}`}\n data-heading-scale={props.headingScale && props.headingScale !== \"normal\" ? props.headingScale : undefined}\n innerHTML={html()}\n />\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["content/MarkdownView.tsx"],"sourcesContent":["import { Marked, Renderer, type Tokens } from \"marked\";\nimport { useLocale } from \"../intl/locale\";\nimport { markdownInfoBlocks } from \"./markdown-info-blocks\";\nimport { markdownLinkReference, renderMarkdownLink } from \"./markdown-links\";\n\ntype CommonProps = MarkdownRenderOptions & {\n /** Optional additional CSS classes */\n class?: string;\n /**\n * Visual heading scale. Markdown heading levels and document structure stay\n * unchanged.\n */\n headingScale?: \"compact\" | \"normal\" | \"large\";\n};\n\nexport type MarkdownViewProps = CommonProps &\n (\n | {\n /** Untrusted Markdown. Raw HTML and unsafe link protocols are escaped. */\n markdown: string;\n /** Exact standalone text tokens to emphasize without changing Markdown parsing or trusted-HTML boundaries. */\n inlineTokens?: readonly string[];\n trustedHtml?: never;\n }\n | {\n /** Explicitly trusted, already-rendered HTML. The caller owns sanitization. */\n trustedHtml: string;\n markdown?: never;\n inlineTokens?: never;\n }\n );\n\nexport type MarkdownRenderOptions = {\n inlineTokens?: readonly string[];\n /** Whether to render images. False renders alt text without resource requests. Defaults to true. */\n allowImages?: boolean;\n /** Optional protocol allowlist, including trailing colons. Relative URLs resolve as HTTPS. */\n linkProtocols?: readonly string[];\n linkTarget?: \"_blank\";\n /** Locale for the screen-reader names of untitled info blocks. `MarkdownView` passes the inherited render locale. */\n locale?: string;\n};\n\nexport const escapeHtml = (value: string): string =>\n value.replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\").replaceAll('\"', \""\").replaceAll(\"'\", \"'\");\n\nconst safeUrl = (value: string): string | null => {\n const normalized = value.trim().replace(/[\\u0000-\\u001f\\u007f-\\u009f\\s]+/g, \"\");\n if (/^(?:javascript|vbscript|data):/i.test(normalized)) return null;\n return value;\n};\n\nconst normalizeInlineTokens = (tokens: readonly string[] | undefined): string[] =>\n [...new Set(tokens?.filter(Boolean) ?? [])].sort((left, right) => right.length - left.length);\n\nconst isStandaloneInlineToken = (text: string, start: number, value: string): boolean => {\n const before = text[start - 1];\n if (before && /[a-zA-Z0-9_.%+\\-]/.test(before)) return false;\n const end = start + value.length;\n const after = text[end];\n if (after && /[a-zA-Z0-9_@]/.test(after)) return false;\n return !(after === \".\" && /[a-zA-Z0-9_]/.test(text[end + 1] ?? \"\"));\n};\n\nexport const createSafeRenderer = (options: MarkdownRenderOptions = {}): Renderer => {\n const renderer = new Renderer();\n const inlineTokens = normalizeInlineTokens(options.inlineTokens);\n const baseText = renderer.text.bind(renderer);\n // marked flags text that follows an inline <pre>, <code>, <kbd> or <script>\n // tag as already escaped, because it expects that tag to reach the output as\n // HTML. The tag is escaped here, so the text after it is escaped as well.\n const renderText: Renderer[\"text\"] = (token) => baseText(token.type === \"text\" && token.escaped ? { ...token, escaped: false } : token);\n const renderTable = renderer.table.bind(renderer);\n renderer.table = (token: Tokens.Table) => {\n const table = renderTable(token);\n const content = token.header.every((cell) => !cell.text.trim()) ? table.replace(/<thead>[\\s\\S]*?<\\/thead>\\n?/, \"\") : table;\n return `<div class=\"k2b-content-markdown__table\" tabindex=\"0\">${content}</div>`;\n };\n renderer.html = ({ text }: Tokens.HTML | Tokens.Tag) => escapeHtml(text);\n renderer.link = function ({ href, title, tokens }: Tokens.Link) {\n const body = this.parser.parseInline(tokens);\n const url = safeUrl(href);\n if (!url) return body;\n if (options.linkProtocols) {\n try {\n if (!options.linkProtocols.includes(new URL(url, \"https://markdown.invalid/\").protocol)) return body;\n } catch {\n return body;\n }\n }\n return renderMarkdownLink({\n href: url,\n html: body,\n title: title ?? undefined,\n target: options.linkTarget,\n reference: markdownLinkReference(url),\n locale: options.locale,\n });\n };\n renderer.image = ({ href, title, text }: Tokens.Image) => {\n const url = safeUrl(href);\n if (!url || options.allowImages === false) return escapeHtml(text);\n const titleAttribute = title ? ` title=\"${escapeHtml(title)}\"` : \"\";\n return `<img src=\"${escapeHtml(url)}\" alt=\"${escapeHtml(text)}\"${titleAttribute}>`;\n };\n renderer.text = (token) => {\n if (inlineTokens.length === 0 || token.type === \"escape\" || (\"tokens\" in token && token.tokens)) return renderText(token);\n const parts: string[] = [];\n let plainStart = 0;\n let cursor = 0;\n while (cursor < token.text.length) {\n const inlineToken = inlineTokens.find(\n (candidate) => token.text.startsWith(candidate, cursor) && isStandaloneInlineToken(token.text, cursor, candidate),\n );\n if (!inlineToken) {\n cursor += 1;\n continue;\n }\n if (plainStart < cursor) {\n const text = token.text.slice(plainStart, cursor);\n parts.push(renderText({ ...token, raw: text, text }));\n }\n parts.push(\n `<span class=\"k2b-content-markdown__inline-token\">${renderText({ ...token, raw: inlineToken, text: inlineToken })}</span>`,\n );\n cursor += inlineToken.length;\n plainStart = cursor;\n }\n if (plainStart === 0) return renderText(token);\n if (plainStart < token.text.length) {\n const text = token.text.slice(plainStart);\n parts.push(renderText({ ...token, raw: text, text }));\n }\n return parts.join(\"\");\n };\n return renderer;\n};\n\nexport const renderSafeMarkdown = (markdown: string, options: MarkdownRenderOptions = {}): string =>\n createSafeMarked(options.locale).parse(markdown, { async: false, renderer: createSafeRenderer(options) }) as string;\n\n/**\n * Internal to the package: the Markdown grammar of `renderSafeMarkdown`, for a component that renders with an adjusted\n * safe renderer or reads the tokens, as `MessageRow` does.\n */\nexport const createSafeMarked = (locale?: string): Marked => new Marked(markdownInfoBlocks({ locale }));\n\n/**\n * Markdown View Component (SSR)\n *\n * Renders untrusted Markdown safely by default. Raw HTML and unsafe link\n * protocols are escaped. Info blocks (`:::note`, `:::info`, `:::success`,\n * `:::warning`, `:::danger`) render on a tinted surface without a border.\n * The icon and title use the tone colour; body text stays neutral. Rendered\n * HTML requires the deliberately named `trustedHtml` boundary; the caller owns\n * sanitization in that mode.\n *\n * @example\n * ```tsx\n * import { MarkdownView } from \"@k2b/ui\";\n *\n * <MarkdownView markdown={source} />;\n * ```\n *\n * @example Compact headings, e.g. inside comments or file previews:\n * ```tsx\n * <MarkdownView markdown={source} headingScale=\"compact\" />;\n * ```\n */\nexport default function MarkdownView(props: MarkdownViewProps) {\n const locale = useLocale();\n const html = () =>\n props.markdown !== undefined\n ? renderSafeMarkdown(props.markdown, {\n inlineTokens: props.inlineTokens,\n allowImages: props.allowImages,\n linkProtocols: props.linkProtocols,\n linkTarget: props.linkTarget,\n locale: locale(),\n })\n : props.trustedHtml;\n return (\n <div\n class={`k2b-content-markdown ${props.class ?? \"\"}`}\n data-heading-scale={props.headingScale && props.headingScale !== \"normal\" ? props.headingScale : undefined}\n innerHTML={html()}\n />\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ssr as _$ssr } from "solid-js/web";
|
|
2
|
+
import { ssrStyleProperty as _$ssrStyleProperty } from "solid-js/web";
|
|
3
|
+
import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
|
|
4
|
+
import { escape as _$escape } from "solid-js/web";
|
|
5
|
+
var _tmpl$ = ["<ol class=\"", "\"", " style=\"", "\">", "</ol>"];
|
|
6
|
+
/**
|
|
7
|
+
* An ordered instruction list with accent numbers. Trusted HTML can use the same class.
|
|
8
|
+
* @example <Steps start={2}><li>Select Share.</li><li>Copy the link.</li></Steps>
|
|
9
|
+
*/
|
|
10
|
+
export function Steps(props) {
|
|
11
|
+
return _$ssr(_tmpl$, `k2b-steps${props.class ? ` ${_$escape(props.class, true)}` : ""}`, _$ssrAttribute("start", _$escape(props.start, true), false), _$ssrStyleProperty("--k2b-steps-start:", _$escape(props.start, true)), _$escape(props.children));
|
|
12
|
+
}
|
|
13
|
+
export default Steps;
|
|
14
|
+
//# sourceMappingURL=Steps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["content/Steps.tsx"],"sourcesContent":["import type { JSX } from \"solid-js\";\n\nexport type StepsProps = { children: JSX.Element; start?: number; class?: string };\n/**\n * An ordered instruction list with accent numbers. Trusted HTML can use the same class.\n * @example <Steps start={2}><li>Select Share.</li><li>Copy the link.</li></Steps>\n */\nexport function Steps(props: StepsProps): JSX.Element {\n return (\n <ol class={`k2b-steps${props.class ? ` ${props.class}` : \"\"}`} start={props.start} style={{ \"--k2b-steps-start\": props.start }}>\n {props.children}\n </ol>\n );\n}\nexport default Steps;\n"],"mappings":";;;;;AAGA;AACA;AACA;AACA;AACA,OAAO,SAAS,KAAK,CAAC,KAAiB,EAAe;EACpD,qBACa,YAAY,KAAK,CAAC,KAAK,GAAG,aAAI,KAAK,CAAC,KAAK,SAAE,GAAG,EAAE,EAAE,mCAAS,KAAK,CAAC,KAAK,mEAAgC,KAAK,CAAC,KAAK,mBACzH,KAAK,CAAC,QAAQ;AAGrB;AACA,eAAe,KAAK","ignoreList":[]}
|
|
@@ -24,6 +24,7 @@ import Dropdown from "../actions/Dropdown";
|
|
|
24
24
|
import { announce } from "../feedback/announce";
|
|
25
25
|
import { useDateConfigLocale } from "../intl/locale";
|
|
26
26
|
import { useUiMessages } from "../intl/messages";
|
|
27
|
+
import { prefersReducedMotion } from "../motion";
|
|
27
28
|
import { useTimelineMessages } from "./timeline-messages";
|
|
28
29
|
import { buildTimelineModel, parseTimelineTime, spanCss, spanPx, timelineDayKey, timelineHourOf } from "./timeline-model";
|
|
29
30
|
/** Unit sizes of the horizontal axis, as in the stylesheet; the server and the first render use them. */
|
|
@@ -38,7 +39,6 @@ const GESTURE_GAP_MS = 150;
|
|
|
38
39
|
const GLIDE_FROM = 50;
|
|
39
40
|
const COLOR_TOKENS = new Set(["blue", "emerald", "amber", "red", "violet", "cyan", "zinc"]);
|
|
40
41
|
const HEX_COLOR = /^#[0-9a-f]{3,8}$/i;
|
|
41
|
-
const reducedMotion = () => typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
42
42
|
const colorAttributes = color => color && HEX_COLOR.test(color) ? {
|
|
43
43
|
token: undefined,
|
|
44
44
|
accent: color
|
|
@@ -387,7 +387,7 @@ export default function Timeline(props) {
|
|
|
387
387
|
if (!primary) return;
|
|
388
388
|
event.preventDefault();
|
|
389
389
|
const delta = event.deltaY * (event.deltaMode === 1 ? 40 : event.deltaMode === 2 ? viewport.clientWidth : 1);
|
|
390
|
-
if (
|
|
390
|
+
if (prefersReducedMotion() || Math.abs(delta) < GLIDE_FROM && !wheelFrame) {
|
|
391
391
|
viewport.scrollLeft += delta;
|
|
392
392
|
return;
|
|
393
393
|
}
|
|
@@ -430,7 +430,7 @@ export default function Timeline(props) {
|
|
|
430
430
|
* arrives instead of cutting it short.
|
|
431
431
|
*/
|
|
432
432
|
const ownScrollBehavior = () => {
|
|
433
|
-
if (
|
|
433
|
+
if (prefersReducedMotion()) return "auto";
|
|
434
434
|
scrolled();
|
|
435
435
|
return "smooth";
|
|
436
436
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["content/Timeline.tsx"],"sourcesContent":["import type { DateContext } from \"@k2b/stdlib\";\nimport {\n createEffect,\n createMemo,\n createSignal,\n createUniqueId,\n For,\n Index,\n type JSX,\n on,\n onCleanup,\n onMount,\n Show,\n untrack,\n} from \"solid-js\";\nimport { Dynamic, isServer } from \"solid-js/web\";\nimport Dropdown, { type DropdownItem } from \"../actions/Dropdown\";\nimport { announce } from \"../feedback/announce\";\nimport { useDateConfigLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { useTimelineMessages } from \"./timeline-messages\";\nimport {\n buildTimelineModel,\n parseTimelineTime,\n spanCss,\n spanPx,\n type TimelineEntry,\n type TimelineGroup,\n type TimelineItem,\n type TimelineItemEntry,\n type TimelineModel,\n type TimelineMoreEntry,\n type TimelineUnits,\n timelineDayKey,\n timelineHourOf,\n} from \"./timeline-model\";\n\nexport type { TimelineColor, TimelineItem } from \"./timeline-model\";\n\nexport type TimelineController = {\n /** Scrolls a time into view; `start` (default) puts it near the start edge, `center` in the middle. */\n scrollToTime: (time: Date | string, options?: { align?: \"start\" | \"center\" }) => void;\n /** Scrolls the current time to the middle of the view. */\n scrollToNow: () => void;\n};\n\nexport type TimelineProps = {\n items: readonly TimelineItem[];\n /** Start of the loaded range. The view starts here, so pass the first time the reader should see. */\n from: Date | string;\n /** End of the loaded range (exclusive). */\n to: Date | string;\n /** The current time. Without it the timeline uses the clock and moves the now line every 30 seconds. */\n now?: Date | string;\n /** Accessible name of the region. Defaults to \"Timeline\". */\n label?: string;\n /** stdlib date context: time zone and locale of days, hours, and folds. */\n dateConfig?: DateContext;\n /** Convenience override for `dateConfig.timeZone`. */\n timeZone?: string;\n /** Level of the per-day headings. Defaults to 3. */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n /** Opens an item, on click, Enter, or Space. */\n onActivate?: (item: TimelineItem) => void;\n /** Changes the checkbox of an item, on a click on the box or Space. Leave it out when the reader may not change it. */\n onToggle?: (item: TimelineItem, checked: boolean) => void;\n /**\n * Called once when the reader nears the start, again once `from` moved and changed the strip's length. Extend `from`\n * to load earlier days.\n */\n onLoadEarlier?: () => unknown;\n /** Called once when the reader nears the end, again once `to` moved and changed the strip's length. Extend `to` to load later days. */\n onLoadLater?: () => unknown;\n /** Marks the region busy, for example while a range loads. */\n busy?: boolean;\n controller?: (controller: TimelineController) => void;\n class?: string;\n};\n\ntype Axis = \"horizontal\" | \"vertical\";\n\n/** Unit sizes of the horizontal axis, as in the stylesheet; the server and the first render use them. */\nconst HORIZONTAL_UNITS: TimelineUnits = [54, 48, 160, 0, 0];\n/** How far beyond the visible area the first render reaches, in pixels. */\nconst INITIAL_REACH = 3200;\n/** A scroll rests once this many frames passed without a scroll event and no finger is down. */\nconst REST_FRAMES = 8;\n/** A pause between wheel events that starts a new gesture. */\nconst GESTURE_GAP_MS = 150;\n/** Wheel steps from this size on, such as a mouse wheel's notches, glide; smaller ones, such as a trackpad's, apply at once. */\nconst GLIDE_FROM = 50;\nconst COLOR_TOKENS = new Set([\"blue\", \"emerald\", \"amber\", \"red\", \"violet\", \"cyan\", \"zinc\"]);\nconst HEX_COLOR = /^#[0-9a-f]{3,8}$/i;\n\nconst reducedMotion = () => typeof window.matchMedia === \"function\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n\nconst colorAttributes = (color: string | undefined) =>\n color && HEX_COLOR.test(color)\n ? { token: undefined, accent: color }\n : { token: color && COLOR_TOKENS.has(color) ? color : \"blue\", accent: undefined };\n\nconst isAllDay = (entry: TimelineEntry) => entry.kind === \"all-day\" || (entry.kind === \"more\" && entry.area === \"all-day\");\nconst asItem = (entry: TimelineEntry): TimelineItemEntry | undefined => (entry.kind === \"more\" ? undefined : entry);\nconst asMore = (entry: TimelineEntry): TimelineMoreEntry | undefined => (entry.kind === \"more\" ? entry : undefined);\n\n/** The nearest ancestor that scrolls vertically, the page included. */\nconst verticalScroller = (from: Element): Element | undefined => {\n for (let element = from.parentElement; element; element = element.parentElement) {\n if (element.scrollHeight <= element.clientHeight + 1) continue;\n const overflow = getComputedStyle(element).overflowY;\n if (overflow === \"auto\" || overflow === \"scroll\" || element === document.scrollingElement) return element;\n }\n const root = document.scrollingElement;\n return root && root.scrollHeight > root.clientHeight + 1 ? root : undefined;\n};\n\n/**\n * A continuous filmstrip of time: waking hours are proportional, nights and empty days fold, overlapping bands share\n * lanes. Wide containers show it horizontally, narrow ones vertically; both use the same model.\n */\nexport default function Timeline(props: TimelineProps): JSX.Element {\n const messages = useUiMessages();\n const timelineMessages = useTimelineMessages();\n const context = useDateConfigLocale(() => ({ ...props.dateConfig, timeZone: props.timeZone ?? props.dateConfig?.timeZone }));\n const baseId = createUniqueId().replace(/[^a-zA-Z0-9_-]/g, \"-\");\n const [clock, setClock] = createSignal(Date.now());\n const now = createMemo(() => {\n const fixed = parseTimelineTime(props.now, context());\n return Number.isFinite(fixed) ? fixed : clock();\n });\n const today = createMemo(() => timelineDayKey(now(), context()));\n const latest = createMemo<TimelineModel>(() =>\n buildTimelineModel({\n from: parseTimelineTime(props.from, context()),\n to: parseTimelineTime(props.to, context()),\n today: today(),\n items: props.items,\n context: context(),\n }),\n );\n /** The model on screen: the latest one, unless that one waits for the reader's scroll to rest (see `resting`). */\n const [model, setModel] = createSignal<TimelineModel>(untrack(latest));\n const groupsByKey = createMemo(() => new Map(model().groups.map((group) => [group.key, group])));\n\n // Formatting.\n const locale = () => context().locale ?? \"en\";\n const timeFormat = createMemo(\n () => new Intl.DateTimeFormat(locale(), { hour: \"2-digit\", minute: \"2-digit\", hourCycle: \"h23\", timeZone: context().timeZone }),\n );\n const formatTime = (time: number) => timeFormat().format(time);\n const dayFormat = createMemo(\n () => new Intl.DateTimeFormat(locale(), { weekday: \"short\", day: \"numeric\", month: \"short\", timeZone: context().timeZone }),\n );\n const longDayFormat = createMemo(\n () => new Intl.DateTimeFormat(locale(), { weekday: \"long\", day: \"numeric\", month: \"long\", timeZone: context().timeZone }),\n );\n const hoursFormat = createMemo(\n () => new Intl.NumberFormat(locale(), { style: \"unit\", unit: \"hour\", unitDisplay: \"short\", maximumFractionDigits: 1 }),\n );\n const noonOf = (key: string) => new Date(timelineHourOf(key, 12, context()));\n const dayRange = (first: string, last: string, format: Intl.DateTimeFormat) =>\n first === last ? format.format(noonOf(first)) : `${format.format(noonOf(first))} – ${format.format(noonOf(last))}`;\n const nightLabel = createMemo(() => {\n const format = new Intl.DateTimeFormat(locale(), { hour: \"2-digit\", minute: \"2-digit\", hourCycle: \"h23\", timeZone: \"UTC\" });\n return timelineMessages().timelineNight({\n start: format.format(Date.UTC(2000, 0, 1, 22)),\n end: format.format(Date.UTC(2000, 0, 1, 6)),\n });\n });\n const spoken = (entry: TimelineItemEntry): string => {\n const item = entry.item;\n const parts = [item.label];\n if (entry.kind === \"all-day\") parts.push(messages().allDay);\n else if (entry.end > entry.start)\n parts.push(timelineMessages().timelineTimeRange({ start: formatTime(entry.start), end: formatTime(entry.end) }));\n else parts.push(formatTime(entry.start));\n if (item.detail) parts.push(item.detail);\n parts.push(\n entry.kind === \"all-day\" ? dayRange(entry.firstKey, entry.lastKey, longDayFormat()) : longDayFormat().format(new Date(entry.start)),\n );\n if (item.checked !== undefined) parts.push(item.checked ? timelineMessages().timelineDone : timelineMessages().timelineOpen);\n return parts.join(\", \");\n };\n /** When an item happens, for a \"+n\" menu row. */\n const when = (entry: TimelineItemEntry): string => {\n if (entry.kind === \"all-day\") return `${messages().allDay}, ${dayRange(entry.firstKey, entry.lastKey, dayFormat())}`;\n return entry.end > entry.start ? `${formatTime(entry.start)}–${formatTime(entry.end)}` : formatTime(entry.start);\n };\n const isPast = (entry: TimelineEntry): boolean => {\n if (entry.kind === \"more\") return entry.hidden.every(isPast);\n if (entry.kind === \"all-day\") return entry.lastKey < today();\n return entry.end <= now();\n };\n\n // Layout of the axis the stylesheet chose, read from the viewport.\n let root: HTMLElement | undefined;\n let viewport: HTMLDivElement | undefined;\n let track: HTMLDivElement | undefined;\n const [layout, setLayout] = createSignal<{ axis: Axis; units: TimelineUnits }>({ axis: \"horizontal\", units: HORIZONTAL_UNITS });\n const readLayout = () => {\n if (!viewport) return layout();\n const style = getComputedStyle(viewport);\n const unit = (name: string) => Number.parseFloat(style.getPropertyValue(`--k2b-timeline-${name}`)) || 0;\n const units: TimelineUnits = [unit(\"hour\"), unit(\"night\"), unit(\"fold\"), unit(\"head\"), unit(\"row\")];\n return {\n axis: style.getPropertyValue(\"--k2b-timeline-axis\").trim() === \"vertical\" ? (\"vertical\" as const) : (\"horizontal\" as const),\n units: units.some((value) => value > 0) ? units : HORIZONTAL_UNITS,\n };\n };\n const px = (time: number) => spanPx(model().posOf(time), layout().units);\n\n /** The visible part of the track in its own pixels, clipped by the viewport and the window. */\n const visible = (): [number, number] => {\n if (!viewport || !track) return [0, INITIAL_REACH];\n const port = viewport.getBoundingClientRect();\n const box = track.getBoundingClientRect();\n const [portStart, portEnd, boxStart, limit] =\n layout().axis === \"horizontal\"\n ? [port.left, port.right, box.left, window.innerWidth]\n : [port.top, port.bottom, box.top, window.innerHeight];\n const start = Math.max(portStart, 0) - boxStart;\n return [start, Math.max(start, Math.min(portEnd, limit) - boxStart)];\n };\n const scrollBy = (distance: number, behavior: ScrollBehavior = \"instant\") => {\n // In device pixels: positions are sums of unit sizes, and an engine that cuts 4671.9999 to 4671 would move the view.\n const delta = Math.round(distance * window.devicePixelRatio) / window.devicePixelRatio;\n if (!viewport || Math.abs(delta) < 0.5) return;\n const horizontal = layout().axis === \"horizontal\";\n const scrollable = horizontal ? viewport.scrollWidth > viewport.clientWidth : viewport.scrollHeight > viewport.clientHeight;\n if (scrollable) viewport.scrollBy({ [horizontal ? \"left\" : \"top\"]: delta, behavior });\n else if (!horizontal) verticalScroller(viewport)?.scrollBy({ top: delta, behavior });\n };\n\n // Bounded rendering: groups whose reach meets the visible time range, widened by a screen, plus the focused group.\n const [range, setRange] = createSignal<[number, number]>();\n const shownRange = (): [number, number] => range() ?? [Number.NEGATIVE_INFINITY, model().timeAt(INITIAL_REACH, HORIZONTAL_UNITS)];\n const [active, setActive] = createSignal<string>();\n /** The item happening now or next. */\n const current = () => {\n const { order, entries } = model();\n return order.find((id) => {\n const entry = entries.get(id)!;\n return !isAllDay(entry) && entry.end >= now();\n });\n };\n const defaultActive = createMemo(() => current() ?? model().order.at(-1));\n const activeId = () => {\n const id = active();\n return id !== undefined && model().entries.has(id) ? id : defaultActive();\n };\n const renderedKeys = createMemo(() => {\n const [low, high] = shownRange();\n const focusGroup = model().entries.get(activeId() ?? \"\")?.group;\n return model()\n .groups.filter((group) => group.index === focusGroup || (group.reach[1] >= low && group.reach[0] <= high))\n .map((group) => group.key);\n });\n\n // Reading position: the time at the start edge stays in place when days load or the axis changes.\n /** The time at the start edge after the last refresh, for an axis change. */\n let edgeTime: number | undefined;\n /**\n * The time to hold in place. A load at the start spreads a leading night or fold over other times, so where the start\n * edge lies in one, the end of that segment holds instead, and with it everything after.\n */\n const anchorAt = (built: TimelineModel, start: number, units: TimelineUnits) => {\n const time = built.timeAt(start, units);\n const first = built.segments.find((segment) => segment.t1 > segment.t0);\n return first && first.kind !== \"wake\" && time < first.t1 ? first.t1 : time;\n };\n /** How far what the reader sees moves from one model to the next. */\n const shiftOf = (before: TimelineModel, after: TimelineModel) => {\n const { units } = layout();\n const time = anchorAt(before, visible()[0], units);\n return spanPx(after.posOf(time), units) - spanPx(before.posOf(time), units);\n };\n /**\n * Where each end of the range was, and how long the strip was, when that end was last asked for. An end is asked\n * again only once the range moved there and the strip's length changed: days that fold into the fold at that end\n * leave the reader where they were, and asking again would load an empty calendar week after week on its own.\n */\n let requestedFrom: { at: number; length: number } | undefined;\n let requestedTo: { at: number; length: number } | undefined;\n let pendingEarlier = false;\n let pendingLater = false;\n const loadEdge = (edge: \"earlier\" | \"later\") => {\n const load = edge === \"earlier\" ? props.onLoadEarlier : props.onLoadLater;\n if (!load) return;\n const settle = () => {\n if (edge === \"earlier\") pendingEarlier = false;\n else pendingLater = false;\n queueMicrotask(refresh);\n };\n if (edge === \"earlier\") pendingEarlier = true;\n else pendingLater = true;\n Promise.resolve().then(load).then(settle, settle);\n };\n const refresh = () => {\n if (!viewport) return;\n const built = model();\n const { units } = layout();\n const [start, end] = visible();\n const reach = Math.max(end - start, 600);\n edgeTime = built.timeAt(start, units);\n const [low, high] = range() ?? [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY];\n if (built.timeAt(start - reach / 2, units) < low || built.timeAt(end + reach / 2, units) > high)\n setRange([built.timeAt(start - reach, units), built.timeAt(end + reach, units)]);\n const length = spanPx(built.total, units);\n const due = (requested: { at: number; length: number } | undefined, at: number) =>\n requested === undefined || (requested.at !== at && requested.length !== length);\n if (start > reach) requestedFrom = undefined;\n else if (!pendingEarlier && due(requestedFrom, built.from)) {\n requestedFrom = { at: built.from, length };\n loadEdge(\"earlier\");\n }\n if (end < length - reach) requestedTo = undefined;\n else if (!pendingLater && due(requestedTo, built.to)) {\n requestedTo = { at: built.to, length };\n loadEdge(\"later\");\n }\n };\n\n const scrollToTime = (time: number, align: \"start\" | \"center\" = \"start\") => {\n if (!viewport) return;\n const [start, end] = visible();\n const target = px(time) - (align === \"center\" ? (end - start) / 2 : 16);\n scrollBy(target - start, ownScrollBehavior());\n };\n\n // Keyboard: one tab stop, moved by the keys of the axis.\n const elementOf = (id: string) =>\n [...(viewport?.querySelectorAll<HTMLElement>(\"[data-entry-id]\") ?? [])].find((element) => element.dataset.entryId === id);\n const focusEntry = (id: string | undefined, message?: string) => {\n if (id === undefined) return;\n setActive(id);\n const element = elementOf(id);\n element?.focus({ preventScroll: true });\n element?.scrollIntoView?.({ block: \"nearest\", inline: \"nearest\", behavior: ownScrollBehavior() });\n if (message) announce(message);\n };\n const groupLabel = (group: TimelineGroup) => dayRange(group.firstKey, group.lastKey, longDayFormat());\n const onKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement | null;\n if (!target || target.closest(\"[role='menu']\") || event.altKey || event.ctrlKey || event.metaKey) return;\n const id = target.closest<HTMLElement>(\"[data-entry-id]\")?.dataset.entryId;\n const { order, entries, groups } = model();\n const index = id === undefined ? -1 : order.indexOf(id);\n const entry = id === undefined ? undefined : entries.get(id);\n const [back, forward] = layout().axis === \"horizontal\" ? [\"ArrowLeft\", \"ArrowRight\"] : [\"ArrowUp\", \"ArrowDown\"];\n const key = event.key;\n const handled = () => {\n event.preventDefault();\n event.stopPropagation();\n };\n if (key.toLowerCase() === \"t\") {\n handled();\n const happening = current();\n if (happening) focusEntry(happening);\n else scrollToTime(now(), \"center\");\n announce(timelineMessages().timelineNow({ time: formatTime(now()) }));\n return;\n }\n if (!entry) return;\n const group = groups[entry.group]!;\n if (key === back || key === forward) {\n handled();\n focusEntry(order[Math.max(0, Math.min(order.length - 1, index + (key === forward ? 1 : -1)))]);\n } else if (key === \"PageDown\" || key === \"PageUp\") {\n handled();\n const step = key === \"PageDown\" ? 1 : -1;\n for (let next = entry.group + step; next >= 0 && next < groups.length; next += step) {\n const first = groups[next]!.entries[0];\n if (first) return focusEntry(first.id, groupLabel(groups[next]!));\n }\n } else if (key === \"Home\" || key === \"End\") {\n handled();\n focusEntry((key === \"Home\" ? group.entries[0] : group.entries.at(-1))?.id);\n } else if (key === \" \" && entry.kind !== \"more\") {\n handled();\n if (props.onToggle && entry.item.checked !== undefined) props.onToggle(entry.item, !entry.item.checked);\n else if (props.onActivate) props.onActivate(entry.item);\n else if (entry.item.href) target.click();\n }\n };\n\n // The wheel scrolls a horizontal strip sideways only where nothing else scrolls vertically, decided once per gesture.\n let wheelAt = Number.NEGATIVE_INFINITY;\n let primary = false;\n /** Pixels a gliding wheel still moves. Relative, so a scroll from elsewhere, such as days loading, adds to it. */\n let wheelLeft = 0;\n let wheelFrame = 0;\n const glide = () => {\n wheelFrame = 0;\n if (!viewport) return;\n // Whole pixels, so every frame moves until the glide is done or meets an edge.\n const step = Math.abs(wheelLeft) <= 1 ? wheelLeft : Math.trunc(wheelLeft * 0.35) || Math.sign(wheelLeft);\n const before = viewport.scrollLeft;\n viewport.scrollLeft = before + step;\n wheelLeft -= step;\n if (wheelLeft !== 0 && viewport.scrollLeft !== before) wheelFrame = requestAnimationFrame(glide);\n else wheelLeft = 0;\n };\n const onWheel = (event: WheelEvent) => {\n if (!viewport || layout().axis !== \"horizontal\" || event.ctrlKey || event.shiftKey) return;\n if (Math.abs(event.deltaY) <= Math.abs(event.deltaX)) return;\n const time = performance.now();\n if (time - wheelAt > GESTURE_GAP_MS) primary = !verticalScroller(viewport);\n wheelAt = time;\n if (!primary) return;\n event.preventDefault();\n const delta = event.deltaY * (event.deltaMode === 1 ? 40 : event.deltaMode === 2 ? viewport.clientWidth : 1);\n if (reducedMotion() || (Math.abs(delta) < GLIDE_FROM && !wheelFrame)) {\n viewport.scrollLeft += delta;\n return;\n }\n wheelLeft += delta;\n if (!wheelFrame) wheelFrame = requestAnimationFrame(glide);\n };\n\n const activate = (event: MouseEvent, entry: TimelineItemEntry) => {\n const onBox = (event.target as Element | null)?.closest(\".k2b-timeline__check\");\n if (onBox && props.onToggle && entry.item.checked !== undefined) {\n event.preventDefault();\n props.onToggle(entry.item, !entry.item.checked);\n return;\n }\n // A modified click on a link keeps its browser meaning, such as opening a new tab.\n if (!props.onActivate || (entry.item.href && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey))) return;\n event.preventDefault();\n props.onActivate(entry.item);\n };\n\n // While the reader scrolls, a scroll write that keeps the view in place would fight a finger or momentum, as on iOS.\n // So a new model that moves what they see waits until the scroll rests: frames without a scroll event, no finger\n // down. Counted in frames, as scrolling and momentum report every frame, also when a busy page draws slowly.\n const [resting, setResting] = createSignal(true);\n const fingers = new Set<number>();\n let quietFrames = 0;\n let restFrame = 0;\n const countQuiet = () => {\n restFrame = 0;\n if (fingers.size > 0) return;\n if (++quietFrames >= REST_FRAMES) setResting(true);\n else restFrame = requestAnimationFrame(countQuiet);\n };\n const scrolled = () => {\n setResting(false);\n quietFrames = 0;\n if (!restFrame) restFrame = requestAnimationFrame(countQuiet);\n };\n /**\n * How a scroll the timeline starts itself moves. A smooth one reports its first frame only later, and a write that\n * keeps the view in place stops it, so it counts as scrolling from its start: days that load meanwhile wait until it\n * arrives instead of cutting it short.\n */\n const ownScrollBehavior = (): ScrollBehavior => {\n if (reducedMotion()) return \"auto\";\n scrolled();\n return \"smooth\";\n };\n const onTouchStart = (event: TouchEvent) => {\n const target = event.target;\n if (!target) return;\n const touches = [...event.changedTouches].map((touch) => touch.identifier);\n for (const touch of touches) fingers.add(touch);\n setResting(false);\n // Touch events keep going to where they began, also after that element left the timeline.\n const release = (ended: Event) => {\n for (const touch of (ended as TouchEvent).changedTouches) fingers.delete(touch.identifier);\n if (touches.some((touch) => fingers.has(touch))) return;\n target.removeEventListener(\"touchend\", release);\n target.removeEventListener(\"touchcancel\", release);\n scrolled();\n };\n target.addEventListener(\"touchend\", release);\n target.addEventListener(\"touchcancel\", release);\n };\n /** The item that had focus when the model changed, to keep focus in the timeline if its element goes. */\n let focused: string | undefined;\n createEffect(() => {\n const next = latest();\n const rest = resting();\n untrack(() => {\n const shown = model();\n if (next === shown || (!rest && viewport && Math.abs(shiftOf(shown, next)) >= 0.5)) return;\n focused = root?.contains(document.activeElement) && !document.activeElement?.closest(\"[role='menu']\") ? activeId() : undefined;\n setModel(next);\n });\n });\n /** The entry that stands in for `id` in the next model: itself, the \"+n\" entry that hides it, or its nearest neighbour. */\n const successor = (before: TimelineModel, after: TimelineModel, id: string): string | undefined => {\n if (after.entries.has(id)) return id;\n for (const entry of after.entries.values())\n if (entry.kind === \"more\" && entry.hidden.some((hidden) => hidden.id === id)) return entry.id;\n const index = before.order.indexOf(id);\n return [...before.order.slice(index + 1), ...before.order.slice(0, Math.max(0, index)).reverse()].find((other) =>\n after.entries.has(other),\n );\n };\n // Days loading at either end, and items changing, keep what the reader sees in place, and keep focus.\n createEffect(\n on(model, (current, previous) => {\n if (!previous) return;\n scrollBy(shiftOf(previous, current));\n const id = focused === undefined ? undefined : successor(previous, current, focused);\n focused = undefined;\n if (id !== undefined && !root?.contains(document.activeElement)) {\n setActive(id);\n // A day that only now holds the tab stop renders right after this update.\n const focus = () => elementOf(id)?.focus({ preventScroll: true });\n if (!elementOf(id)) queueMicrotask(focus);\n else focus();\n }\n refresh();\n }),\n );\n\n onMount(() => {\n if (isServer || !viewport || !root) return;\n setLayout(readLayout());\n refresh();\n let frame = 0;\n const schedule = () => {\n if (frame) return;\n frame = requestAnimationFrame(() => {\n frame = 0;\n refresh();\n });\n };\n // Scrolls of the strip and of the areas around it, which move it too.\n const onScroll = (event: Event) => {\n const target = event.target;\n if (target !== document && !(target instanceof Node && viewport && target.contains(viewport))) return;\n scrolled();\n schedule();\n };\n const resize = new ResizeObserver(() => {\n const next = readLayout();\n const previous = layout();\n if (next.axis !== previous.axis || next.units.some((value, index) => value !== previous.units[index])) {\n setLayout(next);\n if (edgeTime !== undefined) scrollBy(px(edgeTime) - visible()[0]);\n refresh();\n } else schedule();\n });\n resize.observe(viewport);\n viewport.addEventListener(\"wheel\", onWheel, { passive: false });\n viewport.addEventListener(\"touchstart\", onTouchStart, { passive: true });\n root.addEventListener(\"keydown\", onKeyDown, true);\n window.addEventListener(\"scroll\", onScroll, { passive: true, capture: true });\n const timer = props.now === undefined ? setInterval(() => setClock(Date.now()), 30_000) : undefined;\n onCleanup(() => {\n resize.disconnect();\n viewport?.removeEventListener(\"wheel\", onWheel);\n viewport?.removeEventListener(\"touchstart\", onTouchStart);\n root?.removeEventListener(\"keydown\", onKeyDown, true);\n window.removeEventListener(\"scroll\", onScroll, { capture: true });\n cancelAnimationFrame(frame);\n cancelAnimationFrame(wheelFrame);\n cancelAnimationFrame(restFrame);\n if (timer) clearInterval(timer);\n });\n props.controller?.({\n scrollToTime: (time, options) => scrollToTime(parseTimelineTime(time, context()), options?.align),\n scrollToNow: () => scrollToTime(now(), \"center\"),\n });\n });\n\n const nowShown = () => now() >= model().from && now() < model().to;\n\n const Heading = (headingProps: { group: TimelineGroup }) => (\n <Dynamic\n component={`h${props.headingLevel ?? 3}`}\n id={`${baseId}-${headingProps.group.key.replace(/[^a-zA-Z0-9_-]/g, \"-\")}`}\n class=\"k2b-timeline__heading\"\n >\n <Show when={headingProps.group.today}>\n <span class=\"k2b-timeline__today\">{messages().today}</span>\n </Show>\n <span class=\"k2b-timeline__day\">{dayRange(headingProps.group.firstKey, headingProps.group.lastKey, dayFormat())}</span>\n </Dynamic>\n );\n\n const ItemControl = (itemProps: { entry: TimelineItemEntry }) => {\n const entry = () => itemProps.entry;\n const name = createMemo(() => spoken(entry()));\n const time = () => {\n const current = entry();\n if (current.kind === \"all-day\") return \"\";\n if (current.kind !== \"folded\" && current.end > current.start) return `${formatTime(current.start)}–${formatTime(current.end)}`;\n return formatTime(current.start);\n };\n return (\n <Dynamic\n component={entry().item.href ? \"a\" : \"button\"}\n type={entry().item.href ? undefined : \"button\"}\n href={entry().item.href}\n class=\"k2b-timeline__item\"\n data-entry-id={entry().id}\n tabindex={activeId() === entry().id ? 0 : -1}\n aria-label={name()}\n title={name()}\n onClick={(event: MouseEvent) => activate(event, entry())}\n >\n <Show when={entry().item.checked !== undefined}>\n <span class=\"k2b-timeline__check\" data-checked={entry().item.checked ? \"true\" : undefined} aria-hidden=\"true\">\n <i class=\"ti ti-check\" />\n </span>\n </Show>\n <span class=\"k2b-timeline__text\">\n <span class=\"k2b-timeline__label\">{entry().item.label}</span>\n <Show when={time()}>\n <span class=\"k2b-timeline__time\">{time()}</span>\n </Show>\n <Show when={entry().item.detail}>\n <span class=\"k2b-timeline__detail\">{entry().item.detail}</span>\n </Show>\n </span>\n </Dynamic>\n );\n };\n\n const MoreControl = (moreProps: { entry: TimelineMoreEntry }) => {\n const entry = () => moreProps.entry;\n const label = () => {\n const current = entry();\n const count = timelineMessages().timelineMore({ count: current.hidden.length });\n return current.area === \"all-day\"\n ? count\n : `${count}, ${timelineMessages().timelineTimeRange({ start: formatTime(current.start), end: formatTime(current.end) })}`;\n };\n // A row opens its item as a click on it does. Where only the checkbox may change, the row is that checkbox.\n const items = (): DropdownItem[] =>\n entry().hidden.map((hidden): DropdownItem => {\n const { item } = hidden;\n const parts = [when(hidden), ...(item.detail ? [item.detail] : [])];\n const state = item.checked === undefined ? [] : [item.checked ? timelineMessages().timelineDone : timelineMessages().timelineOpen];\n const icon = item.checked === undefined ? undefined : item.checked ? \"ti ti-circle-check\" : \"ti ti-circle\";\n const base = { label: item.label, description: [...parts, ...state].join(\", \"), icon };\n const open = props.onActivate;\n if (open) return item.href ? { ...base, href: item.href, action: () => open(item) } : { ...base, action: () => open(item) };\n if (item.href) return { ...base, href: item.href };\n const toggle = props.onToggle;\n if (toggle && item.checked !== undefined) {\n const checked = item.checked;\n return { label: item.label, description: parts.join(\", \"), choice: \"checkbox\", checked, action: () => toggle(item, !checked) };\n }\n return { ...base, disabled: true };\n });\n return (\n <Dropdown.Root items={items()} label={label()} class=\"k2b-timeline__more-root\">\n <Dropdown.Trigger\n appearance=\"plain\"\n class=\"k2b-timeline__item k2b-timeline__more\"\n data-entry-id={entry().id}\n tabIndex={activeId() === entry().id ? 0 : -1}\n label={label()}\n title={label()}\n >\n +{entry().hidden.length}\n </Dropdown.Trigger>\n </Dropdown.Root>\n );\n };\n\n const Slot = (slotProps: { id: string }) => {\n const entry = createMemo<TimelineEntry>(\n (previous) => model().entries.get(slotProps.id) ?? previous,\n model().entries.get(slotProps.id)!,\n );\n const color = () => {\n const current = entry();\n return colorAttributes(current.kind === \"more\" ? undefined : current.item.color);\n };\n const span = () => {\n const current = entry();\n if (current.kind !== \"band\") return undefined;\n const minutes = (current.end - current.start) / 60_000;\n return minutes < 30 ? \"xs\" : minutes < 60 ? \"s\" : minutes < 120 ? \"m\" : \"l\";\n };\n return (\n <li\n class=\"k2b-timeline__slot\"\n data-kind={entry().kind}\n data-area={asMore(entry())?.area}\n data-past={isPast(entry()) ? \"true\" : undefined}\n data-span={span()}\n data-color={color().token}\n style={{\n \"--k2b-timeline-at\": spanCss(entry().at),\n \"--k2b-timeline-size\": spanCss(entry().size),\n \"--k2b-timeline-lane\": String(entry().lane),\n \"--k2b-timeline-lanes\": String(entry().lanes),\n \"--k2b-timeline-accent\": color().accent,\n }}\n >\n <Show when={asMore(entry())} fallback={<ItemControl entry={asItem(entry())!} />}>\n {(more) => <MoreControl entry={more()} />}\n </Show>\n </li>\n );\n };\n\n const Group = (groupProps: { key: string }) => {\n const group = createMemo<TimelineGroup>(\n (previous) => groupsByKey().get(groupProps.key) ?? previous,\n groupsByKey().get(groupProps.key)!,\n );\n const headingId = () => `${baseId}-${group().key.replace(/[^a-zA-Z0-9_-]/g, \"-\")}`;\n return (\n <div\n class=\"k2b-timeline__group\"\n data-kind={group().kind}\n data-today={group().today ? \"true\" : undefined}\n data-past={group().past ? \"true\" : undefined}\n data-row={group().row ? \"true\" : undefined}\n style={{ \"--k2b-timeline-at\": spanCss(group().at), \"--k2b-timeline-size\": spanCss(group().size) }}\n >\n <Heading group={group()} />\n <div class=\"k2b-timeline__decor\" aria-hidden=\"true\">\n <Index each={group().folds}>\n {(fold) => (\n <div\n class=\"k2b-timeline__fold\"\n data-kind={fold().kind}\n style={{ \"--k2b-timeline-at\": spanCss(fold().at), \"--k2b-timeline-size\": spanCss(fold().size) }}\n >\n <i class=\"ti ti-moon\" />\n <span class=\"k2b-timeline__fold-label\">\n {fold().kind === \"night\" ? nightLabel() : timelineMessages().timelineNothingPlanned}\n </span>\n </div>\n )}\n </Index>\n <Index each={group().hours}>\n {(hour) => (\n <span class=\"k2b-timeline__hour\" style={{ \"--k2b-timeline-at\": spanCss(hour().at) }}>\n <span class=\"k2b-timeline__hour-label\">{formatTime(hour().time)}</span>\n </span>\n )}\n </Index>\n <Index each={group().gaps}>\n {(gap) => (\n <span\n class=\"k2b-timeline__gap\"\n data-long={gap().long ? \"true\" : undefined}\n data-past={gap().end <= now() ? \"true\" : undefined}\n style={{ \"--k2b-timeline-at\": spanCss(gap().at) }}\n >\n {timelineMessages().timelineFree({ duration: hoursFormat().format(gap().hours) })}\n </span>\n )}\n </Index>\n <Index each={group().echoes}>\n {(echo) => {\n const color = () => {\n const current = echo();\n return colorAttributes(current.kind === \"more\" ? undefined : current.item.color);\n };\n return (\n // A pointer shortcut to an item that the keyboard and screen readers reach on the day it starts.\n // biome-ignore lint/a11y/noStaticElementInteractions: hidden from assistive technology on purpose.\n // biome-ignore lint/a11y/useKeyWithClickEvents: the item itself is the keyboard target.\n <span\n class=\"k2b-timeline__echo\"\n data-color={color().token}\n data-past={isPast(echo()) ? \"true\" : undefined}\n style={{ \"--k2b-timeline-lane\": String(echo().lane), \"--k2b-timeline-accent\": color().accent }}\n onClick={() => elementOf(echo().id)?.click()}\n >\n {asItem(echo())?.item.label ?? `+${asMore(echo())?.hidden.length ?? 0}`}\n </span>\n );\n }}\n </Index>\n </div>\n <Show when={group().entries.length > 0}>\n <ol class=\"k2b-timeline__list\" aria-labelledby={headingId()}>\n <For each={group().entries.map((entry) => entry.id)}>{(id) => <Slot id={id} />}</For>\n </ol>\n </Show>\n </div>\n );\n };\n\n return (\n <section\n ref={root}\n class={`k2b-timeline ${props.class ?? \"\"}`}\n aria-label={props.label ?? timelineMessages().timeline}\n aria-describedby={`${baseId}-hint`}\n aria-busy={props.busy ? \"true\" : undefined}\n onFocusIn={(event) => {\n const id = (event.target as HTMLElement).closest<HTMLElement>(\"[data-entry-id]\")?.dataset.entryId;\n if (id !== undefined) setActive(id);\n }}\n >\n <div ref={viewport} class=\"k2b-timeline__viewport\" tabIndex={model().order.length === 0 ? 0 : undefined}>\n <div ref={track} class=\"k2b-timeline__track\" style={{ \"--k2b-timeline-length\": spanCss(model().total) }}>\n <For each={renderedKeys()}>{(key) => <Group key={key} />}</For>\n <div\n class=\"k2b-timeline__now\"\n aria-hidden=\"true\"\n data-hidden={nowShown() ? undefined : \"true\"}\n style={{ \"--k2b-timeline-at\": spanCss(model().posOf(now())) }}\n >\n <span class=\"k2b-timeline__now-time\">{formatTime(now())}</span>\n </div>\n </div>\n </div>\n <span id={`${baseId}-hint`} class=\"k2b-sr-only\">\n {timelineMessages().timelineHint}\n </span>\n </section>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["content/Timeline.tsx"],"sourcesContent":["import type { DateContext } from \"@k2b/stdlib\";\nimport {\n createEffect,\n createMemo,\n createSignal,\n createUniqueId,\n For,\n Index,\n type JSX,\n on,\n onCleanup,\n onMount,\n Show,\n untrack,\n} from \"solid-js\";\nimport { Dynamic, isServer } from \"solid-js/web\";\nimport Dropdown, { type DropdownItem } from \"../actions/Dropdown\";\nimport { announce } from \"../feedback/announce\";\nimport { useDateConfigLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { prefersReducedMotion } from \"../motion\";\nimport { useTimelineMessages } from \"./timeline-messages\";\nimport {\n buildTimelineModel,\n parseTimelineTime,\n spanCss,\n spanPx,\n type TimelineEntry,\n type TimelineGroup,\n type TimelineItem,\n type TimelineItemEntry,\n type TimelineModel,\n type TimelineMoreEntry,\n type TimelineUnits,\n timelineDayKey,\n timelineHourOf,\n} from \"./timeline-model\";\n\nexport type { TimelineColor, TimelineItem } from \"./timeline-model\";\n\nexport type TimelineController = {\n /** Scrolls a time into view; `start` (default) puts it near the start edge, `center` in the middle. */\n scrollToTime: (time: Date | string, options?: { align?: \"start\" | \"center\" }) => void;\n /** Scrolls the current time to the middle of the view. */\n scrollToNow: () => void;\n};\n\nexport type TimelineProps = {\n items: readonly TimelineItem[];\n /** Start of the loaded range. The view starts here, so pass the first time the reader should see. */\n from: Date | string;\n /** End of the loaded range (exclusive). */\n to: Date | string;\n /** The current time. Without it the timeline uses the clock and moves the now line every 30 seconds. */\n now?: Date | string;\n /** Accessible name of the region. Defaults to \"Timeline\". */\n label?: string;\n /** stdlib date context: time zone and locale of days, hours, and folds. */\n dateConfig?: DateContext;\n /** Convenience override for `dateConfig.timeZone`. */\n timeZone?: string;\n /** Level of the per-day headings. Defaults to 3. */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n /** Opens an item, on click, Enter, or Space. */\n onActivate?: (item: TimelineItem) => void;\n /** Changes the checkbox of an item, on a click on the box or Space. Leave it out when the reader may not change it. */\n onToggle?: (item: TimelineItem, checked: boolean) => void;\n /**\n * Called once when the reader nears the start, again once `from` moved and changed the strip's length. Extend `from`\n * to load earlier days.\n */\n onLoadEarlier?: () => unknown;\n /** Called once when the reader nears the end, again once `to` moved and changed the strip's length. Extend `to` to load later days. */\n onLoadLater?: () => unknown;\n /** Marks the region busy, for example while a range loads. */\n busy?: boolean;\n controller?: (controller: TimelineController) => void;\n class?: string;\n};\n\ntype Axis = \"horizontal\" | \"vertical\";\n\n/** Unit sizes of the horizontal axis, as in the stylesheet; the server and the first render use them. */\nconst HORIZONTAL_UNITS: TimelineUnits = [54, 48, 160, 0, 0];\n/** How far beyond the visible area the first render reaches, in pixels. */\nconst INITIAL_REACH = 3200;\n/** A scroll rests once this many frames passed without a scroll event and no finger is down. */\nconst REST_FRAMES = 8;\n/** A pause between wheel events that starts a new gesture. */\nconst GESTURE_GAP_MS = 150;\n/** Wheel steps from this size on, such as a mouse wheel's notches, glide; smaller ones, such as a trackpad's, apply at once. */\nconst GLIDE_FROM = 50;\nconst COLOR_TOKENS = new Set([\"blue\", \"emerald\", \"amber\", \"red\", \"violet\", \"cyan\", \"zinc\"]);\nconst HEX_COLOR = /^#[0-9a-f]{3,8}$/i;\n\nconst colorAttributes = (color: string | undefined) =>\n color && HEX_COLOR.test(color)\n ? { token: undefined, accent: color }\n : { token: color && COLOR_TOKENS.has(color) ? color : \"blue\", accent: undefined };\n\nconst isAllDay = (entry: TimelineEntry) => entry.kind === \"all-day\" || (entry.kind === \"more\" && entry.area === \"all-day\");\nconst asItem = (entry: TimelineEntry): TimelineItemEntry | undefined => (entry.kind === \"more\" ? undefined : entry);\nconst asMore = (entry: TimelineEntry): TimelineMoreEntry | undefined => (entry.kind === \"more\" ? entry : undefined);\n\n/** The nearest ancestor that scrolls vertically, the page included. */\nconst verticalScroller = (from: Element): Element | undefined => {\n for (let element = from.parentElement; element; element = element.parentElement) {\n if (element.scrollHeight <= element.clientHeight + 1) continue;\n const overflow = getComputedStyle(element).overflowY;\n if (overflow === \"auto\" || overflow === \"scroll\" || element === document.scrollingElement) return element;\n }\n const root = document.scrollingElement;\n return root && root.scrollHeight > root.clientHeight + 1 ? root : undefined;\n};\n\n/**\n * A continuous filmstrip of time: waking hours are proportional, nights and empty days fold, overlapping bands share\n * lanes. Wide containers show it horizontally, narrow ones vertically; both use the same model.\n */\nexport default function Timeline(props: TimelineProps): JSX.Element {\n const messages = useUiMessages();\n const timelineMessages = useTimelineMessages();\n const context = useDateConfigLocale(() => ({ ...props.dateConfig, timeZone: props.timeZone ?? props.dateConfig?.timeZone }));\n const baseId = createUniqueId().replace(/[^a-zA-Z0-9_-]/g, \"-\");\n const [clock, setClock] = createSignal(Date.now());\n const now = createMemo(() => {\n const fixed = parseTimelineTime(props.now, context());\n return Number.isFinite(fixed) ? fixed : clock();\n });\n const today = createMemo(() => timelineDayKey(now(), context()));\n const latest = createMemo<TimelineModel>(() =>\n buildTimelineModel({\n from: parseTimelineTime(props.from, context()),\n to: parseTimelineTime(props.to, context()),\n today: today(),\n items: props.items,\n context: context(),\n }),\n );\n /** The model on screen: the latest one, unless that one waits for the reader's scroll to rest (see `resting`). */\n const [model, setModel] = createSignal<TimelineModel>(untrack(latest));\n const groupsByKey = createMemo(() => new Map(model().groups.map((group) => [group.key, group])));\n\n // Formatting.\n const locale = () => context().locale ?? \"en\";\n const timeFormat = createMemo(\n () => new Intl.DateTimeFormat(locale(), { hour: \"2-digit\", minute: \"2-digit\", hourCycle: \"h23\", timeZone: context().timeZone }),\n );\n const formatTime = (time: number) => timeFormat().format(time);\n const dayFormat = createMemo(\n () => new Intl.DateTimeFormat(locale(), { weekday: \"short\", day: \"numeric\", month: \"short\", timeZone: context().timeZone }),\n );\n const longDayFormat = createMemo(\n () => new Intl.DateTimeFormat(locale(), { weekday: \"long\", day: \"numeric\", month: \"long\", timeZone: context().timeZone }),\n );\n const hoursFormat = createMemo(\n () => new Intl.NumberFormat(locale(), { style: \"unit\", unit: \"hour\", unitDisplay: \"short\", maximumFractionDigits: 1 }),\n );\n const noonOf = (key: string) => new Date(timelineHourOf(key, 12, context()));\n const dayRange = (first: string, last: string, format: Intl.DateTimeFormat) =>\n first === last ? format.format(noonOf(first)) : `${format.format(noonOf(first))} – ${format.format(noonOf(last))}`;\n const nightLabel = createMemo(() => {\n const format = new Intl.DateTimeFormat(locale(), { hour: \"2-digit\", minute: \"2-digit\", hourCycle: \"h23\", timeZone: \"UTC\" });\n return timelineMessages().timelineNight({\n start: format.format(Date.UTC(2000, 0, 1, 22)),\n end: format.format(Date.UTC(2000, 0, 1, 6)),\n });\n });\n const spoken = (entry: TimelineItemEntry): string => {\n const item = entry.item;\n const parts = [item.label];\n if (entry.kind === \"all-day\") parts.push(messages().allDay);\n else if (entry.end > entry.start)\n parts.push(timelineMessages().timelineTimeRange({ start: formatTime(entry.start), end: formatTime(entry.end) }));\n else parts.push(formatTime(entry.start));\n if (item.detail) parts.push(item.detail);\n parts.push(\n entry.kind === \"all-day\" ? dayRange(entry.firstKey, entry.lastKey, longDayFormat()) : longDayFormat().format(new Date(entry.start)),\n );\n if (item.checked !== undefined) parts.push(item.checked ? timelineMessages().timelineDone : timelineMessages().timelineOpen);\n return parts.join(\", \");\n };\n /** When an item happens, for a \"+n\" menu row. */\n const when = (entry: TimelineItemEntry): string => {\n if (entry.kind === \"all-day\") return `${messages().allDay}, ${dayRange(entry.firstKey, entry.lastKey, dayFormat())}`;\n return entry.end > entry.start ? `${formatTime(entry.start)}–${formatTime(entry.end)}` : formatTime(entry.start);\n };\n const isPast = (entry: TimelineEntry): boolean => {\n if (entry.kind === \"more\") return entry.hidden.every(isPast);\n if (entry.kind === \"all-day\") return entry.lastKey < today();\n return entry.end <= now();\n };\n\n // Layout of the axis the stylesheet chose, read from the viewport.\n let root: HTMLElement | undefined;\n let viewport: HTMLDivElement | undefined;\n let track: HTMLDivElement | undefined;\n const [layout, setLayout] = createSignal<{ axis: Axis; units: TimelineUnits }>({ axis: \"horizontal\", units: HORIZONTAL_UNITS });\n const readLayout = () => {\n if (!viewport) return layout();\n const style = getComputedStyle(viewport);\n const unit = (name: string) => Number.parseFloat(style.getPropertyValue(`--k2b-timeline-${name}`)) || 0;\n const units: TimelineUnits = [unit(\"hour\"), unit(\"night\"), unit(\"fold\"), unit(\"head\"), unit(\"row\")];\n return {\n axis: style.getPropertyValue(\"--k2b-timeline-axis\").trim() === \"vertical\" ? (\"vertical\" as const) : (\"horizontal\" as const),\n units: units.some((value) => value > 0) ? units : HORIZONTAL_UNITS,\n };\n };\n const px = (time: number) => spanPx(model().posOf(time), layout().units);\n\n /** The visible part of the track in its own pixels, clipped by the viewport and the window. */\n const visible = (): [number, number] => {\n if (!viewport || !track) return [0, INITIAL_REACH];\n const port = viewport.getBoundingClientRect();\n const box = track.getBoundingClientRect();\n const [portStart, portEnd, boxStart, limit] =\n layout().axis === \"horizontal\"\n ? [port.left, port.right, box.left, window.innerWidth]\n : [port.top, port.bottom, box.top, window.innerHeight];\n const start = Math.max(portStart, 0) - boxStart;\n return [start, Math.max(start, Math.min(portEnd, limit) - boxStart)];\n };\n const scrollBy = (distance: number, behavior: ScrollBehavior = \"instant\") => {\n // In device pixels: positions are sums of unit sizes, and an engine that cuts 4671.9999 to 4671 would move the view.\n const delta = Math.round(distance * window.devicePixelRatio) / window.devicePixelRatio;\n if (!viewport || Math.abs(delta) < 0.5) return;\n const horizontal = layout().axis === \"horizontal\";\n const scrollable = horizontal ? viewport.scrollWidth > viewport.clientWidth : viewport.scrollHeight > viewport.clientHeight;\n if (scrollable) viewport.scrollBy({ [horizontal ? \"left\" : \"top\"]: delta, behavior });\n else if (!horizontal) verticalScroller(viewport)?.scrollBy({ top: delta, behavior });\n };\n\n // Bounded rendering: groups whose reach meets the visible time range, widened by a screen, plus the focused group.\n const [range, setRange] = createSignal<[number, number]>();\n const shownRange = (): [number, number] => range() ?? [Number.NEGATIVE_INFINITY, model().timeAt(INITIAL_REACH, HORIZONTAL_UNITS)];\n const [active, setActive] = createSignal<string>();\n /** The item happening now or next. */\n const current = () => {\n const { order, entries } = model();\n return order.find((id) => {\n const entry = entries.get(id)!;\n return !isAllDay(entry) && entry.end >= now();\n });\n };\n const defaultActive = createMemo(() => current() ?? model().order.at(-1));\n const activeId = () => {\n const id = active();\n return id !== undefined && model().entries.has(id) ? id : defaultActive();\n };\n const renderedKeys = createMemo(() => {\n const [low, high] = shownRange();\n const focusGroup = model().entries.get(activeId() ?? \"\")?.group;\n return model()\n .groups.filter((group) => group.index === focusGroup || (group.reach[1] >= low && group.reach[0] <= high))\n .map((group) => group.key);\n });\n\n // Reading position: the time at the start edge stays in place when days load or the axis changes.\n /** The time at the start edge after the last refresh, for an axis change. */\n let edgeTime: number | undefined;\n /**\n * The time to hold in place. A load at the start spreads a leading night or fold over other times, so where the start\n * edge lies in one, the end of that segment holds instead, and with it everything after.\n */\n const anchorAt = (built: TimelineModel, start: number, units: TimelineUnits) => {\n const time = built.timeAt(start, units);\n const first = built.segments.find((segment) => segment.t1 > segment.t0);\n return first && first.kind !== \"wake\" && time < first.t1 ? first.t1 : time;\n };\n /** How far what the reader sees moves from one model to the next. */\n const shiftOf = (before: TimelineModel, after: TimelineModel) => {\n const { units } = layout();\n const time = anchorAt(before, visible()[0], units);\n return spanPx(after.posOf(time), units) - spanPx(before.posOf(time), units);\n };\n /**\n * Where each end of the range was, and how long the strip was, when that end was last asked for. An end is asked\n * again only once the range moved there and the strip's length changed: days that fold into the fold at that end\n * leave the reader where they were, and asking again would load an empty calendar week after week on its own.\n */\n let requestedFrom: { at: number; length: number } | undefined;\n let requestedTo: { at: number; length: number } | undefined;\n let pendingEarlier = false;\n let pendingLater = false;\n const loadEdge = (edge: \"earlier\" | \"later\") => {\n const load = edge === \"earlier\" ? props.onLoadEarlier : props.onLoadLater;\n if (!load) return;\n const settle = () => {\n if (edge === \"earlier\") pendingEarlier = false;\n else pendingLater = false;\n queueMicrotask(refresh);\n };\n if (edge === \"earlier\") pendingEarlier = true;\n else pendingLater = true;\n Promise.resolve().then(load).then(settle, settle);\n };\n const refresh = () => {\n if (!viewport) return;\n const built = model();\n const { units } = layout();\n const [start, end] = visible();\n const reach = Math.max(end - start, 600);\n edgeTime = built.timeAt(start, units);\n const [low, high] = range() ?? [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY];\n if (built.timeAt(start - reach / 2, units) < low || built.timeAt(end + reach / 2, units) > high)\n setRange([built.timeAt(start - reach, units), built.timeAt(end + reach, units)]);\n const length = spanPx(built.total, units);\n const due = (requested: { at: number; length: number } | undefined, at: number) =>\n requested === undefined || (requested.at !== at && requested.length !== length);\n if (start > reach) requestedFrom = undefined;\n else if (!pendingEarlier && due(requestedFrom, built.from)) {\n requestedFrom = { at: built.from, length };\n loadEdge(\"earlier\");\n }\n if (end < length - reach) requestedTo = undefined;\n else if (!pendingLater && due(requestedTo, built.to)) {\n requestedTo = { at: built.to, length };\n loadEdge(\"later\");\n }\n };\n\n const scrollToTime = (time: number, align: \"start\" | \"center\" = \"start\") => {\n if (!viewport) return;\n const [start, end] = visible();\n const target = px(time) - (align === \"center\" ? (end - start) / 2 : 16);\n scrollBy(target - start, ownScrollBehavior());\n };\n\n // Keyboard: one tab stop, moved by the keys of the axis.\n const elementOf = (id: string) =>\n [...(viewport?.querySelectorAll<HTMLElement>(\"[data-entry-id]\") ?? [])].find((element) => element.dataset.entryId === id);\n const focusEntry = (id: string | undefined, message?: string) => {\n if (id === undefined) return;\n setActive(id);\n const element = elementOf(id);\n element?.focus({ preventScroll: true });\n element?.scrollIntoView?.({ block: \"nearest\", inline: \"nearest\", behavior: ownScrollBehavior() });\n if (message) announce(message);\n };\n const groupLabel = (group: TimelineGroup) => dayRange(group.firstKey, group.lastKey, longDayFormat());\n const onKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement | null;\n if (!target || target.closest(\"[role='menu']\") || event.altKey || event.ctrlKey || event.metaKey) return;\n const id = target.closest<HTMLElement>(\"[data-entry-id]\")?.dataset.entryId;\n const { order, entries, groups } = model();\n const index = id === undefined ? -1 : order.indexOf(id);\n const entry = id === undefined ? undefined : entries.get(id);\n const [back, forward] = layout().axis === \"horizontal\" ? [\"ArrowLeft\", \"ArrowRight\"] : [\"ArrowUp\", \"ArrowDown\"];\n const key = event.key;\n const handled = () => {\n event.preventDefault();\n event.stopPropagation();\n };\n if (key.toLowerCase() === \"t\") {\n handled();\n const happening = current();\n if (happening) focusEntry(happening);\n else scrollToTime(now(), \"center\");\n announce(timelineMessages().timelineNow({ time: formatTime(now()) }));\n return;\n }\n if (!entry) return;\n const group = groups[entry.group]!;\n if (key === back || key === forward) {\n handled();\n focusEntry(order[Math.max(0, Math.min(order.length - 1, index + (key === forward ? 1 : -1)))]);\n } else if (key === \"PageDown\" || key === \"PageUp\") {\n handled();\n const step = key === \"PageDown\" ? 1 : -1;\n for (let next = entry.group + step; next >= 0 && next < groups.length; next += step) {\n const first = groups[next]!.entries[0];\n if (first) return focusEntry(first.id, groupLabel(groups[next]!));\n }\n } else if (key === \"Home\" || key === \"End\") {\n handled();\n focusEntry((key === \"Home\" ? group.entries[0] : group.entries.at(-1))?.id);\n } else if (key === \" \" && entry.kind !== \"more\") {\n handled();\n if (props.onToggle && entry.item.checked !== undefined) props.onToggle(entry.item, !entry.item.checked);\n else if (props.onActivate) props.onActivate(entry.item);\n else if (entry.item.href) target.click();\n }\n };\n\n // The wheel scrolls a horizontal strip sideways only where nothing else scrolls vertically, decided once per gesture.\n let wheelAt = Number.NEGATIVE_INFINITY;\n let primary = false;\n /** Pixels a gliding wheel still moves. Relative, so a scroll from elsewhere, such as days loading, adds to it. */\n let wheelLeft = 0;\n let wheelFrame = 0;\n const glide = () => {\n wheelFrame = 0;\n if (!viewport) return;\n // Whole pixels, so every frame moves until the glide is done or meets an edge.\n const step = Math.abs(wheelLeft) <= 1 ? wheelLeft : Math.trunc(wheelLeft * 0.35) || Math.sign(wheelLeft);\n const before = viewport.scrollLeft;\n viewport.scrollLeft = before + step;\n wheelLeft -= step;\n if (wheelLeft !== 0 && viewport.scrollLeft !== before) wheelFrame = requestAnimationFrame(glide);\n else wheelLeft = 0;\n };\n const onWheel = (event: WheelEvent) => {\n if (!viewport || layout().axis !== \"horizontal\" || event.ctrlKey || event.shiftKey) return;\n if (Math.abs(event.deltaY) <= Math.abs(event.deltaX)) return;\n const time = performance.now();\n if (time - wheelAt > GESTURE_GAP_MS) primary = !verticalScroller(viewport);\n wheelAt = time;\n if (!primary) return;\n event.preventDefault();\n const delta = event.deltaY * (event.deltaMode === 1 ? 40 : event.deltaMode === 2 ? viewport.clientWidth : 1);\n if (prefersReducedMotion() || (Math.abs(delta) < GLIDE_FROM && !wheelFrame)) {\n viewport.scrollLeft += delta;\n return;\n }\n wheelLeft += delta;\n if (!wheelFrame) wheelFrame = requestAnimationFrame(glide);\n };\n\n const activate = (event: MouseEvent, entry: TimelineItemEntry) => {\n const onBox = (event.target as Element | null)?.closest(\".k2b-timeline__check\");\n if (onBox && props.onToggle && entry.item.checked !== undefined) {\n event.preventDefault();\n props.onToggle(entry.item, !entry.item.checked);\n return;\n }\n // A modified click on a link keeps its browser meaning, such as opening a new tab.\n if (!props.onActivate || (entry.item.href && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey))) return;\n event.preventDefault();\n props.onActivate(entry.item);\n };\n\n // While the reader scrolls, a scroll write that keeps the view in place would fight a finger or momentum, as on iOS.\n // So a new model that moves what they see waits until the scroll rests: frames without a scroll event, no finger\n // down. Counted in frames, as scrolling and momentum report every frame, also when a busy page draws slowly.\n const [resting, setResting] = createSignal(true);\n const fingers = new Set<number>();\n let quietFrames = 0;\n let restFrame = 0;\n const countQuiet = () => {\n restFrame = 0;\n if (fingers.size > 0) return;\n if (++quietFrames >= REST_FRAMES) setResting(true);\n else restFrame = requestAnimationFrame(countQuiet);\n };\n const scrolled = () => {\n setResting(false);\n quietFrames = 0;\n if (!restFrame) restFrame = requestAnimationFrame(countQuiet);\n };\n /**\n * How a scroll the timeline starts itself moves. A smooth one reports its first frame only later, and a write that\n * keeps the view in place stops it, so it counts as scrolling from its start: days that load meanwhile wait until it\n * arrives instead of cutting it short.\n */\n const ownScrollBehavior = (): ScrollBehavior => {\n if (prefersReducedMotion()) return \"auto\";\n scrolled();\n return \"smooth\";\n };\n const onTouchStart = (event: TouchEvent) => {\n const target = event.target;\n if (!target) return;\n const touches = [...event.changedTouches].map((touch) => touch.identifier);\n for (const touch of touches) fingers.add(touch);\n setResting(false);\n // Touch events keep going to where they began, also after that element left the timeline.\n const release = (ended: Event) => {\n for (const touch of (ended as TouchEvent).changedTouches) fingers.delete(touch.identifier);\n if (touches.some((touch) => fingers.has(touch))) return;\n target.removeEventListener(\"touchend\", release);\n target.removeEventListener(\"touchcancel\", release);\n scrolled();\n };\n target.addEventListener(\"touchend\", release);\n target.addEventListener(\"touchcancel\", release);\n };\n /** The item that had focus when the model changed, to keep focus in the timeline if its element goes. */\n let focused: string | undefined;\n createEffect(() => {\n const next = latest();\n const rest = resting();\n untrack(() => {\n const shown = model();\n if (next === shown || (!rest && viewport && Math.abs(shiftOf(shown, next)) >= 0.5)) return;\n focused = root?.contains(document.activeElement) && !document.activeElement?.closest(\"[role='menu']\") ? activeId() : undefined;\n setModel(next);\n });\n });\n /** The entry that stands in for `id` in the next model: itself, the \"+n\" entry that hides it, or its nearest neighbour. */\n const successor = (before: TimelineModel, after: TimelineModel, id: string): string | undefined => {\n if (after.entries.has(id)) return id;\n for (const entry of after.entries.values())\n if (entry.kind === \"more\" && entry.hidden.some((hidden) => hidden.id === id)) return entry.id;\n const index = before.order.indexOf(id);\n return [...before.order.slice(index + 1), ...before.order.slice(0, Math.max(0, index)).reverse()].find((other) =>\n after.entries.has(other),\n );\n };\n // Days loading at either end, and items changing, keep what the reader sees in place, and keep focus.\n createEffect(\n on(model, (current, previous) => {\n if (!previous) return;\n scrollBy(shiftOf(previous, current));\n const id = focused === undefined ? undefined : successor(previous, current, focused);\n focused = undefined;\n if (id !== undefined && !root?.contains(document.activeElement)) {\n setActive(id);\n // A day that only now holds the tab stop renders right after this update.\n const focus = () => elementOf(id)?.focus({ preventScroll: true });\n if (!elementOf(id)) queueMicrotask(focus);\n else focus();\n }\n refresh();\n }),\n );\n\n onMount(() => {\n if (isServer || !viewport || !root) return;\n setLayout(readLayout());\n refresh();\n let frame = 0;\n const schedule = () => {\n if (frame) return;\n frame = requestAnimationFrame(() => {\n frame = 0;\n refresh();\n });\n };\n // Scrolls of the strip and of the areas around it, which move it too.\n const onScroll = (event: Event) => {\n const target = event.target;\n if (target !== document && !(target instanceof Node && viewport && target.contains(viewport))) return;\n scrolled();\n schedule();\n };\n const resize = new ResizeObserver(() => {\n const next = readLayout();\n const previous = layout();\n if (next.axis !== previous.axis || next.units.some((value, index) => value !== previous.units[index])) {\n setLayout(next);\n if (edgeTime !== undefined) scrollBy(px(edgeTime) - visible()[0]);\n refresh();\n } else schedule();\n });\n resize.observe(viewport);\n viewport.addEventListener(\"wheel\", onWheel, { passive: false });\n viewport.addEventListener(\"touchstart\", onTouchStart, { passive: true });\n root.addEventListener(\"keydown\", onKeyDown, true);\n window.addEventListener(\"scroll\", onScroll, { passive: true, capture: true });\n const timer = props.now === undefined ? setInterval(() => setClock(Date.now()), 30_000) : undefined;\n onCleanup(() => {\n resize.disconnect();\n viewport?.removeEventListener(\"wheel\", onWheel);\n viewport?.removeEventListener(\"touchstart\", onTouchStart);\n root?.removeEventListener(\"keydown\", onKeyDown, true);\n window.removeEventListener(\"scroll\", onScroll, { capture: true });\n cancelAnimationFrame(frame);\n cancelAnimationFrame(wheelFrame);\n cancelAnimationFrame(restFrame);\n if (timer) clearInterval(timer);\n });\n props.controller?.({\n scrollToTime: (time, options) => scrollToTime(parseTimelineTime(time, context()), options?.align),\n scrollToNow: () => scrollToTime(now(), \"center\"),\n });\n });\n\n const nowShown = () => now() >= model().from && now() < model().to;\n\n const Heading = (headingProps: { group: TimelineGroup }) => (\n <Dynamic\n component={`h${props.headingLevel ?? 3}`}\n id={`${baseId}-${headingProps.group.key.replace(/[^a-zA-Z0-9_-]/g, \"-\")}`}\n class=\"k2b-timeline__heading\"\n >\n <Show when={headingProps.group.today}>\n <span class=\"k2b-timeline__today\">{messages().today}</span>\n </Show>\n <span class=\"k2b-timeline__day\">{dayRange(headingProps.group.firstKey, headingProps.group.lastKey, dayFormat())}</span>\n </Dynamic>\n );\n\n const ItemControl = (itemProps: { entry: TimelineItemEntry }) => {\n const entry = () => itemProps.entry;\n const name = createMemo(() => spoken(entry()));\n const time = () => {\n const current = entry();\n if (current.kind === \"all-day\") return \"\";\n if (current.kind !== \"folded\" && current.end > current.start) return `${formatTime(current.start)}–${formatTime(current.end)}`;\n return formatTime(current.start);\n };\n return (\n <Dynamic\n component={entry().item.href ? \"a\" : \"button\"}\n type={entry().item.href ? undefined : \"button\"}\n href={entry().item.href}\n class=\"k2b-timeline__item\"\n data-entry-id={entry().id}\n tabindex={activeId() === entry().id ? 0 : -1}\n aria-label={name()}\n title={name()}\n onClick={(event: MouseEvent) => activate(event, entry())}\n >\n <Show when={entry().item.checked !== undefined}>\n <span class=\"k2b-timeline__check\" data-checked={entry().item.checked ? \"true\" : undefined} aria-hidden=\"true\">\n <i class=\"ti ti-check\" />\n </span>\n </Show>\n <span class=\"k2b-timeline__text\">\n <span class=\"k2b-timeline__label\">{entry().item.label}</span>\n <Show when={time()}>\n <span class=\"k2b-timeline__time\">{time()}</span>\n </Show>\n <Show when={entry().item.detail}>\n <span class=\"k2b-timeline__detail\">{entry().item.detail}</span>\n </Show>\n </span>\n </Dynamic>\n );\n };\n\n const MoreControl = (moreProps: { entry: TimelineMoreEntry }) => {\n const entry = () => moreProps.entry;\n const label = () => {\n const current = entry();\n const count = timelineMessages().timelineMore({ count: current.hidden.length });\n return current.area === \"all-day\"\n ? count\n : `${count}, ${timelineMessages().timelineTimeRange({ start: formatTime(current.start), end: formatTime(current.end) })}`;\n };\n // A row opens its item as a click on it does. Where only the checkbox may change, the row is that checkbox.\n const items = (): DropdownItem[] =>\n entry().hidden.map((hidden): DropdownItem => {\n const { item } = hidden;\n const parts = [when(hidden), ...(item.detail ? [item.detail] : [])];\n const state = item.checked === undefined ? [] : [item.checked ? timelineMessages().timelineDone : timelineMessages().timelineOpen];\n const icon = item.checked === undefined ? undefined : item.checked ? \"ti ti-circle-check\" : \"ti ti-circle\";\n const base = { label: item.label, description: [...parts, ...state].join(\", \"), icon };\n const open = props.onActivate;\n if (open) return item.href ? { ...base, href: item.href, action: () => open(item) } : { ...base, action: () => open(item) };\n if (item.href) return { ...base, href: item.href };\n const toggle = props.onToggle;\n if (toggle && item.checked !== undefined) {\n const checked = item.checked;\n return { label: item.label, description: parts.join(\", \"), choice: \"checkbox\", checked, action: () => toggle(item, !checked) };\n }\n return { ...base, disabled: true };\n });\n return (\n <Dropdown.Root items={items()} label={label()} class=\"k2b-timeline__more-root\">\n <Dropdown.Trigger\n appearance=\"plain\"\n class=\"k2b-timeline__item k2b-timeline__more\"\n data-entry-id={entry().id}\n tabIndex={activeId() === entry().id ? 0 : -1}\n label={label()}\n title={label()}\n >\n +{entry().hidden.length}\n </Dropdown.Trigger>\n </Dropdown.Root>\n );\n };\n\n const Slot = (slotProps: { id: string }) => {\n const entry = createMemo<TimelineEntry>(\n (previous) => model().entries.get(slotProps.id) ?? previous,\n model().entries.get(slotProps.id)!,\n );\n const color = () => {\n const current = entry();\n return colorAttributes(current.kind === \"more\" ? undefined : current.item.color);\n };\n const span = () => {\n const current = entry();\n if (current.kind !== \"band\") return undefined;\n const minutes = (current.end - current.start) / 60_000;\n return minutes < 30 ? \"xs\" : minutes < 60 ? \"s\" : minutes < 120 ? \"m\" : \"l\";\n };\n return (\n <li\n class=\"k2b-timeline__slot\"\n data-kind={entry().kind}\n data-area={asMore(entry())?.area}\n data-past={isPast(entry()) ? \"true\" : undefined}\n data-span={span()}\n data-color={color().token}\n style={{\n \"--k2b-timeline-at\": spanCss(entry().at),\n \"--k2b-timeline-size\": spanCss(entry().size),\n \"--k2b-timeline-lane\": String(entry().lane),\n \"--k2b-timeline-lanes\": String(entry().lanes),\n \"--k2b-timeline-accent\": color().accent,\n }}\n >\n <Show when={asMore(entry())} fallback={<ItemControl entry={asItem(entry())!} />}>\n {(more) => <MoreControl entry={more()} />}\n </Show>\n </li>\n );\n };\n\n const Group = (groupProps: { key: string }) => {\n const group = createMemo<TimelineGroup>(\n (previous) => groupsByKey().get(groupProps.key) ?? previous,\n groupsByKey().get(groupProps.key)!,\n );\n const headingId = () => `${baseId}-${group().key.replace(/[^a-zA-Z0-9_-]/g, \"-\")}`;\n return (\n <div\n class=\"k2b-timeline__group\"\n data-kind={group().kind}\n data-today={group().today ? \"true\" : undefined}\n data-past={group().past ? \"true\" : undefined}\n data-row={group().row ? \"true\" : undefined}\n style={{ \"--k2b-timeline-at\": spanCss(group().at), \"--k2b-timeline-size\": spanCss(group().size) }}\n >\n <Heading group={group()} />\n <div class=\"k2b-timeline__decor\" aria-hidden=\"true\">\n <Index each={group().folds}>\n {(fold) => (\n <div\n class=\"k2b-timeline__fold\"\n data-kind={fold().kind}\n style={{ \"--k2b-timeline-at\": spanCss(fold().at), \"--k2b-timeline-size\": spanCss(fold().size) }}\n >\n <i class=\"ti ti-moon\" />\n <span class=\"k2b-timeline__fold-label\">\n {fold().kind === \"night\" ? nightLabel() : timelineMessages().timelineNothingPlanned}\n </span>\n </div>\n )}\n </Index>\n <Index each={group().hours}>\n {(hour) => (\n <span class=\"k2b-timeline__hour\" style={{ \"--k2b-timeline-at\": spanCss(hour().at) }}>\n <span class=\"k2b-timeline__hour-label\">{formatTime(hour().time)}</span>\n </span>\n )}\n </Index>\n <Index each={group().gaps}>\n {(gap) => (\n <span\n class=\"k2b-timeline__gap\"\n data-long={gap().long ? \"true\" : undefined}\n data-past={gap().end <= now() ? \"true\" : undefined}\n style={{ \"--k2b-timeline-at\": spanCss(gap().at) }}\n >\n {timelineMessages().timelineFree({ duration: hoursFormat().format(gap().hours) })}\n </span>\n )}\n </Index>\n <Index each={group().echoes}>\n {(echo) => {\n const color = () => {\n const current = echo();\n return colorAttributes(current.kind === \"more\" ? undefined : current.item.color);\n };\n return (\n // A pointer shortcut to an item that the keyboard and screen readers reach on the day it starts.\n // biome-ignore lint/a11y/noStaticElementInteractions: hidden from assistive technology on purpose.\n // biome-ignore lint/a11y/useKeyWithClickEvents: the item itself is the keyboard target.\n <span\n class=\"k2b-timeline__echo\"\n data-color={color().token}\n data-past={isPast(echo()) ? \"true\" : undefined}\n style={{ \"--k2b-timeline-lane\": String(echo().lane), \"--k2b-timeline-accent\": color().accent }}\n onClick={() => elementOf(echo().id)?.click()}\n >\n {asItem(echo())?.item.label ?? `+${asMore(echo())?.hidden.length ?? 0}`}\n </span>\n );\n }}\n </Index>\n </div>\n <Show when={group().entries.length > 0}>\n <ol class=\"k2b-timeline__list\" aria-labelledby={headingId()}>\n <For each={group().entries.map((entry) => entry.id)}>{(id) => <Slot id={id} />}</For>\n </ol>\n </Show>\n </div>\n );\n };\n\n return (\n <section\n ref={root}\n class={`k2b-timeline ${props.class ?? \"\"}`}\n aria-label={props.label ?? timelineMessages().timeline}\n aria-describedby={`${baseId}-hint`}\n aria-busy={props.busy ? \"true\" : undefined}\n onFocusIn={(event) => {\n const id = (event.target as HTMLElement).closest<HTMLElement>(\"[data-entry-id]\")?.dataset.entryId;\n if (id !== undefined) setActive(id);\n }}\n >\n <div ref={viewport} class=\"k2b-timeline__viewport\" tabIndex={model().order.length === 0 ? 0 : undefined}>\n <div ref={track} class=\"k2b-timeline__track\" style={{ \"--k2b-timeline-length\": spanCss(model().total) }}>\n <For each={renderedKeys()}>{(key) => <Group key={key} />}</For>\n <div\n class=\"k2b-timeline__now\"\n aria-hidden=\"true\"\n data-hidden={nowShown() ? undefined : \"true\"}\n style={{ \"--k2b-timeline-at\": spanCss(model().posOf(now())) }}\n >\n <span class=\"k2b-timeline__now-time\">{formatTime(now())}</span>\n </div>\n </div>\n </div>\n <span id={`${baseId}-hint`} class=\"k2b-sr-only\">\n {timelineMessages().timelineHint}\n </span>\n </section>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -27,6 +27,8 @@ const WINDOW_STEP = 2_000_000;
|
|
|
27
27
|
const OVERSCAN = 600;
|
|
28
28
|
/** Distance from the end, in px, that still counts as being at the end. */
|
|
29
29
|
const END_TOLERANCE = 2;
|
|
30
|
+
/** Part of an item, in px, that may be cut off while it still counts as fully in view: rounding, not a hidden line. */
|
|
31
|
+
const VISIBLE_TOLERANCE = 1;
|
|
30
32
|
/**
|
|
31
33
|
* Rows mounted during one correction reach the ResizeObserver a frame late; measure up to this many passes at once.
|
|
32
34
|
* A last pass places the rows; the observer measures what that pass mounted.
|
|
@@ -216,6 +218,33 @@ export function VirtualFeed(props) {
|
|
|
216
218
|
if (Math.abs(lastTop - from) > 0.5) owedUntil = performance.now() + END_WAIT_MS;
|
|
217
219
|
return next;
|
|
218
220
|
};
|
|
221
|
+
let visibleKeys;
|
|
222
|
+
const reportVisible = () => {
|
|
223
|
+
if (!props.onVisibleChange) return;
|
|
224
|
+
const top = logicalTop();
|
|
225
|
+
const bottom = top + viewport.clientHeight;
|
|
226
|
+
let first = -1;
|
|
227
|
+
let last = -1;
|
|
228
|
+
if (bottom > top && hi > lo) for (let index = indexAt(top); index < hi && offsetOf(index) < bottom; index++) {
|
|
229
|
+
const from = offsetOf(index);
|
|
230
|
+
const to = offsetOf(index + 1);
|
|
231
|
+
// Rounded scroll positions may cut a fully shown item by a fraction of a pixel.
|
|
232
|
+
if (from > top - VISIBLE_TOLERANCE && to < bottom + VISIBLE_TOLERANCE || from <= top && to >= bottom) {
|
|
233
|
+
if (first < 0) first = index;
|
|
234
|
+
last = index;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const next = first < 0 ? null : {
|
|
238
|
+
first: keys[first],
|
|
239
|
+
last: keys[last]
|
|
240
|
+
};
|
|
241
|
+
if (visibleKeys !== undefined && next?.first === visibleKeys?.first && next?.last === visibleKeys?.last) return;
|
|
242
|
+
visibleKeys = next;
|
|
243
|
+
props.onVisibleChange(first < 0 ? null : {
|
|
244
|
+
first: list[first],
|
|
245
|
+
last: list[last]
|
|
246
|
+
});
|
|
247
|
+
};
|
|
219
248
|
const updateRange = () => {
|
|
220
249
|
const top = logicalTop();
|
|
221
250
|
const height = viewport.clientHeight;
|
|
@@ -231,6 +260,8 @@ export function VirtualFeed(props) {
|
|
|
231
260
|
}
|
|
232
261
|
renderRows(indices);
|
|
233
262
|
setTabStop(focusIndex >= lo && focusIndex < hi ? focusIndex : hi > lo ? indexAt(top + height - 1) : -1);
|
|
263
|
+
// Newly mounted rows still have estimates; report only after their heights are measured.
|
|
264
|
+
if (!restoring && !fresh.some(node => node.isConnected)) reportVisible();
|
|
234
265
|
};
|
|
235
266
|
const measure = measured => {
|
|
236
267
|
let changed = false;
|
|
@@ -367,6 +398,7 @@ export function VirtualFeed(props) {
|
|
|
367
398
|
restoring = false;
|
|
368
399
|
}
|
|
369
400
|
checkEdges();
|
|
401
|
+
reportVisible();
|
|
370
402
|
};
|
|
371
403
|
|
|
372
404
|
/**
|
|
@@ -870,7 +902,7 @@ export function VirtualFeed(props) {
|
|
|
870
902
|
measured.push([row, entry.borderBoxSize?.[0]?.blockSize ?? row.getBoundingClientRect().height]);
|
|
871
903
|
}
|
|
872
904
|
}
|
|
873
|
-
if (measure(measured) || resized) restore();
|
|
905
|
+
if (measure(measured) || resized) restore();else reportVisible();
|
|
874
906
|
} finally {
|
|
875
907
|
observing = false;
|
|
876
908
|
}
|