@k2b/ui 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +1 -1
  2. package/dist/browser/content/MarkdownView.js +13 -5
  3. package/dist/browser/content/MarkdownView.js.map +1 -1
  4. package/dist/browser/content/PdfPreview.js +5 -2
  5. package/dist/browser/content/PdfPreview.js.map +1 -1
  6. package/dist/browser/content/index.js +1 -0
  7. package/dist/browser/content/index.js.map +1 -1
  8. package/dist/browser/content/markdown-info-blocks.js +363 -0
  9. package/dist/browser/content/markdown-info-blocks.js.map +1 -0
  10. package/dist/browser/feedback/InstallGuide.js +267 -0
  11. package/dist/browser/feedback/InstallGuide.js.map +1 -0
  12. package/dist/browser/feedback/announce.js +50 -0
  13. package/dist/browser/feedback/announce.js.map +1 -0
  14. package/dist/browser/feedback/dialog-core.js +88 -2
  15. package/dist/browser/feedback/dialog-core.js.map +1 -1
  16. package/dist/browser/feedback/index.js +4 -0
  17. package/dist/browser/feedback/index.js.map +1 -1
  18. package/dist/browser/feedback/install.js +99 -0
  19. package/dist/browser/feedback/install.js.map +1 -0
  20. package/dist/browser/feedback/prompts.js +11 -1
  21. package/dist/browser/feedback/prompts.js.map +1 -1
  22. package/dist/browser/feedback/theme-color.js +15 -0
  23. package/dist/browser/feedback/theme-color.js.map +1 -0
  24. package/dist/browser/feedback/toast.js +10 -44
  25. package/dist/browser/feedback/toast.js.map +1 -1
  26. package/dist/browser/inputs/QrScanner.js +164 -0
  27. package/dist/browser/inputs/QrScanner.js.map +1 -0
  28. package/dist/browser/inputs/index.js +1 -0
  29. package/dist/browser/inputs/index.js.map +1 -1
  30. package/dist/browser/intl/messages.js +96 -2
  31. package/dist/browser/intl/messages.js.map +1 -1
  32. package/dist/browser/layout/Discussion.js +2 -1
  33. package/dist/browser/layout/Discussion.js.map +1 -1
  34. package/dist/browser/layout/MobileShell.js +284 -0
  35. package/dist/browser/layout/MobileShell.js.map +1 -0
  36. package/dist/browser/layout/TabBar.js +69 -0
  37. package/dist/browser/layout/TabBar.js.map +1 -0
  38. package/dist/browser/layout/index.js +2 -0
  39. package/dist/browser/layout/index.js.map +1 -1
  40. package/dist/browser/surfaces/NoticeCard.js +55 -60
  41. package/dist/browser/surfaces/NoticeCard.js.map +1 -1
  42. package/dist/browser/surfaces/index.js +1 -1
  43. package/dist/browser/surfaces/index.js.map +1 -1
  44. package/dist/ssr/content/MarkdownView.js +13 -5
  45. package/dist/ssr/content/MarkdownView.js.map +1 -1
  46. package/dist/ssr/content/PdfPreview.js +4 -2
  47. package/dist/ssr/content/PdfPreview.js.map +1 -1
  48. package/dist/ssr/content/index.js +1 -0
  49. package/dist/ssr/content/index.js.map +1 -1
  50. package/dist/ssr/content/markdown-info-blocks.js +363 -0
  51. package/dist/ssr/content/markdown-info-blocks.js.map +1 -0
  52. package/dist/ssr/feedback/InstallGuide.js +201 -0
  53. package/dist/ssr/feedback/InstallGuide.js.map +1 -0
  54. package/dist/ssr/feedback/announce.js +50 -0
  55. package/dist/ssr/feedback/announce.js.map +1 -0
  56. package/dist/ssr/feedback/dialog-core.js +88 -2
  57. package/dist/ssr/feedback/dialog-core.js.map +1 -1
  58. package/dist/ssr/feedback/index.js +4 -0
  59. package/dist/ssr/feedback/index.js.map +1 -1
  60. package/dist/ssr/feedback/install.js +99 -0
  61. package/dist/ssr/feedback/install.js.map +1 -0
  62. package/dist/ssr/feedback/prompts.js +11 -1
  63. package/dist/ssr/feedback/prompts.js.map +1 -1
  64. package/dist/ssr/feedback/theme-color.js +15 -0
  65. package/dist/ssr/feedback/theme-color.js.map +1 -0
  66. package/dist/ssr/feedback/toast.js +10 -44
  67. package/dist/ssr/feedback/toast.js.map +1 -1
  68. package/dist/ssr/inputs/QrScanner.js +128 -0
  69. package/dist/ssr/inputs/QrScanner.js.map +1 -0
  70. package/dist/ssr/inputs/index.js +1 -0
  71. package/dist/ssr/inputs/index.js.map +1 -1
  72. package/dist/ssr/intl/messages.js +96 -2
  73. package/dist/ssr/intl/messages.js.map +1 -1
  74. package/dist/ssr/layout/Discussion.js +2 -1
  75. package/dist/ssr/layout/Discussion.js.map +1 -1
  76. package/dist/ssr/layout/MobileShell.js +253 -0
  77. package/dist/ssr/layout/MobileShell.js.map +1 -0
  78. package/dist/ssr/layout/TabBar.js +25 -0
  79. package/dist/ssr/layout/TabBar.js.map +1 -0
  80. package/dist/ssr/layout/index.js +2 -0
  81. package/dist/ssr/layout/index.js.map +1 -1
  82. package/dist/ssr/surfaces/NoticeCard.js +21 -30
  83. package/dist/ssr/surfaces/NoticeCard.js.map +1 -1
  84. package/dist/ssr/surfaces/index.js +1 -1
  85. package/dist/ssr/surfaces/index.js.map +1 -1
  86. package/dist/styles.css +1 -1
  87. package/dist/tabler.css +1 -1
  88. package/dist/types/content/MarkdownView.d.ts +6 -2
  89. package/dist/types/content/index.d.ts +1 -0
  90. package/dist/types/content/markdown-info-blocks.d.ts +67 -0
  91. package/dist/types/feedback/InstallGuide.d.ts +26 -0
  92. package/dist/types/feedback/announce.d.ts +19 -0
  93. package/dist/types/feedback/dialog-core.d.ts +5 -0
  94. package/dist/types/feedback/index.d.ts +7 -0
  95. package/dist/types/feedback/install.d.ts +32 -0
  96. package/dist/types/feedback/prompts.d.ts +2 -0
  97. package/dist/types/feedback/theme-color.d.ts +6 -0
  98. package/dist/types/inputs/QrScanner.d.ts +20 -0
  99. package/dist/types/inputs/index.d.ts +2 -0
  100. package/dist/types/intl/messages.d.ts +47 -0
  101. package/dist/types/layout/MobileShell.d.ts +40 -0
  102. package/dist/types/layout/TabBar.d.ts +26 -0
  103. package/dist/types/layout/index.d.ts +4 -0
  104. package/dist/types/surfaces/NoticeCard.d.ts +4 -4
  105. package/dist/types/surfaces/index.d.ts +1 -1
  106. package/package.json +3 -2
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["surfaces/NoticeCard.tsx"],"sourcesContent":["import { For, type JSX, Show, splitProps } from \"solid-js\";\nimport type { IntentTone } from \"../semantics\";\n\nexport type NoticeTone = Extract<IntentTone, \"neutral\" | \"info\" | \"success\" | \"warning\" | \"danger\">;\n\ntype NoticeCardContentProps =\n | { title: JSX.Element; detail?: JSX.Element; children?: JSX.Element }\n | { title?: never; detail?: never; children: JSX.Element };\n\nexport type NoticeCardProps = Omit<JSX.HTMLAttributes<HTMLElement>, \"children\" | \"class\" | \"title\"> &\n NoticeCardContentProps & {\n tone?: NoticeTone;\n icon?: string | false;\n class?: string;\n bodyClass?: string;\n };\n\nexport const NOTICE_CARD_CLASSES = {\n root: \"k2b-notice-card\",\n inner: \"k2b-notice-card__inner\",\n icon: \"k2b-notice-card__icon\",\n content: \"k2b-notice-card__content\",\n title: \"k2b-notice-card__title\",\n description: \"k2b-notice-card__description\",\n body: \"k2b-notice-card__body\",\n} as const;\n\nexport const NOTICE_CARD_ICONS: Readonly<Record<NoticeTone, string>> = {\n neutral: \"ti ti-note\",\n info: \"ti ti-info-circle\",\n success: \"ti ti-circle-check\",\n warning: \"ti ti-alert-triangle\",\n danger: \"ti ti-alert-circle\",\n};\n\nfunction NoticeCardComponent(props: NoticeCardProps): JSX.Element {\n const [local, articleProps] = splitProps(props, [\"tone\", \"title\", \"detail\", \"children\", \"icon\", \"class\", \"bodyClass\"]);\n const tone = () => local.tone ?? \"warning\";\n return (\n <article {...articleProps} class={`${NOTICE_CARD_CLASSES.root} ${local.class ?? \"\"}`} data-tone={tone()}>\n <div class={NOTICE_CARD_CLASSES.inner}>\n <Show when={local.icon !== false}>\n <i\n class={`${typeof local.icon === \"string\" ? local.icon : NOTICE_CARD_ICONS[tone()]} ${NOTICE_CARD_CLASSES.icon}`}\n aria-hidden=\"true\"\n />\n </Show>\n <div class={NOTICE_CARD_CLASSES.content}>\n <Show when={local.title}>{(title) => <p class={NOTICE_CARD_CLASSES.title}>{title()}</p>}</Show>\n <Show when={local.detail}>{(detail) => <p class={NOTICE_CARD_CLASSES.description}>{detail()}</p>}</Show>\n <Show when={local.children}>{(body) => <div class={`${NOTICE_CARD_CLASSES.body} ${local.bodyClass ?? \"\"}`}>{body()}</div>}</Show>\n </div>\n </div>\n </article>\n );\n}\n\nexport type NoticeGridProps<T> = {\n items: readonly T[];\n children: (item: T) => JSX.Element;\n class?: string;\n};\n\nfunction NoticeGrid<T>(props: NoticeGridProps<T>): JSX.Element {\n const columns = () => (props.items.length <= 1 ? \"one\" : props.items.length === 2 ? \"two\" : \"three\");\n return (\n <Show when={props.items.length > 0}>\n <div class={`k2b-notice-grid ${props.class ?? \"\"}`} data-columns={columns()}>\n <For each={props.items}>{(item) => props.children(item)}</For>\n </div>\n </Show>\n );\n}\n\nexport const NoticeCard = Object.assign(NoticeCardComponent, { Grid: NoticeGrid });\nexport default NoticeCard;\n"],"mappings":";;;;;;;;;;;;;;;AAAA,SAAS,GAAG,EAAY,IAAI,EAAE,UAAU,QAAQ,UAAU;AAiB1D,OAAO,MAAM,mBAAmB,GAAG;EACjC,IAAI,EAAE,iBAAiB;EACvB,KAAK,EAAE,wBAAwB;EAC/B,IAAI,EAAE,uBAAuB;EAC7B,OAAO,EAAE,0BAA0B;EACnC,KAAK,EAAE,wBAAwB;EAC/B,WAAW,EAAE,8BAA8B;EAC3C,IAAI,EAAE;AACR,CAAU;AAEV,OAAO,MAAM,iBAAuD,GAAG;EACrE,OAAO,EAAE,YAAY;EACrB,IAAI,EAAE,mBAAmB;EACzB,OAAO,EAAE,oBAAoB;EAC7B,OAAO,EAAE,sBAAsB;EAC/B,MAAM,EAAE;AACV,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAsB,EAAe;EAChE,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;EACtH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,IAAI,SAAS;EAC1C;IAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;IAAA,4BACe,YAAY;MAAA;QAAA,OAAS,GAAG,mBAAmB,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE;MAAA;MAAA;QAAA,OAAa,IAAI,CAAC,CAAC;MAAA;IAAA;IAAA,kCAElG,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,KAAK,CAAC,IAAI,KAAK,KAAK;MAAA;MAAA;QAAA;QAAA,kCAErB,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,GAAG,KAAK,CAAC,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,mBAAmB,CAAC,IAAI,EAAE;QAAA;MAAA;IAAA;IAAA,kCAKhH,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,KAAK,CAAC,KAAK;MAAA;MAAA,UAAI,KAAK;QAAA;QAAA,iBAA2C,KAAK;QAAA,mCAAjC,mBAAmB,CAAC,KAAK;QAAA;MAAA;IAAe;IAAA,kCACtF,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,KAAK,CAAC,MAAM;MAAA;MAAA,UAAI,MAAM;QAAA;QAAA,iBAAiD,MAAM;QAAA,mCAAxC,mBAAmB,CAAC,WAAW;QAAA;MAAA;IAAgB;IAAA,kCAC/F,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,KAAK,CAAC,QAAQ;MAAA;MAAA,UAAI,IAAI;QAAA;QAAA,iBAA0E,IAAI;QAAA,mCAA7D,GAAG,mBAAmB,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,EAAE;QAAA;MAAA;IAAgB;IAAA;MAAA,UAVjH,mBAAmB,CAAC,KAAK;QAAA,OAOvB,mBAAmB,CAAC,OAAO;MAAA;MAAA;MAAA;IAAA;MAAA;MAAA;IAAA;IAAA;IAAA;EAAA;AAQ/C;AAQA,SAAS,UAAU,CAAI,KAAyB,EAAe;EAC7D,MAAM,OAAO,GAAG,MAAO,KAAK,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,GAAG,KAAK,GAAG,OAAQ;EACpG,yBACG,IAAI;IAAA,IAAC,IAAI;MAAA,OAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;IAAA;IAAA;MAAA;MAAA,mCAE7B,GAAG;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,KAAK;QAAA;QAAA,UAAI,IAAI,IAAK,KAAK,CAAC,QAAQ,CAAC,IAAI;MAAC;MAAA;QAAA,WAD7C,mBAAmB,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE;UAAA,OAAgB,OAAO,CAAC,CAAC;QAAA;QAAA;QAAA;MAAA;QAAA;QAAA;MAAA;MAAA;IAAA;EAAA;AAKjF;AAEA,OAAO,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,mBAAmB,EAAE;EAAE,IAAI,EAAE;AAAW,CAAC,CAAC;AAClF,eAAe,UAAU","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["surfaces/NoticeCard.tsx"],"sourcesContent":["import { For, type JSX, Show, splitProps } from \"solid-js\";\nimport type { IntentTone } from \"../semantics\";\n\nexport type NoticeTone = Extract<IntentTone, \"neutral\" | \"info\" | \"success\" | \"warning\" | \"danger\">;\n\ntype NoticeCardContentProps =\n | { title: JSX.Element; detail?: JSX.Element; meta?: JSX.Element; children?: JSX.Element }\n | { title?: never; detail?: never; meta?: never; children: JSX.Element };\n\nexport type NoticeCardProps = Omit<JSX.HTMLAttributes<HTMLElement>, \"children\" | \"class\" | \"title\"> &\n NoticeCardContentProps & {\n tone?: NoticeTone;\n class?: string;\n bodyClass?: string;\n };\n\nexport const NOTICE_CARD_CLASSES = {\n root: \"k2b-notice-card\",\n content: \"k2b-notice-card__content\",\n head: \"k2b-notice-card__head\",\n title: \"k2b-notice-card__title\",\n meta: \"k2b-notice-card__meta\",\n description: \"k2b-notice-card__description\",\n body: \"k2b-notice-card__body\",\n} as const;\n\nfunction NoticeCardComponent(props: NoticeCardProps): JSX.Element {\n const [local, articleProps] = splitProps(props, [\"tone\", \"title\", \"detail\", \"meta\", \"children\", \"class\", \"bodyClass\"]);\n return (\n <article {...articleProps} class={`${NOTICE_CARD_CLASSES.root} ${local.class ?? \"\"}`} data-tone={local.tone ?? \"neutral\"}>\n <div class={NOTICE_CARD_CLASSES.content}>\n <Show when={local.title}>\n {(title) => (\n <div class={NOTICE_CARD_CLASSES.head}>\n <p class={NOTICE_CARD_CLASSES.title}>{title()}</p>\n <Show when={local.meta}>{(meta) => <span class={NOTICE_CARD_CLASSES.meta}>{meta()}</span>}</Show>\n </div>\n )}\n </Show>\n <Show when={local.detail}>{(detail) => <p class={NOTICE_CARD_CLASSES.description}>{detail()}</p>}</Show>\n <Show when={local.children}>{(body) => <div class={`${NOTICE_CARD_CLASSES.body} ${local.bodyClass ?? \"\"}`}>{body()}</div>}</Show>\n </div>\n </article>\n );\n}\n\nexport type NoticeGridProps<T> = {\n items: readonly T[];\n children: (item: T) => JSX.Element;\n class?: string;\n};\n\nfunction NoticeGrid<T>(props: NoticeGridProps<T>): JSX.Element {\n const columns = () => (props.items.length <= 1 ? \"one\" : props.items.length === 2 ? \"two\" : \"three\");\n return (\n <Show when={props.items.length > 0}>\n <div class={`k2b-notice-grid ${props.class ?? \"\"}`} data-columns={columns()}>\n <For each={props.items}>{(item) => props.children(item)}</For>\n </div>\n </Show>\n );\n}\n\nexport const NoticeCard = Object.assign(NoticeCardComponent, { Grid: NoticeGrid });\nexport default NoticeCard;\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA,SAAS,GAAG,EAAY,IAAI,EAAE,UAAU,QAAQ,UAAU;AAgB1D,OAAO,MAAM,mBAAmB,GAAG;EACjC,IAAI,EAAE,iBAAiB;EACvB,OAAO,EAAE,0BAA0B;EACnC,IAAI,EAAE,uBAAuB;EAC7B,KAAK,EAAE,wBAAwB;EAC/B,IAAI,EAAE,uBAAuB;EAC7B,WAAW,EAAE,8BAA8B;EAC3C,IAAI,EAAE;AACR,CAAU;AAEV,SAAS,mBAAmB,CAAC,KAAsB,EAAe;EAChE,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;EACtH;IAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;IAAA,4BACe,YAAY;MAAA;QAAA,OAAS,GAAG,mBAAmB,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE;MAAA;MAAA;QAAA,OAAa,KAAK,CAAC,IAAI,IAAI,SAAS;MAAA;IAAA;IAAA,kCAEnH,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,KAAK,CAAC,KAAK;MAAA;MAAA,UACnB,KAAK;QAAA;UAAA;UAAA;UAAA;QAAA,gBAEmC,KAAK;QAAA,kCAC1C,IAAI;UAAA,IAAC,IAAI;YAAA,OAAE,KAAK,CAAC,IAAI;UAAA;UAAA,UAAI,IAAI;YAAA;YAAA,iBAA6C,IAAI;YAAA,mCAA/B,mBAAmB,CAAC,IAAI;YAAA;UAAA;QAAiB;QAAA;UAAA,UAF/E,mBAAmB,CAAC,IAAI;YAAA,OACxB,mBAAmB,CAAC,KAAK;UAAA;UAAA;UAAA;QAAA;UAAA;UAAA;QAAA;QAAA;MAAA;IAGtC;IAAA,kCAEF,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,KAAK,CAAC,MAAM;MAAA;MAAA,UAAI,MAAM;QAAA;QAAA,iBAAiD,MAAM;QAAA,mCAAxC,mBAAmB,CAAC,WAAW;QAAA;MAAA;IAAgB;IAAA,kCAC/F,IAAI;MAAA,IAAC,IAAI;QAAA,OAAE,KAAK,CAAC,QAAQ;MAAA;MAAA,UAAI,IAAI;QAAA;QAAA,iBAA0E,IAAI;QAAA,mCAA7D,GAAG,mBAAmB,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,EAAE;QAAA;MAAA;IAAgB;IAAA,kCAV/G,mBAAmB,CAAC,OAAO;IAAA;IAAA;EAAA;AAc7C;AAQA,SAAS,UAAU,CAAI,KAAyB,EAAe;EAC7D,MAAM,OAAO,GAAG,MAAO,KAAK,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,GAAG,KAAK,GAAG,OAAQ;EACpG,yBACG,IAAI;IAAA,IAAC,IAAI;MAAA,OAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;IAAA;IAAA;MAAA;MAAA,mCAE7B,GAAG;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,KAAK;QAAA;QAAA,UAAI,IAAI,IAAK,KAAK,CAAC,QAAQ,CAAC,IAAI;MAAC;MAAA;QAAA,WAD7C,mBAAmB,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE;UAAA,OAAgB,OAAO,CAAC,CAAC;QAAA;QAAA;QAAA;MAAA;QAAA;QAAA;MAAA;MAAA;IAAA;EAAA;AAKjF;AAEA,OAAO,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,mBAAmB,EAAE;EAAE,IAAI,EAAE;AAAW,CAAC,CAAC;AAClF,eAAe,UAAU","ignoreList":[]}
@@ -2,7 +2,7 @@ export { Avatar } from "./Avatar";
2
2
  export { DescriptionList } from "./DescriptionList";
3
3
  export { LinkCard } from "./LinkCard";
4
4
  export { NotFoundState } from "./NotFoundState";
5
- export { NOTICE_CARD_CLASSES, NOTICE_CARD_ICONS, NoticeCard } from "./NoticeCard";
5
+ export { NOTICE_CARD_CLASSES, NoticeCard } from "./NoticeCard";
6
6
  export { Paper } from "./Paper";
7
7
  export { default as Placeholder } from "./Placeholder";
8
8
  export { ProgressBar } from "./ProgressBar";
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["surfaces/index.ts"],"sourcesContent":["export type { AvatarProps, AvatarSize } from \"./Avatar\";\nexport { Avatar } from \"./Avatar\";\nexport type { DescriptionListItem, DescriptionListProps } from \"./DescriptionList\";\nexport { DescriptionList } from \"./DescriptionList\";\nexport type { LinkCardColor, LinkCardProps } from \"./LinkCard\";\nexport { LinkCard } from \"./LinkCard\";\nexport type { NotFoundStateAction, NotFoundStateProps } from \"./NotFoundState\";\nexport { NotFoundState } from \"./NotFoundState\";\nexport type { NoticeCardProps, NoticeGridProps, NoticeTone } from \"./NoticeCard\";\nexport { NOTICE_CARD_CLASSES, NOTICE_CARD_ICONS, NoticeCard } from \"./NoticeCard\";\nexport type { PaperProps, PaperTag } from \"./Paper\";\nexport { Paper } from \"./Paper\";\nexport type {\n PlaceholderAlign,\n PlaceholderProps,\n PlaceholderState,\n PlaceholderSurface,\n PlaceholderVariant,\n} from \"./Placeholder\";\nexport { default as Placeholder } from \"./Placeholder\";\nexport type { ProgressBarProps, ProgressBarTone } from \"./ProgressBar\";\nexport { ProgressBar } from \"./ProgressBar\";\nexport type { ProgressRingProps, ProgressRingTone } from \"./ProgressRing\";\nexport { ProgressRing } from \"./ProgressRing\";\nexport type { StatCellAccent, StatCellProps, StatCellTone } from \"./StatCell\";\nexport { StatCell } from \"./StatCell\";\nexport type {\n StatGridAction,\n StatGridColumns,\n StatGridProps,\n StatGridSize,\n StatGridSurface,\n} from \"./StatGrid\";\nexport { StatGrid } from \"./StatGrid\";\nexport type { StatusBadgeProps, StatusTone } from \"./StatusBadge\";\nexport { StatusBadge } from \"./StatusBadge\";\nexport type { TagProps, TagSize } from \"./Tag\";\nexport { Tag } from \"./Tag\";\n"],"mappings":"AACA,SAAS,MAAM,QAAQ,UAAU;AAEjC,SAAS,eAAe,QAAQ,mBAAmB;AAEnD,SAAS,QAAQ,QAAQ,YAAY;AAErC,SAAS,aAAa,QAAQ,iBAAiB;AAE/C,SAAS,mBAAmB,EAAE,iBAAiB,EAAE,UAAU,QAAQ,cAAc;AAEjF,SAAS,KAAK,QAAQ,SAAS;AAQ/B,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAEtD,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,YAAY,QAAQ,gBAAgB;AAE7C,SAAS,QAAQ,QAAQ,YAAY;AAQrC,SAAS,QAAQ,QAAQ,YAAY;AAErC,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,GAAG,QAAQ,OAAO","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["surfaces/index.ts"],"sourcesContent":["export type { AvatarProps, AvatarSize } from \"./Avatar\";\nexport { Avatar } from \"./Avatar\";\nexport type { DescriptionListItem, DescriptionListProps } from \"./DescriptionList\";\nexport { DescriptionList } from \"./DescriptionList\";\nexport type { LinkCardColor, LinkCardProps } from \"./LinkCard\";\nexport { LinkCard } from \"./LinkCard\";\nexport type { NotFoundStateAction, NotFoundStateProps } from \"./NotFoundState\";\nexport { NotFoundState } from \"./NotFoundState\";\nexport type { NoticeCardProps, NoticeGridProps, NoticeTone } from \"./NoticeCard\";\nexport { NOTICE_CARD_CLASSES, NoticeCard } from \"./NoticeCard\";\nexport type { PaperProps, PaperTag } from \"./Paper\";\nexport { Paper } from \"./Paper\";\nexport type {\n PlaceholderAlign,\n PlaceholderProps,\n PlaceholderState,\n PlaceholderSurface,\n PlaceholderVariant,\n} from \"./Placeholder\";\nexport { default as Placeholder } from \"./Placeholder\";\nexport type { ProgressBarProps, ProgressBarTone } from \"./ProgressBar\";\nexport { ProgressBar } from \"./ProgressBar\";\nexport type { ProgressRingProps, ProgressRingTone } from \"./ProgressRing\";\nexport { ProgressRing } from \"./ProgressRing\";\nexport type { StatCellAccent, StatCellProps, StatCellTone } from \"./StatCell\";\nexport { StatCell } from \"./StatCell\";\nexport type {\n StatGridAction,\n StatGridColumns,\n StatGridProps,\n StatGridSize,\n StatGridSurface,\n} from \"./StatGrid\";\nexport { StatGrid } from \"./StatGrid\";\nexport type { StatusBadgeProps, StatusTone } from \"./StatusBadge\";\nexport { StatusBadge } from \"./StatusBadge\";\nexport type { TagProps, TagSize } from \"./Tag\";\nexport { Tag } from \"./Tag\";\n"],"mappings":"AACA,SAAS,MAAM,QAAQ,UAAU;AAEjC,SAAS,eAAe,QAAQ,mBAAmB;AAEnD,SAAS,QAAQ,QAAQ,YAAY;AAErC,SAAS,aAAa,QAAQ,iBAAiB;AAE/C,SAAS,mBAAmB,EAAE,UAAU,QAAQ,cAAc;AAE9D,SAAS,KAAK,QAAQ,SAAS;AAQ/B,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAEtD,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,YAAY,QAAQ,gBAAgB;AAE7C,SAAS,QAAQ,QAAQ,YAAY;AAQrC,SAAS,QAAQ,QAAQ,YAAY;AAErC,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,GAAG,QAAQ,OAAO","ignoreList":[]}
@@ -2,7 +2,9 @@ import { ssr as _$ssr } from "solid-js/web";
2
2
  import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
3
3
  import { escape as _$escape } from "solid-js/web";
4
4
  var _tmpl$ = ["<div class=\"", "\"", ">", "</div>"];
5
- import { marked, Renderer } from "marked";
5
+ import { Marked, Renderer } from "marked";
6
+ import { useLocale } from "../intl/locale";
7
+ import { markdownInfoBlocks } from "./markdown-info-blocks";
6
8
  const escapeHtml = value => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
7
9
  const safeUrl = value => {
8
10
  const normalized = value.trim().replace(/[\u0000-\u001f\u007f-\u009f\s]+/g, "");
@@ -107,7 +109,9 @@ const createSafeRenderer = (options = {}) => {
107
109
  };
108
110
  return renderer;
109
111
  };
110
- export const renderSafeMarkdown = (markdown, options = {}) => marked.parse(markdown, {
112
+ export const renderSafeMarkdown = (markdown, options = {}) => new Marked(markdownInfoBlocks({
113
+ locale: options.locale
114
+ })).parse(markdown, {
111
115
  async: false,
112
116
  renderer: createSafeRenderer(options)
113
117
  });
@@ -116,8 +120,10 @@ export const renderSafeMarkdown = (markdown, options = {}) => marked.parse(markd
116
120
  * Markdown View Component (SSR)
117
121
  *
118
122
  * Renders untrusted Markdown safely by default. Raw HTML and unsafe link
119
- * protocols are escaped. Already-rendered HTML requires the deliberately named
120
- * `trustedHtml` boundary; the caller owns sanitization in that mode.
123
+ * protocols are escaped. Info blocks (`:::note`, `:::info`, `:::success`,
124
+ * `:::warning`, `:::danger`) render as the calm `NoticeCard`. Already-rendered
125
+ * HTML requires the deliberately named `trustedHtml` boundary; the caller owns
126
+ * sanitization in that mode.
121
127
  *
122
128
  * @example
123
129
  * ```tsx
@@ -132,11 +138,13 @@ export const renderSafeMarkdown = (markdown, options = {}) => marked.parse(markd
132
138
  * ```
133
139
  */
134
140
  export default function MarkdownView(props) {
141
+ const locale = useLocale();
135
142
  const html = () => props.markdown !== undefined ? renderSafeMarkdown(props.markdown, {
136
143
  inlineTokens: props.inlineTokens,
137
144
  allowImages: props.allowImages,
138
145
  linkProtocols: props.linkProtocols,
139
- linkTarget: props.linkTarget
146
+ linkTarget: props.linkTarget,
147
+ locale: locale()
140
148
  }) : props.trustedHtml;
141
149
  return _$ssr(_tmpl$, `k2b-content-markdown ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-heading-scale", props.headingScale && props.headingScale !== "normal" ? _$escape(props.headingScale, true) : _$escape(undefined, true), false), html());
142
150
  }
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/MarkdownView.tsx"],"sourcesContent":["import { marked, Renderer, type Tokens } from \"marked\";\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};\n\nconst escapeHtml = (value: string): string =>\n value.replaceAll(\"&\", \"&amp;\").replaceAll(\"<\", \"&lt;\").replaceAll(\">\", \"&gt;\").replaceAll('\"', \"&quot;\").replaceAll(\"'\", \"&#39;\");\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\nconst 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 const titleAttribute = title ? ` title=\"${escapeHtml(title)}\"` : \"\";\n const target = options.linkTarget === \"_blank\" ? ' target=\"_blank\" rel=\"noopener noreferrer\"' : \"\";\n return `<a href=\"${escapeHtml(url)}\"${titleAttribute}${target}>${body}</a>`;\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 marked.parse(markdown, {\n async: false,\n renderer: createSafeRenderer(options),\n }) as string;\n\n/**\n * Markdown View Component (SSR)\n *\n * Renders untrusted Markdown safely by default. Raw HTML and unsafe link\n * protocols are escaped. Already-rendered HTML requires the deliberately named\n * `trustedHtml` boundary; the caller owns 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 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 })\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\";\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\nconst escapeHtml = (value: string): string =>\n value.replaceAll(\"&\", \"&amp;\").replaceAll(\"<\", \"&lt;\").replaceAll(\">\", \"&gt;\").replaceAll('\"', \"&quot;\").replaceAll(\"'\", \"&#39;\");\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\nconst 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 const titleAttribute = title ? ` title=\"${escapeHtml(title)}\"` : \"\";\n const target = options.linkTarget === \"_blank\" ? ' target=\"_blank\" rel=\"noopener noreferrer\"' : \"\";\n return `<a href=\"${escapeHtml(url)}\"${titleAttribute}${target}>${body}</a>`;\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 new Marked(markdownInfoBlocks({ locale: options.locale })).parse(markdown, {\n async: false,\n renderer: createSafeRenderer(options),\n }) as string;\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":[]}
@@ -39,6 +39,7 @@ export default function PdfPreview(props) {
39
39
  // An automatic preview shows one fixed document; the open action reuses it instead of requesting it again.
40
40
  let shownBlob = null;
41
41
  let openButton;
42
+ let frame;
42
43
  let renderButton;
43
44
  let errorRetryButton;
44
45
  let disposed = false;
@@ -82,8 +83,9 @@ export default function PdfPreview(props) {
82
83
  setUrl(nextUrl);
83
84
  setLoading(false);
84
85
  if (previousUrl) URL.revokeObjectURL(previousUrl);
85
- // The shown document removes the retry action; keep keyboard focus in the actions instead of the page.
86
- if (retryFocused && document.activeElement === document.body) openButton?.focus();
86
+ // The shown document removes the retry action; keep keyboard focus in the actions instead of the page, or on the
87
+ // document itself when the host shows only the content.
88
+ if (retryFocused && document.activeElement === document.body) (openButton?.isConnected ? openButton : frame)?.focus();
87
89
  } catch (e) {
88
90
  if (disposed || generation !== loadGeneration) return;
89
91
  shownBlob = null;
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/PdfPreview.tsx"],"sourcesContent":["import { createSignal, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { resolveUiMessages, useUiMessages } from \"../intl/messages\";\nimport Placeholder from \"../surfaces/Placeholder\";\n\nexport type PdfPreviewRequest = () => Promise<Response | Blob>;\n\nexport type PdfPreviewProps = {\n request: PdfPreviewRequest;\n autoLoad?: boolean;\n disabled?: () => boolean;\n title?: string;\n buttonLabel?: string;\n openButtonLabel?: string;\n /**\n * Opens the document at this address in a new tab instead of a local copy. Pass a stable same-origin URL that\n * serves the PDF inline, so reloading and the viewer's file name keep working. Without it, the open action shows\n * a temporary copy of the requested document.\n */\n openHref?: string;\n /** Adds a Download action. The host owns the download, for example a fresh attachment URL. */\n onDownload?: () => void;\n emptyText?: string;\n class?: string;\n children?: (parts: { actions: JSX.Element; content: JSX.Element }) => JSX.Element;\n renderError?: (message: string) => JSX.Element;\n};\n\nconst readErrorMessage = async (response: Response): Promise<string> => {\n try {\n const data = (await response.json()) as unknown;\n if (data && typeof data === \"object\" && \"message\" in data && typeof data.message === \"string\") return data.message;\n } catch {\n // Fall through to the HTTP status fallback.\n }\n return resolveUiMessages().pdfPreviewHttpError({ status: response.status });\n};\n\nexport default function PdfPreview(props: PdfPreviewProps) {\n const messages = useUiMessages();\n const [url, setUrl] = createSignal<string | null>(null);\n // An automatic preview starts loading once mounted. The server and the page before hydration already show that\n // state, so they offer neither a retry nor an invitation to render while nothing has failed.\n const [loading, setLoading] = createSignal(Boolean(props.autoLoad) && !props.disabled?.());\n const [opening, setOpening] = createSignal(false);\n const [error, setError] = createSignal<string | null>(null);\n const [failed, setFailed] = createSignal(false);\n const [tabBlocked, setTabBlocked] = createSignal(false);\n // An automatic preview shows one fixed document; the open action reuses it instead of requesting it again.\n let shownBlob: Blob | null = null;\n let openButton: HTMLElement | undefined;\n let renderButton: HTMLButtonElement | undefined;\n let errorRetryButton: HTMLButtonElement | undefined;\n let disposed = false;\n let loadGeneration = 0;\n let openGeneration = 0;\n\n const revokeCurrent = () => {\n const current = url();\n if (current) URL.revokeObjectURL(current);\n setUrl(null);\n };\n\n onCleanup(() => {\n disposed = true;\n loadGeneration += 1;\n openGeneration += 1;\n revokeCurrent();\n });\n\n const readPdfBlob = async () => {\n const response = await props.request();\n const blob = response instanceof Response ? (response.ok ? await response.blob() : null) : response;\n if (!blob) throw new Error(await readErrorMessage(response as Response));\n if (blob.type && blob.type !== \"application/pdf\") throw new Error(`PDF preview returned ${blob.type} instead of application/pdf`);\n return blob;\n };\n\n const load = async () => {\n if (loading() || opening() || props.disabled?.()) return;\n const generation = ++loadGeneration;\n // A retry the shown document or the loading state removes hands keyboard focus on instead of dropping it.\n const retryFocused =\n (props.autoLoad && document.activeElement === renderButton) ||\n (errorRetryButton?.isConnected && document.activeElement === errorRetryButton);\n setLoading(true);\n setError(null);\n try {\n const blob = await readPdfBlob();\n const nextUrl = URL.createObjectURL(blob);\n if (disposed || generation !== loadGeneration) {\n URL.revokeObjectURL(nextUrl);\n return;\n }\n const previousUrl = url();\n shownBlob = blob;\n setFailed(false);\n setUrl(nextUrl);\n setLoading(false);\n if (previousUrl) URL.revokeObjectURL(previousUrl);\n // The shown document removes the retry action; keep keyboard focus in the actions instead of the page.\n if (retryFocused && document.activeElement === document.body) openButton?.focus();\n } catch (e) {\n if (disposed || generation !== loadGeneration) return;\n shownBlob = null;\n setFailed(true);\n setError(e instanceof Error ? e.message : \"PDF preview failed\");\n if (retryFocused && document.activeElement === document.body) errorRetryButton?.focus();\n } finally {\n if (!disposed && generation === loadGeneration) setLoading(false);\n }\n };\n\n onMount(() => {\n // Hand the initial loading state to the request itself, which also covers a preview disabled by now.\n setLoading(false);\n if (props.autoLoad) void load();\n });\n\n const openInNewTab = async () => {\n if (loading() || opening() || props.disabled?.()) return;\n const generation = ++openGeneration;\n const tab = window.open(\"\", \"_blank\");\n // A blocked tab is not a document error: keep the shown document and report it beside the actions.\n setTabBlocked(!tab);\n if (!tab) return;\n tab.opener = null;\n tab.document.title = props.title ?? messages().pdfPreview;\n tab.document.body.textContent = messages().pdfPreviewRendering;\n setOpening(true);\n setError(null);\n try {\n const blob = (props.autoLoad ? shownBlob : null) ?? (await readPdfBlob());\n if (disposed || generation !== openGeneration) {\n tab.close();\n return;\n }\n const objectUrl = URL.createObjectURL(blob);\n tab.location.href = objectUrl;\n window.setTimeout(() => URL.revokeObjectURL(objectUrl), 60_000);\n } catch (e) {\n tab.close();\n if (!disposed && generation === openGeneration) setError(e instanceof Error ? e.message : \"PDF preview failed\");\n } finally {\n if (!disposed && generation === openGeneration) setOpening(false);\n }\n };\n\n // With autoLoad, rendering again would show the same document: offer it only until one is shown. After a failure the\n // default error state carries it as the retry; beside a caller's error content it stays in place while a retry loads.\n const renderable = () => !props.autoLoad || (failed() ? Boolean(props.renderError) : !url() && !loading());\n const actions = () => (\n <div class=\"k2b-content-pdf-preview__actions\">\n <Show\n when={!props.disabled?.() && props.openHref}\n fallback={\n <button\n ref={(element) => (openButton = element)}\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void openInNewTab()}\n disabled={loading() || opening() || props.disabled?.()}\n >\n <i class={opening() ? \"ti ti-loader-2 k2b-spin\" : \"ti ti-external-link\"} aria-hidden=\"true\" />\n {props.openButtonLabel ?? messages().openPreview}\n </button>\n }\n >\n {(href) => (\n // A plain link to a real address: the browser opens it on the user's own click, and the tab can reload it.\n <a\n ref={(element) => (openButton = element)}\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n href={href()}\n target=\"_blank\"\n rel=\"noopener\"\n >\n <i class=\"ti ti-external-link\" aria-hidden=\"true\" />\n {props.openButtonLabel ?? messages().openPreview}\n </a>\n )}\n </Show>\n <Show when={props.onDownload}>\n <button\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => props.onDownload?.()}\n disabled={props.disabled?.()}\n >\n <i class=\"ti ti-download\" aria-hidden=\"true\" />\n {messages().download}\n </button>\n </Show>\n <Show when={renderable()}>\n <button\n ref={renderButton}\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void load()}\n disabled={loading() || opening() || props.disabled?.()}\n >\n <i class={loading() ? \"ti ti-loader-2 k2b-spin\" : \"ti ti-file-type-pdf\"} aria-hidden=\"true\" />\n {props.buttonLabel ?? messages().previewPdf}\n </button>\n </Show>\n <Show when={tabBlocked()}>\n <span role=\"alert\" class=\"k2b-content-pdf-preview__notice\">\n {messages().pdfPreviewTabBlocked}\n </span>\n </Show>\n </div>\n );\n // Every state before a document is shown uses one placeholder in the viewer's box, so loading changes no layout.\n const content = () => (\n <Show\n when={error()}\n fallback={\n <Show\n when={url()}\n fallback={\n <Placeholder\n class=\"k2b-content-pdf-preview__placeholder\"\n state={loading() ? \"loading\" : \"empty\"}\n icon={loading() ? undefined : \"ti ti-file-type-pdf\"}\n title={loading() ? messages().loading : undefined}\n description={loading() ? undefined : (props.emptyText ?? messages().renderPdfPreview)}\n />\n }\n >\n {(currentUrl) => (\n <iframe class=\"k2b-content-pdf-preview__frame\" src={currentUrl()} title={props.title ?? messages().pdfPreview} />\n )}\n </Show>\n }\n >\n {(message) =>\n props.renderError?.(message()) ?? (\n <Placeholder\n class=\"k2b-content-pdf-preview__placeholder\"\n state=\"error\"\n description={message()}\n action={\n // One retry at a time: the render action moves here only where the toolbar no longer offers it.\n renderable() ? undefined : (\n <button\n ref={(element) => (errorRetryButton = element)}\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void load()}\n disabled={opening() || props.disabled?.()}\n >\n {props.buttonLabel ?? messages().retry}\n </button>\n )\n }\n />\n )\n }\n </Show>\n );\n\n if (props.children)\n return props.children({\n get actions() {\n return actions();\n },\n get content() {\n return content();\n },\n });\n return (\n <section class={`k2b-content-pdf-preview ${props.class ?? \"\"}`}>\n <div class=\"k2b-content-pdf-preview__toolbar\">\n <div class=\"k2b-content-pdf-preview__heading\">\n <Show when={props.title}>\n <h2 class=\"k2b-content-pdf-preview__title\">{props.title}</h2>\n </Show>\n </div>\n {actions()}\n </div>\n {content()}\n </section>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/PdfPreview.tsx"],"sourcesContent":["import { createSignal, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { resolveUiMessages, useUiMessages } from \"../intl/messages\";\nimport Placeholder from \"../surfaces/Placeholder\";\n\nexport type PdfPreviewRequest = () => Promise<Response | Blob>;\n\nexport type PdfPreviewProps = {\n request: PdfPreviewRequest;\n autoLoad?: boolean;\n disabled?: () => boolean;\n title?: string;\n buttonLabel?: string;\n openButtonLabel?: string;\n /**\n * Opens the document at this address in a new tab instead of a local copy. Pass a stable same-origin URL that\n * serves the PDF inline, so reloading and the viewer's file name keep working. Without it, the open action shows\n * a temporary copy of the requested document.\n */\n openHref?: string;\n /** Adds a Download action. The host owns the download, for example a fresh attachment URL. */\n onDownload?: () => void;\n emptyText?: string;\n class?: string;\n children?: (parts: { actions: JSX.Element; content: JSX.Element }) => JSX.Element;\n renderError?: (message: string) => JSX.Element;\n};\n\nconst readErrorMessage = async (response: Response): Promise<string> => {\n try {\n const data = (await response.json()) as unknown;\n if (data && typeof data === \"object\" && \"message\" in data && typeof data.message === \"string\") return data.message;\n } catch {\n // Fall through to the HTTP status fallback.\n }\n return resolveUiMessages().pdfPreviewHttpError({ status: response.status });\n};\n\nexport default function PdfPreview(props: PdfPreviewProps) {\n const messages = useUiMessages();\n const [url, setUrl] = createSignal<string | null>(null);\n // An automatic preview starts loading once mounted. The server and the page before hydration already show that\n // state, so they offer neither a retry nor an invitation to render while nothing has failed.\n const [loading, setLoading] = createSignal(Boolean(props.autoLoad) && !props.disabled?.());\n const [opening, setOpening] = createSignal(false);\n const [error, setError] = createSignal<string | null>(null);\n const [failed, setFailed] = createSignal(false);\n const [tabBlocked, setTabBlocked] = createSignal(false);\n // An automatic preview shows one fixed document; the open action reuses it instead of requesting it again.\n let shownBlob: Blob | null = null;\n let openButton: HTMLElement | undefined;\n let frame: HTMLIFrameElement | undefined;\n let renderButton: HTMLButtonElement | undefined;\n let errorRetryButton: HTMLButtonElement | undefined;\n let disposed = false;\n let loadGeneration = 0;\n let openGeneration = 0;\n\n const revokeCurrent = () => {\n const current = url();\n if (current) URL.revokeObjectURL(current);\n setUrl(null);\n };\n\n onCleanup(() => {\n disposed = true;\n loadGeneration += 1;\n openGeneration += 1;\n revokeCurrent();\n });\n\n const readPdfBlob = async () => {\n const response = await props.request();\n const blob = response instanceof Response ? (response.ok ? await response.blob() : null) : response;\n if (!blob) throw new Error(await readErrorMessage(response as Response));\n if (blob.type && blob.type !== \"application/pdf\") throw new Error(`PDF preview returned ${blob.type} instead of application/pdf`);\n return blob;\n };\n\n const load = async () => {\n if (loading() || opening() || props.disabled?.()) return;\n const generation = ++loadGeneration;\n // A retry the shown document or the loading state removes hands keyboard focus on instead of dropping it.\n const retryFocused =\n (props.autoLoad && document.activeElement === renderButton) ||\n (errorRetryButton?.isConnected && document.activeElement === errorRetryButton);\n setLoading(true);\n setError(null);\n try {\n const blob = await readPdfBlob();\n const nextUrl = URL.createObjectURL(blob);\n if (disposed || generation !== loadGeneration) {\n URL.revokeObjectURL(nextUrl);\n return;\n }\n const previousUrl = url();\n shownBlob = blob;\n setFailed(false);\n setUrl(nextUrl);\n setLoading(false);\n if (previousUrl) URL.revokeObjectURL(previousUrl);\n // The shown document removes the retry action; keep keyboard focus in the actions instead of the page, or on the\n // document itself when the host shows only the content.\n if (retryFocused && document.activeElement === document.body) (openButton?.isConnected ? openButton : frame)?.focus();\n } catch (e) {\n if (disposed || generation !== loadGeneration) return;\n shownBlob = null;\n setFailed(true);\n setError(e instanceof Error ? e.message : \"PDF preview failed\");\n if (retryFocused && document.activeElement === document.body) errorRetryButton?.focus();\n } finally {\n if (!disposed && generation === loadGeneration) setLoading(false);\n }\n };\n\n onMount(() => {\n // Hand the initial loading state to the request itself, which also covers a preview disabled by now.\n setLoading(false);\n if (props.autoLoad) void load();\n });\n\n const openInNewTab = async () => {\n if (loading() || opening() || props.disabled?.()) return;\n const generation = ++openGeneration;\n const tab = window.open(\"\", \"_blank\");\n // A blocked tab is not a document error: keep the shown document and report it beside the actions.\n setTabBlocked(!tab);\n if (!tab) return;\n tab.opener = null;\n tab.document.title = props.title ?? messages().pdfPreview;\n tab.document.body.textContent = messages().pdfPreviewRendering;\n setOpening(true);\n setError(null);\n try {\n const blob = (props.autoLoad ? shownBlob : null) ?? (await readPdfBlob());\n if (disposed || generation !== openGeneration) {\n tab.close();\n return;\n }\n const objectUrl = URL.createObjectURL(blob);\n tab.location.href = objectUrl;\n window.setTimeout(() => URL.revokeObjectURL(objectUrl), 60_000);\n } catch (e) {\n tab.close();\n if (!disposed && generation === openGeneration) setError(e instanceof Error ? e.message : \"PDF preview failed\");\n } finally {\n if (!disposed && generation === openGeneration) setOpening(false);\n }\n };\n\n // With autoLoad, rendering again would show the same document: offer it only until one is shown. After a failure the\n // default error state carries it as the retry; beside a caller's error content it stays in place while a retry loads.\n const renderable = () => !props.autoLoad || (failed() ? Boolean(props.renderError) : !url() && !loading());\n const actions = () => (\n <div class=\"k2b-content-pdf-preview__actions\">\n <Show\n when={!props.disabled?.() && props.openHref}\n fallback={\n <button\n ref={(element) => (openButton = element)}\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void openInNewTab()}\n disabled={loading() || opening() || props.disabled?.()}\n >\n <i class={opening() ? \"ti ti-loader-2 k2b-spin\" : \"ti ti-external-link\"} aria-hidden=\"true\" />\n {props.openButtonLabel ?? messages().openPreview}\n </button>\n }\n >\n {(href) => (\n // A plain link to a real address: the browser opens it on the user's own click, and the tab can reload it.\n <a\n ref={(element) => (openButton = element)}\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n href={href()}\n target=\"_blank\"\n rel=\"noopener\"\n >\n <i class=\"ti ti-external-link\" aria-hidden=\"true\" />\n {props.openButtonLabel ?? messages().openPreview}\n </a>\n )}\n </Show>\n <Show when={props.onDownload}>\n <button\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => props.onDownload?.()}\n disabled={props.disabled?.()}\n >\n <i class=\"ti ti-download\" aria-hidden=\"true\" />\n {messages().download}\n </button>\n </Show>\n <Show when={renderable()}>\n <button\n ref={renderButton}\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void load()}\n disabled={loading() || opening() || props.disabled?.()}\n >\n <i class={loading() ? \"ti ti-loader-2 k2b-spin\" : \"ti ti-file-type-pdf\"} aria-hidden=\"true\" />\n {props.buttonLabel ?? messages().previewPdf}\n </button>\n </Show>\n <Show when={tabBlocked()}>\n <span role=\"alert\" class=\"k2b-content-pdf-preview__notice\">\n {messages().pdfPreviewTabBlocked}\n </span>\n </Show>\n </div>\n );\n // Every state before a document is shown uses one placeholder in the viewer's box, so loading changes no layout.\n const content = () => (\n <Show\n when={error()}\n fallback={\n <Show\n when={url()}\n fallback={\n <Placeholder\n class=\"k2b-content-pdf-preview__placeholder\"\n state={loading() ? \"loading\" : \"empty\"}\n icon={loading() ? undefined : \"ti ti-file-type-pdf\"}\n title={loading() ? messages().loading : undefined}\n description={loading() ? undefined : (props.emptyText ?? messages().renderPdfPreview)}\n />\n }\n >\n {(currentUrl) => (\n <iframe\n ref={(element) => (frame = element)}\n class=\"k2b-content-pdf-preview__frame\"\n src={currentUrl()}\n title={props.title ?? messages().pdfPreview}\n />\n )}\n </Show>\n }\n >\n {(message) =>\n props.renderError?.(message()) ?? (\n <Placeholder\n class=\"k2b-content-pdf-preview__placeholder\"\n state=\"error\"\n description={message()}\n action={\n // One retry at a time: the render action moves here only where the toolbar no longer offers it.\n renderable() ? undefined : (\n <button\n ref={(element) => (errorRetryButton = element)}\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void load()}\n disabled={opening() || props.disabled?.()}\n >\n {props.buttonLabel ?? messages().retry}\n </button>\n )\n }\n />\n )\n }\n </Show>\n );\n\n if (props.children)\n return props.children({\n get actions() {\n return actions();\n },\n get content() {\n return content();\n },\n });\n return (\n <section class={`k2b-content-pdf-preview ${props.class ?? \"\"}`}>\n <div class=\"k2b-content-pdf-preview__toolbar\">\n <div class=\"k2b-content-pdf-preview__heading\">\n <Show when={props.title}>\n <h2 class=\"k2b-content-pdf-preview__title\">{props.title}</h2>\n </Show>\n </div>\n {actions()}\n </div>\n {content()}\n </section>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -18,6 +18,7 @@ export { canPreviewFile, default as FileView, formatFileViewSize, getFileViewPre
18
18
  export { default as Lightbox } from "./Lightbox";
19
19
  export { default as LogEntriesTable } from "./LogEntriesTable";
20
20
  export { default as MarkdownView, renderSafeMarkdown } from "./MarkdownView";
21
+ export { markdownInfoBlocks, renderMarkdownInfoBlock, scanMarkdownInfoBlock } from "./markdown-info-blocks";
21
22
  export { Pagination } from "./Pagination";
22
23
  export { default as PdfPreview } from "./PdfPreview";
23
24
  export { default as RangePicker } from "./RangePicker";
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/index.ts"],"sourcesContent":["export type {\n CalendarAttendee,\n CalendarDayBadge,\n CalendarEvent,\n CalendarEventColor,\n CalendarEventRenderContext,\n CalendarEventTimeChange,\n CalendarLabels,\n CalendarProps,\n CalendarRecurrence,\n CalendarResource,\n CalendarView,\n} from \"./Calendar\";\nexport { default as Calendar } from \"./Calendar\";\n\nexport type { ChartKind, ChartLabels, ChartProps, ChartRenderOptions } from \"./Chart\";\nexport { default as Chart } from \"./Chart\";\nexport type { ChartExplorerColumn, ChartExplorerProps } from \"./ChartExplorer\";\nexport { ChartExplorer } from \"./ChartExplorer\";\nexport type { ChartExplorerControlsProps } from \"./ChartExplorerControls\";\nexport { ChartExplorerControls } from \"./ChartExplorerControls\";\nexport { ChartFilterControls, type ChartFilterControlsProps } from \"./ChartFilterControls\";\nexport { ChartSnapshotView } from \"./ChartSnapshotView\";\nexport type { CodeDisplayLanguage, CodeDisplayProps } from \"./CodeDisplay\";\nexport { default as CodeDisplay } from \"./CodeDisplay\";\nexport { type ChartCursor, createChartCursor } from \"./chart-cursor\";\nexport type {\n ChartExplorerCharts,\n ChartExplorerController,\n ChartExplorerData,\n ChartExplorerOptions,\n ChartExplorerRequest,\n ChartExplorerRow,\n ChartExplorerSnapshot,\n} from \"./chart-explorer\";\nexport { createChartExplorer } from \"./chart-explorer\";\nexport type { ChartDatumRef, ChartSelection, ChartTooltip, ChartTooltipFormatter } from \"./chart-inspection\";\nexport type { ChartSnapshot } from \"./chart-snapshot\";\nexport { prepareChartSnapshot } from \"./chart-snapshot\";\nexport type {\n StateTimelineChartOptions,\n StateTimelineDomain,\n StateTimelineInterval,\n StateTimelineRow,\n StateTimelineState,\n} from \"./chart-state-timeline\";\nexport { type CollectionSelection, createCollectionSelection, type SelectionModifiers } from \"./collection-selection\";\nexport type {\n DataTableColumn,\n DataTableControlsProps,\n DataTableFooter,\n DataTableHeaderProps,\n DataTablePanelFooterProps,\n DataTablePanelProps,\n DataTableProps,\n DataTableRenderCell,\n DataTableRenderHeader,\n DataTableSort,\n} from \"./DataTable\";\nexport { default as DataTable } from \"./DataTable\";\nexport type { DocCodeHighlighter, DocCodeProps, DocConcept, DocNoteVariant, DocRow } from \"./Docs\";\nexport { DocCode, DocConceptGrid, DocInlineCode, DocLead, DocNote, DocPage, DocRows, DocSection } from \"./Docs\";\nexport { FileBrowserPanel, type FileBrowserPanelProps, type FileSource, openFileBrowser } from \"./FileBrowser\";\nexport { FileGrid, type FileGridProps } from \"./FileGrid\";\nexport { default as FileTree, type FileTreeActions, type FileTreeEntry, type FileTreeProps } from \"./FileTree\";\nexport {\n canPreviewFile,\n default as FileView,\n type FileViewContent,\n type FileViewFile,\n type FileViewPreviewKind,\n type FileViewProps,\n type FileViewRenderer,\n type FileViewRendererProps,\n formatFileViewSize,\n getFileViewPreviewKind,\n} from \"./FileView\";\nexport type { LightboxImage } from \"./Lightbox\";\nexport { default as Lightbox } from \"./Lightbox\";\nexport type { LogTableEntry } from \"./LogEntriesTable\";\nexport { default as LogEntriesTable } from \"./LogEntriesTable\";\nexport { default as MarkdownView, type MarkdownRenderOptions, type MarkdownViewProps, renderSafeMarkdown } from \"./MarkdownView\";\nexport { Pagination, type PaginationProps } from \"./Pagination\";\nexport type { PdfPreviewProps, PdfPreviewRequest } from \"./PdfPreview\";\nexport { default as PdfPreview } from \"./PdfPreview\";\nexport type { RangeOption, RangePickerProps } from \"./RangePicker\";\nexport { default as RangePicker } from \"./RangePicker\";\nexport type { StructuredDataPreviewMode, StructuredDataPreviewProps, StructuredDataValue } from \"./StructuredDataPreview\";\nexport { default as StructuredDataPreview, isStructuredDataValue } from \"./StructuredDataPreview\";\nexport type { ZoomPanAction, ZoomPanFullscreen, ZoomPanViewportProps } from \"./ZoomPanViewport\";\nexport { ZoomPanViewport } from \"./ZoomPanViewport\";\n"],"mappings":"AAaA,SAAS,OAAO,IAAI,QAAQ,QAAQ,YAAY;AAGhD,SAAS,OAAO,IAAI,KAAK,QAAQ,SAAS;AAE1C,SAAS,aAAa,QAAQ,iBAAiB;AAE/C,SAAS,qBAAqB,QAAQ,yBAAyB;AAC/D,SAAS,mBAAmB,QAAuC,uBAAuB;AAC1F,SAAS,iBAAiB,QAAQ,qBAAqB;AAEvD,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AACtD,SAA2B,iBAAiB,QAAQ,gBAAgB;AAUpE,SAAS,mBAAmB,QAAQ,kBAAkB;AAGtD,SAAS,oBAAoB,QAAQ,kBAAkB;AAQvD,SAAmC,yBAAyB,QAAiC,wBAAwB;AAarH,SAAS,OAAO,IAAI,SAAS,QAAQ,aAAa;AAElD,SAAS,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,QAAQ,QAAQ;AAC/G,SAAS,gBAAgB,EAA+C,eAAe,QAAQ,eAAe;AAC9G,SAAS,QAAQ,QAA4B,YAAY;AACzD,SAAS,OAAO,IAAI,QAAQ,QAAsE,YAAY;AAC9G,SACE,cAAc,EACd,OAAO,IAAI,QAAQ,EAOnB,kBAAkB,EAClB,sBAAsB,QACjB,YAAY;AAEnB,SAAS,OAAO,IAAI,QAAQ,QAAQ,YAAY;AAEhD,SAAS,OAAO,IAAI,eAAe,QAAQ,mBAAmB;AAC9D,SAAS,OAAO,IAAI,YAAY,EAAsD,kBAAkB,QAAQ,gBAAgB;AAChI,SAAS,UAAU,QAA8B,cAAc;AAE/D,SAAS,OAAO,IAAI,UAAU,QAAQ,cAAc;AAEpD,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAEtD,SAAS,OAAO,IAAI,qBAAqB,EAAE,qBAAqB,QAAQ,yBAAyB;AAEjG,SAAS,eAAe,QAAQ,mBAAmB","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/index.ts"],"sourcesContent":["export type {\n CalendarAttendee,\n CalendarDayBadge,\n CalendarEvent,\n CalendarEventColor,\n CalendarEventRenderContext,\n CalendarEventTimeChange,\n CalendarLabels,\n CalendarProps,\n CalendarRecurrence,\n CalendarResource,\n CalendarView,\n} from \"./Calendar\";\nexport { default as Calendar } from \"./Calendar\";\n\nexport type { ChartKind, ChartLabels, ChartProps, ChartRenderOptions } from \"./Chart\";\nexport { default as Chart } from \"./Chart\";\nexport type { ChartExplorerColumn, ChartExplorerProps } from \"./ChartExplorer\";\nexport { ChartExplorer } from \"./ChartExplorer\";\nexport type { ChartExplorerControlsProps } from \"./ChartExplorerControls\";\nexport { ChartExplorerControls } from \"./ChartExplorerControls\";\nexport { ChartFilterControls, type ChartFilterControlsProps } from \"./ChartFilterControls\";\nexport { ChartSnapshotView } from \"./ChartSnapshotView\";\nexport type { CodeDisplayLanguage, CodeDisplayProps } from \"./CodeDisplay\";\nexport { default as CodeDisplay } from \"./CodeDisplay\";\nexport { type ChartCursor, createChartCursor } from \"./chart-cursor\";\nexport type {\n ChartExplorerCharts,\n ChartExplorerController,\n ChartExplorerData,\n ChartExplorerOptions,\n ChartExplorerRequest,\n ChartExplorerRow,\n ChartExplorerSnapshot,\n} from \"./chart-explorer\";\nexport { createChartExplorer } from \"./chart-explorer\";\nexport type { ChartDatumRef, ChartSelection, ChartTooltip, ChartTooltipFormatter } from \"./chart-inspection\";\nexport type { ChartSnapshot } from \"./chart-snapshot\";\nexport { prepareChartSnapshot } from \"./chart-snapshot\";\nexport type {\n StateTimelineChartOptions,\n StateTimelineDomain,\n StateTimelineInterval,\n StateTimelineRow,\n StateTimelineState,\n} from \"./chart-state-timeline\";\nexport { type CollectionSelection, createCollectionSelection, type SelectionModifiers } from \"./collection-selection\";\nexport type {\n DataTableColumn,\n DataTableControlsProps,\n DataTableFooter,\n DataTableHeaderProps,\n DataTablePanelFooterProps,\n DataTablePanelProps,\n DataTableProps,\n DataTableRenderCell,\n DataTableRenderHeader,\n DataTableSort,\n} from \"./DataTable\";\nexport { default as DataTable } from \"./DataTable\";\nexport type { DocCodeHighlighter, DocCodeProps, DocConcept, DocNoteVariant, DocRow } from \"./Docs\";\nexport { DocCode, DocConceptGrid, DocInlineCode, DocLead, DocNote, DocPage, DocRows, DocSection } from \"./Docs\";\nexport { FileBrowserPanel, type FileBrowserPanelProps, type FileSource, openFileBrowser } from \"./FileBrowser\";\nexport { FileGrid, type FileGridProps } from \"./FileGrid\";\nexport { default as FileTree, type FileTreeActions, type FileTreeEntry, type FileTreeProps } from \"./FileTree\";\nexport {\n canPreviewFile,\n default as FileView,\n type FileViewContent,\n type FileViewFile,\n type FileViewPreviewKind,\n type FileViewProps,\n type FileViewRenderer,\n type FileViewRendererProps,\n formatFileViewSize,\n getFileViewPreviewKind,\n} from \"./FileView\";\nexport type { LightboxImage } from \"./Lightbox\";\nexport { default as Lightbox } from \"./Lightbox\";\nexport type { LogTableEntry } from \"./LogEntriesTable\";\nexport { default as LogEntriesTable } from \"./LogEntriesTable\";\nexport { default as MarkdownView, type MarkdownRenderOptions, type MarkdownViewProps, renderSafeMarkdown } from \"./MarkdownView\";\nexport {\n type MarkdownInfoBlock,\n type MarkdownInfoBlockRenderInput,\n type MarkdownInfoBlockType,\n markdownInfoBlocks,\n renderMarkdownInfoBlock,\n scanMarkdownInfoBlock,\n} from \"./markdown-info-blocks\";\nexport { Pagination, type PaginationProps } from \"./Pagination\";\nexport type { PdfPreviewProps, PdfPreviewRequest } from \"./PdfPreview\";\nexport { default as PdfPreview } from \"./PdfPreview\";\nexport type { RangeOption, RangePickerProps } from \"./RangePicker\";\nexport { default as RangePicker } from \"./RangePicker\";\nexport type { StructuredDataPreviewMode, StructuredDataPreviewProps, StructuredDataValue } from \"./StructuredDataPreview\";\nexport { default as StructuredDataPreview, isStructuredDataValue } from \"./StructuredDataPreview\";\nexport type { ZoomPanAction, ZoomPanFullscreen, ZoomPanViewportProps } from \"./ZoomPanViewport\";\nexport { ZoomPanViewport } from \"./ZoomPanViewport\";\n"],"mappings":"AAaA,SAAS,OAAO,IAAI,QAAQ,QAAQ,YAAY;AAGhD,SAAS,OAAO,IAAI,KAAK,QAAQ,SAAS;AAE1C,SAAS,aAAa,QAAQ,iBAAiB;AAE/C,SAAS,qBAAqB,QAAQ,yBAAyB;AAC/D,SAAS,mBAAmB,QAAuC,uBAAuB;AAC1F,SAAS,iBAAiB,QAAQ,qBAAqB;AAEvD,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AACtD,SAA2B,iBAAiB,QAAQ,gBAAgB;AAUpE,SAAS,mBAAmB,QAAQ,kBAAkB;AAGtD,SAAS,oBAAoB,QAAQ,kBAAkB;AAQvD,SAAmC,yBAAyB,QAAiC,wBAAwB;AAarH,SAAS,OAAO,IAAI,SAAS,QAAQ,aAAa;AAElD,SAAS,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,QAAQ,QAAQ;AAC/G,SAAS,gBAAgB,EAA+C,eAAe,QAAQ,eAAe;AAC9G,SAAS,QAAQ,QAA4B,YAAY;AACzD,SAAS,OAAO,IAAI,QAAQ,QAAsE,YAAY;AAC9G,SACE,cAAc,EACd,OAAO,IAAI,QAAQ,EAOnB,kBAAkB,EAClB,sBAAsB,QACjB,YAAY;AAEnB,SAAS,OAAO,IAAI,QAAQ,QAAQ,YAAY;AAEhD,SAAS,OAAO,IAAI,eAAe,QAAQ,mBAAmB;AAC9D,SAAS,OAAO,IAAI,YAAY,EAAsD,kBAAkB,QAAQ,gBAAgB;AAChI,SAIE,kBAAkB,EAClB,uBAAuB,EACvB,qBAAqB,QAChB,wBAAwB;AAC/B,SAAS,UAAU,QAA8B,cAAc;AAE/D,SAAS,OAAO,IAAI,UAAU,QAAQ,cAAc;AAEpD,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAEtD,SAAS,OAAO,IAAI,qBAAqB,EAAE,qBAAqB,QAAQ,yBAAyB;AAEjG,SAAS,eAAe,QAAQ,mBAAmB","ignoreList":[]}