@k2b/ui 0.30.0 → 0.31.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 +1 -1
- package/dist/browser/actions/Toolbar.js +2 -0
- package/dist/browser/actions/Toolbar.js.map +1 -1
- package/dist/browser/chat/ChatDecision.js +28 -2
- package/dist/browser/chat/ChatDecision.js.map +1 -1
- package/dist/browser/content/MapAttribution.js +27 -0
- package/dist/browser/content/MapAttribution.js.map +1 -0
- package/dist/browser/content/MapView.js +553 -0
- package/dist/browser/content/MapView.js.map +1 -0
- package/dist/browser/content/MapViewFrame.js +395 -0
- package/dist/browser/content/MapViewFrame.js.map +1 -0
- package/dist/browser/content/index.js +5 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/content/map-palette.js +39 -0
- package/dist/browser/content/map-palette.js.map +1 -0
- package/dist/browser/content/map-style.js +276 -0
- package/dist/browser/content/map-style.js.map +1 -0
- package/dist/browser/content/map-view-geometry.js +269 -0
- package/dist/browser/content/map-view-geometry.js.map +1 -0
- package/dist/browser/content/map-view-live.js +28 -0
- package/dist/browser/content/map-view-live.js.map +1 -0
- package/dist/browser/content/map-view-messages.js +53 -0
- package/dist/browser/content/map-view-messages.js.map +1 -0
- package/dist/browser/content/map-view-types.js +2 -0
- package/dist/browser/content/map-view-types.js.map +1 -0
- package/dist/browser/content/map-view-worker.js +10 -0
- package/dist/browser/feedback/dialog-core.js +19 -0
- package/dist/browser/feedback/dialog-core.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +17 -9
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/app-workspace-controller.js +114 -8
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/layout/app-workspace-width.js +26 -0
- package/dist/browser/layout/app-workspace-width.js.map +1 -0
- package/dist/browser/layout/index.js +1 -1
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/licenses/maplibre-gl.txt +116 -0
- package/dist/ssr/actions/Toolbar.js +2 -0
- package/dist/ssr/actions/Toolbar.js.map +1 -1
- package/dist/ssr/chat/ChatDecision.js +11 -0
- package/dist/ssr/chat/ChatDecision.js.map +1 -1
- package/dist/ssr/content/MapAttribution.js +19 -0
- package/dist/ssr/content/MapAttribution.js.map +1 -0
- package/dist/ssr/content/MapView.js +474 -0
- package/dist/ssr/content/MapView.js.map +1 -0
- package/dist/ssr/content/MapViewFrame.js +193 -0
- package/dist/ssr/content/MapViewFrame.js.map +1 -0
- package/dist/ssr/content/index.js +5 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/content/map-palette.js +39 -0
- package/dist/ssr/content/map-palette.js.map +1 -0
- package/dist/ssr/content/map-style.js +276 -0
- package/dist/ssr/content/map-style.js.map +1 -0
- package/dist/ssr/content/map-view-geometry.js +269 -0
- package/dist/ssr/content/map-view-geometry.js.map +1 -0
- package/dist/ssr/content/map-view-live.js +1 -0
- package/dist/ssr/content/map-view-messages.js +53 -0
- package/dist/ssr/content/map-view-messages.js.map +1 -0
- package/dist/ssr/content/map-view-types.js +2 -0
- package/dist/ssr/content/map-view-types.js.map +1 -0
- package/dist/ssr/feedback/dialog-core.js +19 -0
- package/dist/ssr/feedback/dialog-core.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +17 -9
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/app-workspace-controller.js +114 -8
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/layout/app-workspace-width.js +26 -0
- package/dist/ssr/layout/app-workspace-width.js.map +1 -0
- package/dist/ssr/layout/index.js +1 -1
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/content/MapAttribution.d.ts +6 -0
- package/dist/types/content/MapView.d.ts +5 -0
- package/dist/types/content/MapViewFrame.d.ts +31 -0
- package/dist/types/content/index.d.ts +6 -0
- package/dist/types/content/map-palette.d.ts +58 -0
- package/dist/types/content/map-style.d.ts +29 -0
- package/dist/types/content/map-view-geometry.d.ts +55 -0
- package/dist/types/content/map-view-live.d.ts +2 -0
- package/dist/types/content/map-view-messages.d.ts +21 -0
- package/dist/types/content/map-view-types.d.ts +61 -0
- package/dist/types/feedback/dialog-core.d.ts +1 -0
- package/dist/types/layout/AppWorkspace.d.ts +7 -3
- package/dist/types/layout/app-workspace-width.d.ts +13 -0
- package/dist/types/layout/index.d.ts +2 -2
- package/map-glyphs/IBM Plex Sans Medium/0-255.pbf +0 -0
- package/map-glyphs/IBM Plex Sans Medium/1024-1279.pbf +0 -0
- package/map-glyphs/IBM Plex Sans Medium/256-511.pbf +0 -0
- package/map-glyphs/IBM Plex Sans Medium/512-767.pbf +0 -0
- package/map-glyphs/IBM Plex Sans Medium/768-1023.pbf +0 -0
- package/map-glyphs/IBM Plex Sans Medium/7680-7935.pbf +0 -0
- package/map-glyphs/IBM Plex Sans Medium/8192-8447.pbf +0 -0
- package/map-glyphs/IBM Plex Sans Medium/8448-8703.pbf +0 -0
- package/map-glyphs/IBM Plex Sans Medium/8704-8959.pbf +0 -0
- package/map-glyphs/OFL.txt +93 -0
- package/package.json +10 -5
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** A width that follows the workspace's own border-box width: clamp(min, share × workspace width + offset, max), in px. */
|
|
2
|
+
|
|
3
|
+
export const isAppWorkspaceWidthShare = value => {
|
|
4
|
+
if (!value || typeof value !== "object" || !("share" in value) || !("min" in value) || !("max" in value)) return false;
|
|
5
|
+
return typeof value.share === "number" && value.share > 0 && value.share < 1 && Number.isFinite(value.min) && Number.isFinite(value.max) && typeof value.min === "number" && typeof value.max === "number" && value.min <= value.max && (!("offset" in value) || value.offset === undefined || typeof value.offset === "number" && Number.isFinite(value.offset));
|
|
6
|
+
};
|
|
7
|
+
export const appWorkspaceWidthToken = value => typeof value === "number" ? String(value) : `share:${value.share},${value.offset ?? 0},${value.min},${value.max}`;
|
|
8
|
+
export const readAppWorkspaceWidth = token => {
|
|
9
|
+
if (!token) return undefined;
|
|
10
|
+
if (!token.startsWith("share:")) {
|
|
11
|
+
const value = Number(token);
|
|
12
|
+
return Number.isFinite(value) ? value : undefined;
|
|
13
|
+
}
|
|
14
|
+
const [share, offset, min, max] = token.slice(6).split(",").map(Number);
|
|
15
|
+
const value = {
|
|
16
|
+
share,
|
|
17
|
+
offset,
|
|
18
|
+
min,
|
|
19
|
+
max
|
|
20
|
+
};
|
|
21
|
+
return isAppWorkspaceWidthShare(value) ? value : undefined;
|
|
22
|
+
};
|
|
23
|
+
export const resolveAppWorkspaceWidth = (value, workspaceWidth) => typeof value === "number" ? value : Math.min(value.max, Math.max(value.min, value.share * workspaceWidth + (value.offset ?? 0)));
|
|
24
|
+
export const appWorkspaceWidthCss = (value, width) => typeof value === "number" ? `${value}px` : `clamp(${value.min}px, ${value.share} * ${width} + ${value.offset ?? 0}px, ${value.max}px)`;
|
|
25
|
+
export const appWorkspaceInverseWidthCss = (value, width) => `clamp(${value.min}px, (${value.share} * (${width} + var(--k2b-workspace-sidebar-space) + 2px - 20rem) + ${value.offset ?? 0}px) / ${1 - value.share}, ${value.max}px)`;
|
|
26
|
+
//# sourceMappingURL=app-workspace-width.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["layout/app-workspace-width.ts"],"sourcesContent":["/** A width that follows the workspace's own border-box width: clamp(min, share × workspace width + offset, max), in px. */\nexport type AppWorkspaceWidthShare = { share: number; offset?: number; min: number; max: number };\n\nexport const isAppWorkspaceWidthShare = (value: unknown): value is AppWorkspaceWidthShare => {\n if (!value || typeof value !== \"object\" || !(\"share\" in value) || !(\"min\" in value) || !(\"max\" in value)) return false;\n return (\n typeof value.share === \"number\" &&\n value.share > 0 &&\n value.share < 1 &&\n Number.isFinite(value.min) &&\n Number.isFinite(value.max) &&\n typeof value.min === \"number\" &&\n typeof value.max === \"number\" &&\n value.min <= value.max &&\n (!(\"offset\" in value) || value.offset === undefined || (typeof value.offset === \"number\" && Number.isFinite(value.offset)))\n );\n};\n\nexport const appWorkspaceWidthToken = (value: number | AppWorkspaceWidthShare): string =>\n typeof value === \"number\" ? String(value) : `share:${value.share},${value.offset ?? 0},${value.min},${value.max}`;\n\nexport const readAppWorkspaceWidth = (token: string | undefined): number | AppWorkspaceWidthShare | undefined => {\n if (!token) return undefined;\n if (!token.startsWith(\"share:\")) {\n const value = Number(token);\n return Number.isFinite(value) ? value : undefined;\n }\n const [share, offset, min, max] = token.slice(6).split(\",\").map(Number);\n const value = { share, offset, min, max };\n return isAppWorkspaceWidthShare(value) ? value : undefined;\n};\n\nexport const resolveAppWorkspaceWidth = (value: number | AppWorkspaceWidthShare, workspaceWidth: number): number =>\n typeof value === \"number\" ? value : Math.min(value.max, Math.max(value.min, value.share * workspaceWidth + (value.offset ?? 0)));\n\nexport const appWorkspaceWidthCss = (value: number | AppWorkspaceWidthShare, width: string): string =>\n typeof value === \"number\" ? `${value}px` : `clamp(${value.min}px, ${value.share} * ${width} + ${value.offset ?? 0}px, ${value.max}px)`;\n\nexport const appWorkspaceInverseWidthCss = (value: AppWorkspaceWidthShare, width: string): string =>\n `clamp(${value.min}px, (${value.share} * (${width} + var(--k2b-workspace-sidebar-space) + 2px - 20rem) + ${value.offset ?? 0}px) / ${1 - value.share}, ${value.max}px)`;\n"],"mappings":"AAAA;;AAGA,OAAO,MAAM,wBAAwB,GAAI,KAAc,IAAsC;EAC3F,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,EAAE,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,KAAK,CAAC,EAAE,OAAO,KAAK;EACtH,OACE,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAC/B,KAAK,CAAC,KAAK,GAAG,CAAC,IACf,KAAK,CAAC,KAAK,GAAG,CAAC,IACf,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAC1B,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAC1B,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,IAC7B,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,IAC7B,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,KACrB,EAAE,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAK,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAE,CAAC;AAE/H,CAAC;AAED,OAAO,MAAM,sBAAsB,GAAI,KAAsC,IAC3E,OAAO,KAAK,KAAK,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,SAAS,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,EAAE;AAEnH,OAAO,MAAM,qBAAqB,GAAI,KAAyB,IAAkD;EAC/G,IAAI,CAAC,KAAK,EAAE,OAAO,SAAS;EAC5B,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,SAAS;EACnD;EACA,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;EACvE,MAAM,KAAK,GAAG;IAAE,KAAK;IAAE,MAAM;IAAE,GAAG;IAAE;EAAI,CAAC;EACzC,OAAO,wBAAwB,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,SAAS;AAC5D,CAAC;AAED,OAAO,MAAM,wBAAwB,GAAG,CAAC,KAAsC,EAAE,cAAsB,KACrG,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,GAAG,cAAc,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;AAElI,OAAO,MAAM,oBAAoB,GAAG,CAAC,KAAsC,EAAE,KAAa,KACxF,OAAO,KAAK,KAAK,QAAQ,GAAG,GAAG,KAAK,IAAI,GAAG,SAAS,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,KAAK,MAAM,KAAK,MAAM,KAAK,CAAC,MAAM,IAAI,CAAC,OAAO,KAAK,CAAC,GAAG,KAAK;AAExI,OAAO,MAAM,2BAA2B,GAAG,CAAC,KAA6B,EAAE,KAAa,KACtF,SAAS,KAAK,CAAC,GAAG,QAAQ,KAAK,CAAC,KAAK,OAAO,KAAK,0DAA0D,KAAK,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,GAAG,KAAK","ignoreList":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { default as AppOverview } from "./AppOverview";
|
|
2
|
-
export { default as AppWorkspace } from "./AppWorkspace";
|
|
2
|
+
export { appWorkspaceDetailElementId, default as AppWorkspace } from "./AppWorkspace";
|
|
3
3
|
export { watchAppHostWidth } from "./app-host-width";
|
|
4
4
|
export { installAppWorkspaceController, parkWorkspaceDetailDrawers } from "./app-workspace-controller";
|
|
5
5
|
export { APP_WORKSPACE_DETAIL_DEFAULT, APP_WORKSPACE_DETAIL_MAX, APP_WORKSPACE_DETAIL_MIN, APP_WORKSPACE_DRAWER_DEFAULT, APP_WORKSPACE_DRAWER_MAX, APP_WORKSPACE_DRAWER_MIN, APP_WORKSPACE_MAIN_MIN, APP_WORKSPACE_MAIN_MIN_HEIGHT, APP_WORKSPACE_PANE_DEFAULT, APP_WORKSPACE_PANE_MAX, APP_WORKSPACE_PANE_MIN, APP_WORKSPACE_SIDEBAR_COLLAPSE_THRESHOLD, APP_WORKSPACE_SIDEBAR_COLLAPSED, APP_WORKSPACE_SIDEBAR_DEFAULT, APP_WORKSPACE_SIDEBAR_MAX, APP_WORKSPACE_SIDEBAR_MIN, appWorkspaceLayoutStyle, appWorkspacePanelVariable, appWorkspaceResizeLimits, normalizeAppWorkspaceLayoutState, parseAppWorkspaceLayoutState, resolveAppWorkspaceSidebarWidth, safeAppWorkspacePanelId, serializeAppWorkspaceLayoutState, shouldCollapseAppWorkspaceSidebar } from "./app-workspace-state";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["layout/index.ts"],"sourcesContent":["export type {\n AppOverviewCardsProps,\n AppOverviewEmptyStateProps,\n AppOverviewPanelProps,\n AppOverviewProps,\n} from \"./AppOverview\";\nexport { default as AppOverview } from \"./AppOverview\";\nexport type {\n AppWorkspaceBottomDrawerHeight,\n AppWorkspaceBottomDrawerProps,\n AppWorkspaceContentProps,\n AppWorkspaceDetailProps,\n AppWorkspaceDetailWidth,\n AppWorkspaceHeadProps,\n AppWorkspaceMainPaneProps,\n AppWorkspaceMainProps,\n AppWorkspaceNavTreeItemProps,\n AppWorkspaceNavTreeMove,\n AppWorkspaceNavTreeProps,\n AppWorkspaceProps,\n AppWorkspaceSidebarAccessoryVisibility,\n AppWorkspaceSidebarBodyProps,\n AppWorkspaceSidebarIconActionProps,\n AppWorkspaceSidebarIconActionTone,\n AppWorkspaceSidebarIconGridProps,\n AppWorkspaceSidebarItemActionProps,\n AppWorkspaceSidebarItemActionsProps,\n AppWorkspaceSidebarItemIconProps,\n AppWorkspaceSidebarItemLabelProps,\n AppWorkspaceSidebarItemMetaProps,\n AppWorkspaceSidebarItemProps,\n AppWorkspaceSidebarItemStatusProps,\n AppWorkspaceSidebarItemTone,\n AppWorkspaceSidebarProps,\n AppWorkspaceSidebarSectionProps,\n AppWorkspaceSidebarVisibility,\n} from \"./AppWorkspace\";\nexport { default as AppWorkspace } from \"./AppWorkspace\";\nexport { watchAppHostWidth } from \"./app-host-width\";\nexport type { AppWorkspaceControllerOptions } from \"./app-workspace-controller\";\nexport { installAppWorkspaceController, parkWorkspaceDetailDrawers } from \"./app-workspace-controller\";\nexport type {\n AppWorkspaceLayoutState,\n AppWorkspaceResizeKind,\n} from \"./app-workspace-state\";\nexport {\n APP_WORKSPACE_DETAIL_DEFAULT,\n APP_WORKSPACE_DETAIL_MAX,\n APP_WORKSPACE_DETAIL_MIN,\n APP_WORKSPACE_DRAWER_DEFAULT,\n APP_WORKSPACE_DRAWER_MAX,\n APP_WORKSPACE_DRAWER_MIN,\n APP_WORKSPACE_MAIN_MIN,\n APP_WORKSPACE_MAIN_MIN_HEIGHT,\n APP_WORKSPACE_PANE_DEFAULT,\n APP_WORKSPACE_PANE_MAX,\n APP_WORKSPACE_PANE_MIN,\n APP_WORKSPACE_SIDEBAR_COLLAPSE_THRESHOLD,\n APP_WORKSPACE_SIDEBAR_COLLAPSED,\n APP_WORKSPACE_SIDEBAR_DEFAULT,\n APP_WORKSPACE_SIDEBAR_MAX,\n APP_WORKSPACE_SIDEBAR_MIN,\n appWorkspaceLayoutStyle,\n appWorkspacePanelVariable,\n appWorkspaceResizeLimits,\n normalizeAppWorkspaceLayoutState,\n parseAppWorkspaceLayoutState,\n resolveAppWorkspaceSidebarWidth,\n safeAppWorkspacePanelId,\n serializeAppWorkspaceLayoutState,\n shouldCollapseAppWorkspaceSidebar,\n} from \"./app-workspace-state\";\nexport { type BottomSheetProps, bottomSheetAdaptiveOptions, bottomSheetOptions, default as BottomSheet } from \"./BottomSheet\";\nexport type { DataPanelProps } from \"./DataPanel\";\nexport { DataPanel } from \"./DataPanel\";\nexport type {\n DetailPanelActionButtonProps,\n DetailPanelActionLinkProps,\n DetailPanelActionProps,\n DetailPanelActionSecondary,\n DetailPanelBodyProps,\n DetailPanelGroupProps,\n DetailPanelHeaderProps,\n DetailPanelProps,\n DetailPanelSectionProps,\n DetailPanelSummaryProps,\n DetailPanelTone,\n} from \"./DetailPanel\";\nexport { default as DetailPanel } from \"./DetailPanel\";\nexport type { DiscussionComposerProps, DiscussionItemProps, DiscussionListProps, DiscussionProps } from \"./Discussion\";\nexport { default as Discussion } from \"./Discussion\";\nexport type {\n FloatingWindowClose,\n FloatingWindowProps,\n OpenFloatingWindowOptions,\n} from \"./FloatingWindow\";\nexport {\n default as FloatingWindow,\n type FloatingWindowRect,\n fitFloatingWindowRect,\n openFloatingWindow,\n} from \"./FloatingWindow\";\nexport type { MobileShellHeaderProps, MobileShellProps } from \"./MobileShell\";\nexport { default as MobileShell, observeMobileShell } from \"./MobileShell\";\nexport { default as Navigation, type NavigationProps } from \"./Navigation\";\nexport {\n createNavigation,\n findNavigationItem,\n type NavigationController,\n type NavigationItem,\n type NavigationOptions,\n type NavigationStatus,\n} from \"./navigation-model\";\nexport type { PageTitleProps, PageTrailLink, PageTrailState } from \"./PageTitle\";\nexport { followPageTrail, PAGE_TRAIL_EVENT, PageTitle, PageTrailProvider, readPageTrail, setPageTrail, usePageTrail } from \"./PageTitle\";\nexport type {\n PanelDialogBodyProps,\n PanelDialogFooterProps,\n PanelDialogHeaderProps,\n PanelDialogProps,\n PanelDialogSectionProps,\n PanelDialogSurface,\n PanelDialogTabOption,\n PanelDialogTabsProps,\n} from \"./PanelDialog\";\nexport {\n confirmDiscardIfDirty,\n default as PanelDialog,\n panelDialogFixedOptions,\n panelDialogFixedPanelClass,\n panelDialogOptions,\n panelDialogPanelClass,\n panelDialogWideOptions,\n panelDialogWidePanelClass,\n panelDialogWorkspaceOptions,\n panelDialogWorkspacePanelClass,\n} from \"./PanelDialog\";\nexport type { PanelHeaderProps } from \"./PanelHeader\";\nexport { PanelHeader } from \"./PanelHeader\";\nexport type { PanesItem, PanesProps } from \"./Panes\";\nexport { default as Panes } from \"./Panes\";\nexport type { PullToRefreshProps, PullToRefreshState } from \"./PullToRefresh\";\nexport { default as PullToRefresh } from \"./PullToRefresh\";\nexport { installPageTitleController } from \"./page-title-controller\";\nexport type {\n AddPanesItemOptions,\n PanesDirection,\n PanesGroup,\n PanesIntent,\n PanesLayout,\n PanesNode,\n PanesPath,\n PanesPathSegment,\n PanesSide,\n PanesSplit,\n} from \"./panes-layout\";\nexport {\n activatePanesItem,\n addPanesItem,\n applyPanesIntent,\n createPanesLayout,\n isPanesItemVisible,\n PANES_LAYOUT_VERSION,\n parsePanesLayout,\n reconcilePanesLayout,\n removePanesItem,\n resizePanesSplit,\n} from \"./panes-layout\";\nexport { default as ResizeSeparator, type ResizeSeparatorProps } from \"./ResizeSeparator\";\nexport { attachResizeSeparator, type ResizeSeparatorOptions } from \"./resize-separator\";\nexport type { ScrollAreaProps } from \"./ScrollArea\";\nexport { default as ScrollArea } from \"./ScrollArea\";\nexport type {\n SettingsFieldControlProps,\n SettingsFieldProps,\n SettingsGroupActionProps,\n SettingsGroupProps,\n SettingsPageProps,\n SettingsPanelFooterProps,\n SettingsSaveBarProps,\n SettingsSectionProps,\n} from \"./Settings\";\nexport {\n readSettingsError,\n SettingsField,\n SettingsGroup,\n SettingsPage,\n SettingsPanelFooter,\n SettingsSaveBar,\n SettingsSection,\n sameSettingValue,\n} from \"./Settings\";\nexport type {\n SettingsCollectionActionProps,\n SettingsCollectionItemActionsProps,\n SettingsCollectionItemProps,\n SettingsCollectionItemReorderProps,\n SettingsCollectionItemStatusProps,\n SettingsCollectionProps,\n} from \"./SettingsCollection\";\nexport { default as SettingsCollection } from \"./SettingsCollection\";\nexport type {\n SettingsModalFooterProps,\n SettingsModalGroupProps,\n SettingsModalProps,\n SettingsModalTabProps,\n SettingsModalTabTone,\n} from \"./SettingsModal\";\nexport { default as SettingsModal } from \"./SettingsModal\";\nexport {\n APP_WORKSPACE_SWITCHER_SEARCH_FROM,\n type AppWorkspaceSidebarSwitcherProps,\n type AppWorkspaceSwitcherAction,\n type AppWorkspaceSwitcherOption,\n} from \"./SidebarSwitcher\";\nexport type { TabBarItem, TabBarProps } from \"./TabBar\";\nexport { default as TabBar } from \"./TabBar\";\nexport type { TableOfContentsItem, TableOfContentsProps } from \"./TableOfContents\";\nexport { TableOfContents } from \"./TableOfContents\";\n"],"mappings":"AAMA,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;
|
|
1
|
+
{"version":3,"names":[],"sources":["layout/index.ts"],"sourcesContent":["export type {\n AppOverviewCardsProps,\n AppOverviewEmptyStateProps,\n AppOverviewPanelProps,\n AppOverviewProps,\n} from \"./AppOverview\";\nexport { default as AppOverview } from \"./AppOverview\";\nexport type {\n AppWorkspaceBottomDrawerHeight,\n AppWorkspaceBottomDrawerProps,\n AppWorkspaceContentProps,\n AppWorkspaceDetailProps,\n AppWorkspaceDetailWidth,\n AppWorkspaceHeadProps,\n AppWorkspaceMainPaneProps,\n AppWorkspaceMainProps,\n AppWorkspaceNavTreeItemProps,\n AppWorkspaceNavTreeMove,\n AppWorkspaceNavTreeProps,\n AppWorkspaceProps,\n AppWorkspaceSidebarAccessoryVisibility,\n AppWorkspaceSidebarBodyProps,\n AppWorkspaceSidebarIconActionProps,\n AppWorkspaceSidebarIconActionTone,\n AppWorkspaceSidebarIconGridProps,\n AppWorkspaceSidebarItemActionProps,\n AppWorkspaceSidebarItemActionsProps,\n AppWorkspaceSidebarItemIconProps,\n AppWorkspaceSidebarItemLabelProps,\n AppWorkspaceSidebarItemMetaProps,\n AppWorkspaceSidebarItemProps,\n AppWorkspaceSidebarItemStatusProps,\n AppWorkspaceSidebarItemTone,\n AppWorkspaceSidebarProps,\n AppWorkspaceSidebarSectionProps,\n AppWorkspaceSidebarVisibility,\n AppWorkspaceWidthShare,\n} from \"./AppWorkspace\";\nexport { appWorkspaceDetailElementId, default as AppWorkspace } from \"./AppWorkspace\";\nexport { watchAppHostWidth } from \"./app-host-width\";\nexport type { AppWorkspaceControllerOptions } from \"./app-workspace-controller\";\nexport { installAppWorkspaceController, parkWorkspaceDetailDrawers } from \"./app-workspace-controller\";\nexport type {\n AppWorkspaceLayoutState,\n AppWorkspaceResizeKind,\n} from \"./app-workspace-state\";\nexport {\n APP_WORKSPACE_DETAIL_DEFAULT,\n APP_WORKSPACE_DETAIL_MAX,\n APP_WORKSPACE_DETAIL_MIN,\n APP_WORKSPACE_DRAWER_DEFAULT,\n APP_WORKSPACE_DRAWER_MAX,\n APP_WORKSPACE_DRAWER_MIN,\n APP_WORKSPACE_MAIN_MIN,\n APP_WORKSPACE_MAIN_MIN_HEIGHT,\n APP_WORKSPACE_PANE_DEFAULT,\n APP_WORKSPACE_PANE_MAX,\n APP_WORKSPACE_PANE_MIN,\n APP_WORKSPACE_SIDEBAR_COLLAPSE_THRESHOLD,\n APP_WORKSPACE_SIDEBAR_COLLAPSED,\n APP_WORKSPACE_SIDEBAR_DEFAULT,\n APP_WORKSPACE_SIDEBAR_MAX,\n APP_WORKSPACE_SIDEBAR_MIN,\n appWorkspaceLayoutStyle,\n appWorkspacePanelVariable,\n appWorkspaceResizeLimits,\n normalizeAppWorkspaceLayoutState,\n parseAppWorkspaceLayoutState,\n resolveAppWorkspaceSidebarWidth,\n safeAppWorkspacePanelId,\n serializeAppWorkspaceLayoutState,\n shouldCollapseAppWorkspaceSidebar,\n} from \"./app-workspace-state\";\nexport { type BottomSheetProps, bottomSheetAdaptiveOptions, bottomSheetOptions, default as BottomSheet } from \"./BottomSheet\";\nexport type { DataPanelProps } from \"./DataPanel\";\nexport { DataPanel } from \"./DataPanel\";\nexport type {\n DetailPanelActionButtonProps,\n DetailPanelActionLinkProps,\n DetailPanelActionProps,\n DetailPanelActionSecondary,\n DetailPanelBodyProps,\n DetailPanelGroupProps,\n DetailPanelHeaderProps,\n DetailPanelProps,\n DetailPanelSectionProps,\n DetailPanelSummaryProps,\n DetailPanelTone,\n} from \"./DetailPanel\";\nexport { default as DetailPanel } from \"./DetailPanel\";\nexport type { DiscussionComposerProps, DiscussionItemProps, DiscussionListProps, DiscussionProps } from \"./Discussion\";\nexport { default as Discussion } from \"./Discussion\";\nexport type {\n FloatingWindowClose,\n FloatingWindowProps,\n OpenFloatingWindowOptions,\n} from \"./FloatingWindow\";\nexport {\n default as FloatingWindow,\n type FloatingWindowRect,\n fitFloatingWindowRect,\n openFloatingWindow,\n} from \"./FloatingWindow\";\nexport type { MobileShellHeaderProps, MobileShellProps } from \"./MobileShell\";\nexport { default as MobileShell, observeMobileShell } from \"./MobileShell\";\nexport { default as Navigation, type NavigationProps } from \"./Navigation\";\nexport {\n createNavigation,\n findNavigationItem,\n type NavigationController,\n type NavigationItem,\n type NavigationOptions,\n type NavigationStatus,\n} from \"./navigation-model\";\nexport type { PageTitleProps, PageTrailLink, PageTrailState } from \"./PageTitle\";\nexport { followPageTrail, PAGE_TRAIL_EVENT, PageTitle, PageTrailProvider, readPageTrail, setPageTrail, usePageTrail } from \"./PageTitle\";\nexport type {\n PanelDialogBodyProps,\n PanelDialogFooterProps,\n PanelDialogHeaderProps,\n PanelDialogProps,\n PanelDialogSectionProps,\n PanelDialogSurface,\n PanelDialogTabOption,\n PanelDialogTabsProps,\n} from \"./PanelDialog\";\nexport {\n confirmDiscardIfDirty,\n default as PanelDialog,\n panelDialogFixedOptions,\n panelDialogFixedPanelClass,\n panelDialogOptions,\n panelDialogPanelClass,\n panelDialogWideOptions,\n panelDialogWidePanelClass,\n panelDialogWorkspaceOptions,\n panelDialogWorkspacePanelClass,\n} from \"./PanelDialog\";\nexport type { PanelHeaderProps } from \"./PanelHeader\";\nexport { PanelHeader } from \"./PanelHeader\";\nexport type { PanesItem, PanesProps } from \"./Panes\";\nexport { default as Panes } from \"./Panes\";\nexport type { PullToRefreshProps, PullToRefreshState } from \"./PullToRefresh\";\nexport { default as PullToRefresh } from \"./PullToRefresh\";\nexport { installPageTitleController } from \"./page-title-controller\";\nexport type {\n AddPanesItemOptions,\n PanesDirection,\n PanesGroup,\n PanesIntent,\n PanesLayout,\n PanesNode,\n PanesPath,\n PanesPathSegment,\n PanesSide,\n PanesSplit,\n} from \"./panes-layout\";\nexport {\n activatePanesItem,\n addPanesItem,\n applyPanesIntent,\n createPanesLayout,\n isPanesItemVisible,\n PANES_LAYOUT_VERSION,\n parsePanesLayout,\n reconcilePanesLayout,\n removePanesItem,\n resizePanesSplit,\n} from \"./panes-layout\";\nexport { default as ResizeSeparator, type ResizeSeparatorProps } from \"./ResizeSeparator\";\nexport { attachResizeSeparator, type ResizeSeparatorOptions } from \"./resize-separator\";\nexport type { ScrollAreaProps } from \"./ScrollArea\";\nexport { default as ScrollArea } from \"./ScrollArea\";\nexport type {\n SettingsFieldControlProps,\n SettingsFieldProps,\n SettingsGroupActionProps,\n SettingsGroupProps,\n SettingsPageProps,\n SettingsPanelFooterProps,\n SettingsSaveBarProps,\n SettingsSectionProps,\n} from \"./Settings\";\nexport {\n readSettingsError,\n SettingsField,\n SettingsGroup,\n SettingsPage,\n SettingsPanelFooter,\n SettingsSaveBar,\n SettingsSection,\n sameSettingValue,\n} from \"./Settings\";\nexport type {\n SettingsCollectionActionProps,\n SettingsCollectionItemActionsProps,\n SettingsCollectionItemProps,\n SettingsCollectionItemReorderProps,\n SettingsCollectionItemStatusProps,\n SettingsCollectionProps,\n} from \"./SettingsCollection\";\nexport { default as SettingsCollection } from \"./SettingsCollection\";\nexport type {\n SettingsModalFooterProps,\n SettingsModalGroupProps,\n SettingsModalProps,\n SettingsModalTabProps,\n SettingsModalTabTone,\n} from \"./SettingsModal\";\nexport { default as SettingsModal } from \"./SettingsModal\";\nexport {\n APP_WORKSPACE_SWITCHER_SEARCH_FROM,\n type AppWorkspaceSidebarSwitcherProps,\n type AppWorkspaceSwitcherAction,\n type AppWorkspaceSwitcherOption,\n} from \"./SidebarSwitcher\";\nexport type { TabBarItem, TabBarProps } from \"./TabBar\";\nexport { default as TabBar } from \"./TabBar\";\nexport type { TableOfContentsItem, TableOfContentsProps } from \"./TableOfContents\";\nexport { TableOfContents } from \"./TableOfContents\";\n"],"mappings":"AAMA,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAgCtD,SAAS,2BAA2B,EAAE,OAAO,IAAI,YAAY,QAAQ,gBAAgB;AACrF,SAAS,iBAAiB,QAAQ,kBAAkB;AAEpD,SAAS,6BAA6B,EAAE,0BAA0B,QAAQ,4BAA4B;AAKtG,SACE,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,6BAA6B,EAC7B,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,wCAAwC,EACxC,+BAA+B,EAC/B,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,wBAAwB,EACxB,gCAAgC,EAChC,4BAA4B,EAC5B,+BAA+B,EAC/B,uBAAuB,EACvB,gCAAgC,EAChC,iCAAiC,QAC5B,uBAAuB;AAC9B,SAAgC,0BAA0B,EAAE,kBAAkB,EAAE,OAAO,IAAI,WAAW,QAAQ,eAAe;AAE7H,SAAS,SAAS,QAAQ,aAAa;AAcvC,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAEtD,SAAS,OAAO,IAAI,UAAU,QAAQ,cAAc;AAMpD,SACE,OAAO,IAAI,cAAc,EAEzB,qBAAqB,EACrB,kBAAkB,QACb,kBAAkB;AAEzB,SAAS,OAAO,IAAI,WAAW,EAAE,kBAAkB,QAAQ,eAAe;AAC1E,SAAS,OAAO,IAAI,UAAU,QAA8B,cAAc;AAC1E,SACE,gBAAgB,EAChB,kBAAkB,QAKb,oBAAoB;AAE3B,SAAS,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,QAAQ,aAAa;AAWxI,SACE,qBAAqB,EACrB,OAAO,IAAI,WAAW,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,EAC3B,8BAA8B,QACzB,eAAe;AAEtB,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,OAAO,IAAI,KAAK,QAAQ,SAAS;AAE1C,SAAS,OAAO,IAAI,aAAa,QAAQ,iBAAiB;AAC1D,SAAS,0BAA0B,QAAQ,yBAAyB;AAapE,SACE,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,gBAAgB,QACX,gBAAgB;AACvB,SAAS,OAAO,IAAI,eAAe,QAAmC,mBAAmB;AACzF,SAAS,qBAAqB,QAAqC,oBAAoB;AAEvF,SAAS,OAAO,IAAI,UAAU,QAAQ,cAAc;AAWpD,SACE,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,gBAAgB,QACX,YAAY;AASnB,SAAS,OAAO,IAAI,kBAAkB,QAAQ,sBAAsB;AAQpE,SAAS,OAAO,IAAI,aAAa,QAAQ,iBAAiB;AAC1D,SACE,kCAAkC,QAI7B,mBAAmB;AAE1B,SAAS,OAAO,IAAI,MAAM,QAAQ,UAAU;AAE5C,SAAS,eAAe,QAAQ,mBAAmB","ignoreList":[]}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
Copyright (c) 2023, MapLibre contributors
|
|
2
|
+
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
6
|
+
are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
* Redistributions of source code must retain the above copyright notice,
|
|
9
|
+
this list of conditions and the following disclaimer.
|
|
10
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
11
|
+
this list of conditions and the following disclaimer in the documentation
|
|
12
|
+
and/or other materials provided with the distribution.
|
|
13
|
+
* Neither the name of MapLibre GL JS nor the names of its contributors
|
|
14
|
+
may be used to endorse or promote products derived from this software
|
|
15
|
+
without specific prior written permission.
|
|
16
|
+
|
|
17
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
18
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
19
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
20
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
21
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
22
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
23
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
24
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
25
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
26
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
27
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
-------------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
Contains code from mapbox-gl-js v1.13 and earlier
|
|
33
|
+
|
|
34
|
+
Version v1.13 of mapbox-gl-js and earlier are licensed under a BSD-3-Clause license
|
|
35
|
+
|
|
36
|
+
Copyright (c) 2020, Mapbox
|
|
37
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
38
|
+
are permitted provided that the following conditions are met:
|
|
39
|
+
|
|
40
|
+
* Redistributions of source code must retain the above copyright notice,
|
|
41
|
+
this list of conditions and the following disclaimer.
|
|
42
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
43
|
+
this list of conditions and the following disclaimer in the documentation
|
|
44
|
+
and/or other materials provided with the distribution.
|
|
45
|
+
* Neither the name of Mapbox GL JS nor the names of its contributors
|
|
46
|
+
may be used to endorse or promote products derived from this software
|
|
47
|
+
without specific prior written permission.
|
|
48
|
+
|
|
49
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
50
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
51
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
52
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
53
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
54
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
55
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
56
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
57
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
58
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
59
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
-------------------------------------------------------------------------------
|
|
63
|
+
|
|
64
|
+
Contains code from glfx.js
|
|
65
|
+
|
|
66
|
+
Copyright (C) 2011 by Evan Wallace
|
|
67
|
+
|
|
68
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
69
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
70
|
+
in the Software without restriction, including without limitation the rights
|
|
71
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
72
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
73
|
+
furnished to do so, subject to the following conditions:
|
|
74
|
+
|
|
75
|
+
The above copyright notice and this permission notice shall be included in
|
|
76
|
+
all copies or substantial portions of the Software.
|
|
77
|
+
|
|
78
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
79
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
80
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
81
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
82
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
83
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
84
|
+
THE SOFTWARE.
|
|
85
|
+
|
|
86
|
+
--------------------------------------------------------------------------------
|
|
87
|
+
|
|
88
|
+
Contains a portion of d3-color https://github.com/d3/d3-color
|
|
89
|
+
|
|
90
|
+
Copyright 2010-2016 Mike Bostock
|
|
91
|
+
All rights reserved.
|
|
92
|
+
|
|
93
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
94
|
+
are permitted provided that the following conditions are met:
|
|
95
|
+
|
|
96
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
97
|
+
list of conditions and the following disclaimer.
|
|
98
|
+
|
|
99
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
100
|
+
this list of conditions and the following disclaimer in the documentation
|
|
101
|
+
and/or other materials provided with the distribution.
|
|
102
|
+
|
|
103
|
+
* Neither the name of the author nor the names of contributors may be used to
|
|
104
|
+
endorse or promote products derived from this software without specific prior
|
|
105
|
+
written permission.
|
|
106
|
+
|
|
107
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
108
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
109
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
110
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
111
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
112
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
113
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
114
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
115
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
116
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -279,6 +279,8 @@ export const Toolbar = Object.assign(props => {
|
|
|
279
279
|
// More, or to the toolbar's tab stop when nothing is left in More. Inside an effect the menu rows update after
|
|
280
280
|
// this function returns, so the check waits for that flush; a microtask still runs before the next paint.
|
|
281
281
|
queueMicrotask(() => {
|
|
282
|
+
// A toolbar unmounted meanwhile, as its view closes, owns no focus any more.
|
|
283
|
+
if (!mounted) return;
|
|
282
284
|
const lost = next.some(action => action.element === focused) || focused instanceof HTMLElement && !focused.isConnected || focused === trigger && !next.length;
|
|
283
285
|
if (lost) (next.length ? trigger : root.querySelector('[tabindex="0"]'))?.focus();
|
|
284
286
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["actions/Toolbar.tsx"],"sourcesContent":["import { createContext, createEffect, createSignal, type JSX, onCleanup, onMount, Show, sharedConfig, useContext } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport { Kbd } from \"../content/Kbd\";\nimport { useLocale } from \"../intl/locale\";\nimport { formatShortcut, type KeyboardPlatform, keyboardPlatform } from \"../intl/shortcut\";\nimport { IconButton } from \"./Button\";\nimport { Dropdown, type DropdownAction } from \"./Dropdown\";\nimport { useToolbarMessages } from \"./toolbar-messages\";\n\nexport type ToolbarProps = {\n children: JSX.Element;\n label: string;\n orientation?: \"horizontal\" | \"vertical\";\n wrap?: boolean;\n /** `floating` floats the toolbar at the bottom of its column. Defaults to `inline`. */\n variant?: \"inline\" | \"floating\";\n class?: string;\n};\n\nexport type ToolbarActionProps = {\n /** Accessible name, tooltip text, and the row label in the More menu. */\n label: string;\n /** Icon class, such as \"ti ti-archive\". */\n icon: string;\n /** Shortcut hint, tooltip suffix, and aria-keyshortcuts; does not register a shortcut handler. */\n keys?: string;\n /** 1 is most important. Larger numbers move first; ties move later DOM actions first. Omit to keep fixed. */\n priority?: number;\n disabled?: boolean;\n onClick?: () => void;\n};\nexport type ToolbarLabelProps = { children: JSX.Element; class?: string };\n\nexport type ToolbarGroupProps = { children: JSX.Element; label?: string; class?: string };\nexport type ToolbarSeparatorProps = { class?: string };\n\ntype ToolbarComponent = ((props: ToolbarProps) => JSX.Element) & {\n Action: (props: ToolbarActionProps) => JSX.Element;\n Label: (props: ToolbarLabelProps) => JSX.Element;\n Group: (props: ToolbarGroupProps) => JSX.Element;\n Separator: (props: ToolbarSeparatorProps) => JSX.Element;\n Spacer: () => JSX.Element;\n};\n\ntype ToolbarOrientation = NonNullable<ToolbarProps[\"orientation\"]>;\n\nconst defaultToolbarOrientation: () => ToolbarOrientation = () => \"horizontal\";\nconst ToolbarOrientationContext = createContext(defaultToolbarOrientation);\n\n// `item` is created once per action: the More menu keys its rows by identity, so a remeasure keeps a focused row.\ntype RegisteredAction = { element: HTMLButtonElement; props: ToolbarActionProps; item: DropdownAction };\nconst ToolbarActionsContext = createContext<(action: RegisteredAction) => () => void>();\nconst overflowAttribute = \"data-overflow\";\nconst hide = (element: Element) => element.setAttribute(overflowAttribute, \"hidden\");\nconst reveal = (element: Element) => element.removeAttribute(overflowAttribute);\n\n// ARIA uses language-independent key names, unlike the translated tooltip and caps.\nconst ariaShortcut = (keys: string | undefined, platform: KeyboardPlatform): string | undefined => {\n if (!keys || !formatShortcut(keys, { platform, locale: \"en\" }).keys.length) return undefined;\n const input = keys.trim().toLowerCase();\n const plus = input === \"+\" || input.endsWith(\"++\");\n const parts = (plus ? input.slice(0, -1) : input).split(\"+\");\n // ARIA separates keys with \"+\", so the plus key itself is named \"plus\".\n const key = plus ? \"plus\" : parts.pop() || \"space\";\n if (plus) parts.pop();\n const names: Record<string, string> = {\n mod: platform === \"apple\" ? \"Meta\" : \"Control\",\n ctrl: \"Control\",\n alt: \"Alt\",\n shift: \"Shift\",\n meta: \"Meta\",\n arrowup: \"ArrowUp\",\n arrowdown: \"ArrowDown\",\n arrowleft: \"ArrowLeft\",\n arrowright: \"ArrowRight\",\n escape: \"Escape\",\n esc: \"Escape\",\n backspace: \"Backspace\",\n enter: \"Enter\",\n delete: \"Delete\",\n space: \"Space\",\n tab: \"Tab\",\n home: \"Home\",\n end: \"End\",\n pageup: \"PageUp\",\n pagedown: \"PageDown\",\n plus: \"plus\",\n };\n const final = key.length === 1 || /^f(?:[1-9]|1[0-2])$/.test(key) ? key.toUpperCase() : names[key];\n return final ? [...new Set(parts.map((part) => names[part])), final].join(\"+\") : undefined;\n};\n\nconst ToolbarAction = (props: ToolbarActionProps): JSX.Element => {\n const register = useContext(ToolbarActionsContext);\n const locale = useLocale();\n const [platform, setPlatform] = createSignal<KeyboardPlatform>(isServer || sharedConfig.context ? \"other\" : keyboardPlatform());\n onMount(() => setPlatform(keyboardPlatform()));\n const tooltip = () => {\n const shortcut = props.keys ? formatShortcut(props.keys, { platform: platform(), locale: locale() }).label : \"\";\n return shortcut ? `${props.label} (${shortcut})` : props.label;\n };\n return (\n <IconButton\n ref={(element) => {\n const item: DropdownAction = {\n get label() {\n return props.label;\n },\n get icon() {\n return props.icon;\n },\n get disabled() {\n return props.disabled;\n },\n action: () => props.onClick?.(),\n };\n const unregister = register?.({ element, props, item });\n if (unregister) onCleanup(unregister);\n }}\n class=\"k2b-toolbar__action\"\n label={props.label}\n variant=\"ghost\"\n tooltip={tooltip()}\n aria-keyshortcuts={ariaShortcut(props.keys, platform())}\n data-priority={props.priority}\n disabled={props.disabled}\n onClick={() => props.onClick?.()}\n >\n <i class={props.icon} aria-hidden=\"true\" />\n <Show when={props.keys}>{(keys) => <Kbd keys={keys()} class=\"k2b-kbd-hint k2b-toolbar__hint\" />}</Show>\n </IconButton>\n );\n};\n\nconst ToolbarLabel = (props: ToolbarLabelProps): JSX.Element => (\n <span class={`k2b-toolbar__label ${props.class ?? \"\"}`}>{props.children}</span>\n);\n\nconst ToolbarGroup = (props: ToolbarGroupProps): JSX.Element => (\n <div class={`k2b-toolbar__group ${props.class ?? \"\"}`} role=\"group\" aria-label={props.label}>\n {props.children}\n </div>\n);\n\nconst ToolbarSeparator = (props: ToolbarSeparatorProps): JSX.Element => {\n const toolbarOrientation = useContext(ToolbarOrientationContext);\n const separatorOrientation = () => (toolbarOrientation() === \"horizontal\" ? \"vertical\" : \"horizontal\");\n\n return (\n <span\n class={`k2b-toolbar__separator ${props.class ?? \"\"}`}\n role=\"separator\"\n aria-orientation={separatorOrientation()}\n data-orientation={separatorOrientation()}\n />\n );\n};\n\nconst ToolbarSpacer = (): JSX.Element => <span class=\"k2b-toolbar__spacer\" aria-hidden=\"true\" />;\n\nconst rovingFocus = (root: HTMLDivElement, orientation: () => ToolbarOrientation) => {\n let last: HTMLElement | undefined;\n const setLast = (item: HTMLElement | undefined) => {\n if (item === last) return;\n if (last) resizeObserver.unobserve(last);\n last = item;\n if (last) resizeObserver.observe(last);\n };\n const controls = () =>\n Array.from(root.querySelectorAll<HTMLElement>(\"button, a[href], input, select, textarea, [tabindex]\")).filter((item) => {\n if (\n item.matches(\"textarea, select\") ||\n item.isContentEditable ||\n (item.matches(\"input\") && !/^(button|checkbox|reset|submit|image|color|file)$/i.test(item.getAttribute(\"type\") ?? \"text\"))\n )\n return false;\n const nested = item.closest('[role=\"menu\"], [role=\"listbox\"], [role=\"dialog\"], [popover]');\n return !nested || !root.contains(nested);\n });\n const items = () =>\n controls().filter(\n (item) => !item.matches(\":disabled\") && !item.closest('[data-overflow=\"hidden\"]') && item.getClientRects().length > 0,\n );\n const sync = () => {\n const available = items();\n if (!last || !available.includes(last)) setLast(available[0]);\n for (const item of controls()) item.tabIndex = item === last ? 0 : -1;\n };\n const focusin = (event: FocusEvent) => {\n if (event.target instanceof HTMLElement && items().includes(event.target)) {\n setLast(event.target);\n sync();\n }\n };\n const keydown = (event: KeyboardEvent) => {\n if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;\n const available = items();\n const target = event.target;\n if (!(target instanceof HTMLElement) || !available.includes(target)) return;\n const forward = orientation() === \"vertical\" ? \"ArrowDown\" : getComputedStyle(root).direction === \"rtl\" ? \"ArrowLeft\" : \"ArrowRight\";\n const backward = orientation() === \"vertical\" ? \"ArrowUp\" : forward === \"ArrowRight\" ? \"ArrowLeft\" : \"ArrowRight\";\n const index = available.indexOf(target);\n const next =\n event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? available.length - 1\n : event.key === forward\n ? (index + 1) % available.length\n : event.key === backward\n ? (index + available.length - 1) % available.length\n : -1;\n if (next < 0) return;\n event.preventDefault();\n setLast(available[next]);\n sync();\n last?.focus();\n };\n const observer = new MutationObserver(sync);\n observer.observe(root, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"disabled\", \"hidden\", \"class\", \"style\", overflowAttribute],\n });\n const resizeObserver = new ResizeObserver(sync);\n resizeObserver.observe(root);\n root.addEventListener(\"focusin\", focusin);\n sync();\n return {\n keydown,\n sync,\n cleanup: () => {\n observer.disconnect();\n resizeObserver.disconnect();\n root.removeEventListener(\"focusin\", focusin);\n },\n };\n};\n\n/**\n * All measurement writes are DOM attributes: reactive writes do not flush during onMount. More is never toggled while\n * measuring: hiding it, even for a moment, can make the browser drop focus from it or from its open menu. An idle More\n * stays out of the flow but keeps its box, so its width is always known.\n */\nconst measureOverflow = (\n root: HTMLDivElement,\n more: HTMLDivElement,\n actions: RegisteredAction[],\n available: number,\n): RegisteredAction[] => {\n for (const element of root.querySelectorAll(`[${overflowAttribute}]`)) if (element !== more) reveal(element);\n const children = Array.from(root.children).filter(\n (element): element is HTMLElement => element instanceof HTMLElement && element !== more,\n );\n const visible = (element: Element) => !element.matches(\"[popover]\") && element.getClientRects().length > 0;\n const separator = (element: Element) => element.classList.contains(\"k2b-toolbar__separator\");\n const item = (element: Element) => !separator(element) && !element.classList.contains(\"k2b-toolbar__spacer\");\n // Separators are tidied in DOM order with More, the last control, counted as shown when `withMore` is set.\n const all = Array.from(root.children).filter((element): element is HTMLElement => element instanceof HTMLElement);\n const tidy = (withMore: boolean) => {\n for (const group of root.querySelectorAll(\".k2b-toolbar__group\")) {\n reveal(group);\n if (!Array.from(group.children).some(visible)) hide(group);\n }\n for (const child of children) if (separator(child)) reveal(child);\n const shown = (element: HTMLElement) => (element === more ? withMore : visible(element));\n let preceding = false;\n for (let index = 0; index < all.length; index++) {\n const child = all[index]!;\n if (!shown(child)) continue;\n if (separator(child)) {\n const following = all.slice(index + 1).some((next) => item(next) && shown(next));\n if (!preceding || !following) hide(child);\n else preceding = false;\n } else if (item(child)) preceding = true;\n }\n };\n const style = getComputedStyle(root);\n const edges = [style.paddingLeft, style.paddingRight, style.borderLeftWidth, style.borderRightWidth].reduce(\n (sum, value) => sum + (Number.parseFloat(value) || 0),\n 0,\n );\n const gap = Number.parseFloat(style.columnGap) || 0;\n // A label may shrink in an overfull pill; measure its untruncated width (up to its cap) so actions move before the\n // count or title truncates.\n const width = (child: HTMLElement) => {\n // Separators carry inline margins, which bounding boxes leave out.\n const childStyle = getComputedStyle(child);\n const box =\n child.getBoundingClientRect().width +\n (Number.parseFloat(childStyle.marginLeft) || 0) +\n (Number.parseFloat(childStyle.marginRight) || 0);\n if (!child.classList.contains(\"k2b-toolbar__label\")) return box;\n const cap = Number.parseFloat(childStyle.maxWidth);\n return Math.max(box, Math.min(child.scrollWidth, Number.isNaN(cap) ? Number.POSITIVE_INFINITY : cap));\n };\n const moreWidth = width(more) + gap;\n const used = (withMore: boolean) => {\n const shown = children.filter(visible);\n return shown.reduce((sum, child) => sum + width(child), edges) + gap * Math.max(0, shown.length - 1) + (withMore ? moreWidth : 0);\n };\n // Stable sort retains DOM order for the menu, but removes later actions first on a priority tie.\n const candidates = actions\n // An action its application hides, even with `visibility: hidden`, must not reappear as a More row.\n .filter(\n (action) =>\n action.props.priority !== undefined && visible(action.element) && getComputedStyle(action.element).visibility !== \"hidden\",\n )\n .reverse()\n .sort((a, b) => b.props.priority! - a.props.priority!);\n let movedAny = false;\n tidy(false);\n for (const action of candidates) {\n if (used(movedAny) <= available) break;\n hide(action.element);\n movedAny = true;\n tidy(true);\n }\n // More changes only here, and only when its state changes.\n if (movedAny) reveal(more);\n else if (!more.hasAttribute(overflowAttribute)) hide(more);\n return actions.filter((action) => action.element.hasAttribute(overflowAttribute));\n};\n\nexport const Toolbar = Object.assign(\n (props: ToolbarProps): JSX.Element => {\n // The variant decides the DOM shape, so it is read once.\n const floating = props.variant === \"floating\";\n const orientation = () => (floating ? \"horizontal\" : (props.orientation ?? \"horizontal\"));\n const messages = useToolbarMessages();\n const actions = new Set<RegisteredAction>();\n const [revision, setRevision] = createSignal(0);\n const [moved, setMoved] = createSignal<RegisteredAction[]>([]);\n let root!: HTMLDivElement;\n let strip: HTMLDivElement | undefined;\n let more: HTMLDivElement | undefined;\n let trigger: HTMLButtonElement | undefined;\n let mounted = false;\n let navigation: ReturnType<typeof rovingFocus> | undefined;\n // Only the floating variant moves actions into More; inline toolbars keep every action in place.\n const measure = () => {\n if (!mounted || !strip || !more) return;\n const style = getComputedStyle(strip);\n const available = strip.clientWidth - Number.parseFloat(style.paddingLeft) - Number.parseFloat(style.paddingRight);\n if (available <= 0) return;\n const ordered = [...actions].sort((a, b) =>\n a.element.compareDocumentPosition(b.element) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1,\n );\n const focused = document.activeElement;\n // Cleared before measuring so the pending `visibility: hidden` does not hide every action from the check\n // below; the whole measurement still runs before the next paint.\n root.removeAttribute(\"data-overflow-pending\");\n const next = measureOverflow(root, more, ordered, available);\n setMoved((previous) =>\n previous.length === next.length && previous.every((action, index) => action === next[index]) ? previous : next,\n );\n navigation?.sync();\n // Focus on an action that moved, on a menu row whose action came back, or on a More that disappeared goes to\n // More, or to the toolbar's tab stop when nothing is left in More. Inside an effect the menu rows update after\n // this function returns, so the check waits for that flush; a microtask still runs before the next paint.\n queueMicrotask(() => {\n const lost =\n next.some((action) => action.element === focused) ||\n (focused instanceof HTMLElement && !focused.isConnected) ||\n (focused === trigger && !next.length);\n if (lost) (next.length ? trigger : root.querySelector<HTMLElement>('[tabindex=\"0\"]'))?.focus();\n });\n };\n const register = (action: RegisteredAction) => {\n actions.add(action);\n setRevision((value) => value + 1);\n return () => {\n actions.delete(action);\n setRevision((value) => value + 1);\n };\n };\n if (floating)\n createEffect(() => {\n revision();\n for (const action of actions) {\n // Content and priority changes can affect intrinsic widths as well as menu rows.\n void action.props.priority;\n void action.props.label;\n void action.props.icon;\n void action.props.keys;\n }\n measure();\n });\n onMount(() => {\n mounted = true;\n navigation = rovingFocus(root, orientation);\n onCleanup(() => {\n mounted = false;\n navigation?.cleanup();\n });\n if (!strip) return;\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(strip);\n observer.observe(root);\n const mutations = new MutationObserver(measure);\n // Visibility an application sets also counts. Measurement writes only data attributes, which stay unobserved.\n mutations.observe(root, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n attributeFilter: [\"hidden\", \"class\", \"style\"],\n });\n onCleanup(() => {\n observer.disconnect();\n mutations.disconnect();\n });\n });\n const menuItems = (): DropdownAction[] => moved().map((action) => action.item);\n const content = (\n <ToolbarOrientationContext.Provider value={orientation}>\n <ToolbarActionsContext.Provider value={floating ? register : undefined}>\n <div\n ref={root}\n onKeyDown={(event) => navigation?.keydown(event)}\n class={`k2b-toolbar ${props.class ?? \"\"}`}\n role=\"toolbar\"\n aria-label={props.label}\n aria-orientation={orientation()}\n data-orientation={orientation()}\n data-variant={floating ? \"floating\" : undefined}\n data-wrap={!floating && props.wrap ? \"true\" : undefined}\n data-overflow-pending={floating ? \"\" : undefined}\n >\n {props.children}\n <Show when={floating}>\n <div ref={more} class=\"k2b-toolbar__more\" data-overflow=\"hidden\">\n <Dropdown.Root\n items={menuItems()}\n position=\"top-left\"\n label={messages().moreActions}\n // An open menu closes when its last row returns to the toolbar.\n disabled={moved().length === 0}\n >\n <Dropdown.Trigger ref={trigger} iconOnly label={messages().moreActions}>\n <i class=\"ti ti-dots\" aria-hidden=\"true\" />\n </Dropdown.Trigger>\n </Dropdown.Root>\n </div>\n </Show>\n </div>\n </ToolbarActionsContext.Provider>\n </ToolbarOrientationContext.Provider>\n );\n return floating ? (\n <div ref={strip} class=\"k2b-toolbar-float\">\n {content}\n </div>\n ) : (\n content\n );\n },\n { Action: ToolbarAction, Label: ToolbarLabel, Group: ToolbarGroup, Separator: ToolbarSeparator, Spacer: ToolbarSpacer },\n) as ToolbarComponent;\n\nexport default Toolbar;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["actions/Toolbar.tsx"],"sourcesContent":["import { createContext, createEffect, createSignal, type JSX, onCleanup, onMount, Show, sharedConfig, useContext } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport { Kbd } from \"../content/Kbd\";\nimport { useLocale } from \"../intl/locale\";\nimport { formatShortcut, type KeyboardPlatform, keyboardPlatform } from \"../intl/shortcut\";\nimport { IconButton } from \"./Button\";\nimport { Dropdown, type DropdownAction } from \"./Dropdown\";\nimport { useToolbarMessages } from \"./toolbar-messages\";\n\nexport type ToolbarProps = {\n children: JSX.Element;\n label: string;\n orientation?: \"horizontal\" | \"vertical\";\n wrap?: boolean;\n /** `floating` floats the toolbar at the bottom of its column. Defaults to `inline`. */\n variant?: \"inline\" | \"floating\";\n class?: string;\n};\n\nexport type ToolbarActionProps = {\n /** Accessible name, tooltip text, and the row label in the More menu. */\n label: string;\n /** Icon class, such as \"ti ti-archive\". */\n icon: string;\n /** Shortcut hint, tooltip suffix, and aria-keyshortcuts; does not register a shortcut handler. */\n keys?: string;\n /** 1 is most important. Larger numbers move first; ties move later DOM actions first. Omit to keep fixed. */\n priority?: number;\n disabled?: boolean;\n onClick?: () => void;\n};\nexport type ToolbarLabelProps = { children: JSX.Element; class?: string };\n\nexport type ToolbarGroupProps = { children: JSX.Element; label?: string; class?: string };\nexport type ToolbarSeparatorProps = { class?: string };\n\ntype ToolbarComponent = ((props: ToolbarProps) => JSX.Element) & {\n Action: (props: ToolbarActionProps) => JSX.Element;\n Label: (props: ToolbarLabelProps) => JSX.Element;\n Group: (props: ToolbarGroupProps) => JSX.Element;\n Separator: (props: ToolbarSeparatorProps) => JSX.Element;\n Spacer: () => JSX.Element;\n};\n\ntype ToolbarOrientation = NonNullable<ToolbarProps[\"orientation\"]>;\n\nconst defaultToolbarOrientation: () => ToolbarOrientation = () => \"horizontal\";\nconst ToolbarOrientationContext = createContext(defaultToolbarOrientation);\n\n// `item` is created once per action: the More menu keys its rows by identity, so a remeasure keeps a focused row.\ntype RegisteredAction = { element: HTMLButtonElement; props: ToolbarActionProps; item: DropdownAction };\nconst ToolbarActionsContext = createContext<(action: RegisteredAction) => () => void>();\nconst overflowAttribute = \"data-overflow\";\nconst hide = (element: Element) => element.setAttribute(overflowAttribute, \"hidden\");\nconst reveal = (element: Element) => element.removeAttribute(overflowAttribute);\n\n// ARIA uses language-independent key names, unlike the translated tooltip and caps.\nconst ariaShortcut = (keys: string | undefined, platform: KeyboardPlatform): string | undefined => {\n if (!keys || !formatShortcut(keys, { platform, locale: \"en\" }).keys.length) return undefined;\n const input = keys.trim().toLowerCase();\n const plus = input === \"+\" || input.endsWith(\"++\");\n const parts = (plus ? input.slice(0, -1) : input).split(\"+\");\n // ARIA separates keys with \"+\", so the plus key itself is named \"plus\".\n const key = plus ? \"plus\" : parts.pop() || \"space\";\n if (plus) parts.pop();\n const names: Record<string, string> = {\n mod: platform === \"apple\" ? \"Meta\" : \"Control\",\n ctrl: \"Control\",\n alt: \"Alt\",\n shift: \"Shift\",\n meta: \"Meta\",\n arrowup: \"ArrowUp\",\n arrowdown: \"ArrowDown\",\n arrowleft: \"ArrowLeft\",\n arrowright: \"ArrowRight\",\n escape: \"Escape\",\n esc: \"Escape\",\n backspace: \"Backspace\",\n enter: \"Enter\",\n delete: \"Delete\",\n space: \"Space\",\n tab: \"Tab\",\n home: \"Home\",\n end: \"End\",\n pageup: \"PageUp\",\n pagedown: \"PageDown\",\n plus: \"plus\",\n };\n const final = key.length === 1 || /^f(?:[1-9]|1[0-2])$/.test(key) ? key.toUpperCase() : names[key];\n return final ? [...new Set(parts.map((part) => names[part])), final].join(\"+\") : undefined;\n};\n\nconst ToolbarAction = (props: ToolbarActionProps): JSX.Element => {\n const register = useContext(ToolbarActionsContext);\n const locale = useLocale();\n const [platform, setPlatform] = createSignal<KeyboardPlatform>(isServer || sharedConfig.context ? \"other\" : keyboardPlatform());\n onMount(() => setPlatform(keyboardPlatform()));\n const tooltip = () => {\n const shortcut = props.keys ? formatShortcut(props.keys, { platform: platform(), locale: locale() }).label : \"\";\n return shortcut ? `${props.label} (${shortcut})` : props.label;\n };\n return (\n <IconButton\n ref={(element) => {\n const item: DropdownAction = {\n get label() {\n return props.label;\n },\n get icon() {\n return props.icon;\n },\n get disabled() {\n return props.disabled;\n },\n action: () => props.onClick?.(),\n };\n const unregister = register?.({ element, props, item });\n if (unregister) onCleanup(unregister);\n }}\n class=\"k2b-toolbar__action\"\n label={props.label}\n variant=\"ghost\"\n tooltip={tooltip()}\n aria-keyshortcuts={ariaShortcut(props.keys, platform())}\n data-priority={props.priority}\n disabled={props.disabled}\n onClick={() => props.onClick?.()}\n >\n <i class={props.icon} aria-hidden=\"true\" />\n <Show when={props.keys}>{(keys) => <Kbd keys={keys()} class=\"k2b-kbd-hint k2b-toolbar__hint\" />}</Show>\n </IconButton>\n );\n};\n\nconst ToolbarLabel = (props: ToolbarLabelProps): JSX.Element => (\n <span class={`k2b-toolbar__label ${props.class ?? \"\"}`}>{props.children}</span>\n);\n\nconst ToolbarGroup = (props: ToolbarGroupProps): JSX.Element => (\n <div class={`k2b-toolbar__group ${props.class ?? \"\"}`} role=\"group\" aria-label={props.label}>\n {props.children}\n </div>\n);\n\nconst ToolbarSeparator = (props: ToolbarSeparatorProps): JSX.Element => {\n const toolbarOrientation = useContext(ToolbarOrientationContext);\n const separatorOrientation = () => (toolbarOrientation() === \"horizontal\" ? \"vertical\" : \"horizontal\");\n\n return (\n <span\n class={`k2b-toolbar__separator ${props.class ?? \"\"}`}\n role=\"separator\"\n aria-orientation={separatorOrientation()}\n data-orientation={separatorOrientation()}\n />\n );\n};\n\nconst ToolbarSpacer = (): JSX.Element => <span class=\"k2b-toolbar__spacer\" aria-hidden=\"true\" />;\n\nconst rovingFocus = (root: HTMLDivElement, orientation: () => ToolbarOrientation) => {\n let last: HTMLElement | undefined;\n const setLast = (item: HTMLElement | undefined) => {\n if (item === last) return;\n if (last) resizeObserver.unobserve(last);\n last = item;\n if (last) resizeObserver.observe(last);\n };\n const controls = () =>\n Array.from(root.querySelectorAll<HTMLElement>(\"button, a[href], input, select, textarea, [tabindex]\")).filter((item) => {\n if (\n item.matches(\"textarea, select\") ||\n item.isContentEditable ||\n (item.matches(\"input\") && !/^(button|checkbox|reset|submit|image|color|file)$/i.test(item.getAttribute(\"type\") ?? \"text\"))\n )\n return false;\n const nested = item.closest('[role=\"menu\"], [role=\"listbox\"], [role=\"dialog\"], [popover]');\n return !nested || !root.contains(nested);\n });\n const items = () =>\n controls().filter(\n (item) => !item.matches(\":disabled\") && !item.closest('[data-overflow=\"hidden\"]') && item.getClientRects().length > 0,\n );\n const sync = () => {\n const available = items();\n if (!last || !available.includes(last)) setLast(available[0]);\n for (const item of controls()) item.tabIndex = item === last ? 0 : -1;\n };\n const focusin = (event: FocusEvent) => {\n if (event.target instanceof HTMLElement && items().includes(event.target)) {\n setLast(event.target);\n sync();\n }\n };\n const keydown = (event: KeyboardEvent) => {\n if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;\n const available = items();\n const target = event.target;\n if (!(target instanceof HTMLElement) || !available.includes(target)) return;\n const forward = orientation() === \"vertical\" ? \"ArrowDown\" : getComputedStyle(root).direction === \"rtl\" ? \"ArrowLeft\" : \"ArrowRight\";\n const backward = orientation() === \"vertical\" ? \"ArrowUp\" : forward === \"ArrowRight\" ? \"ArrowLeft\" : \"ArrowRight\";\n const index = available.indexOf(target);\n const next =\n event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? available.length - 1\n : event.key === forward\n ? (index + 1) % available.length\n : event.key === backward\n ? (index + available.length - 1) % available.length\n : -1;\n if (next < 0) return;\n event.preventDefault();\n setLast(available[next]);\n sync();\n last?.focus();\n };\n const observer = new MutationObserver(sync);\n observer.observe(root, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"disabled\", \"hidden\", \"class\", \"style\", overflowAttribute],\n });\n const resizeObserver = new ResizeObserver(sync);\n resizeObserver.observe(root);\n root.addEventListener(\"focusin\", focusin);\n sync();\n return {\n keydown,\n sync,\n cleanup: () => {\n observer.disconnect();\n resizeObserver.disconnect();\n root.removeEventListener(\"focusin\", focusin);\n },\n };\n};\n\n/**\n * All measurement writes are DOM attributes: reactive writes do not flush during onMount. More is never toggled while\n * measuring: hiding it, even for a moment, can make the browser drop focus from it or from its open menu. An idle More\n * stays out of the flow but keeps its box, so its width is always known.\n */\nconst measureOverflow = (\n root: HTMLDivElement,\n more: HTMLDivElement,\n actions: RegisteredAction[],\n available: number,\n): RegisteredAction[] => {\n for (const element of root.querySelectorAll(`[${overflowAttribute}]`)) if (element !== more) reveal(element);\n const children = Array.from(root.children).filter(\n (element): element is HTMLElement => element instanceof HTMLElement && element !== more,\n );\n const visible = (element: Element) => !element.matches(\"[popover]\") && element.getClientRects().length > 0;\n const separator = (element: Element) => element.classList.contains(\"k2b-toolbar__separator\");\n const item = (element: Element) => !separator(element) && !element.classList.contains(\"k2b-toolbar__spacer\");\n // Separators are tidied in DOM order with More, the last control, counted as shown when `withMore` is set.\n const all = Array.from(root.children).filter((element): element is HTMLElement => element instanceof HTMLElement);\n const tidy = (withMore: boolean) => {\n for (const group of root.querySelectorAll(\".k2b-toolbar__group\")) {\n reveal(group);\n if (!Array.from(group.children).some(visible)) hide(group);\n }\n for (const child of children) if (separator(child)) reveal(child);\n const shown = (element: HTMLElement) => (element === more ? withMore : visible(element));\n let preceding = false;\n for (let index = 0; index < all.length; index++) {\n const child = all[index]!;\n if (!shown(child)) continue;\n if (separator(child)) {\n const following = all.slice(index + 1).some((next) => item(next) && shown(next));\n if (!preceding || !following) hide(child);\n else preceding = false;\n } else if (item(child)) preceding = true;\n }\n };\n const style = getComputedStyle(root);\n const edges = [style.paddingLeft, style.paddingRight, style.borderLeftWidth, style.borderRightWidth].reduce(\n (sum, value) => sum + (Number.parseFloat(value) || 0),\n 0,\n );\n const gap = Number.parseFloat(style.columnGap) || 0;\n // A label may shrink in an overfull pill; measure its untruncated width (up to its cap) so actions move before the\n // count or title truncates.\n const width = (child: HTMLElement) => {\n // Separators carry inline margins, which bounding boxes leave out.\n const childStyle = getComputedStyle(child);\n const box =\n child.getBoundingClientRect().width +\n (Number.parseFloat(childStyle.marginLeft) || 0) +\n (Number.parseFloat(childStyle.marginRight) || 0);\n if (!child.classList.contains(\"k2b-toolbar__label\")) return box;\n const cap = Number.parseFloat(childStyle.maxWidth);\n return Math.max(box, Math.min(child.scrollWidth, Number.isNaN(cap) ? Number.POSITIVE_INFINITY : cap));\n };\n const moreWidth = width(more) + gap;\n const used = (withMore: boolean) => {\n const shown = children.filter(visible);\n return shown.reduce((sum, child) => sum + width(child), edges) + gap * Math.max(0, shown.length - 1) + (withMore ? moreWidth : 0);\n };\n // Stable sort retains DOM order for the menu, but removes later actions first on a priority tie.\n const candidates = actions\n // An action its application hides, even with `visibility: hidden`, must not reappear as a More row.\n .filter(\n (action) =>\n action.props.priority !== undefined && visible(action.element) && getComputedStyle(action.element).visibility !== \"hidden\",\n )\n .reverse()\n .sort((a, b) => b.props.priority! - a.props.priority!);\n let movedAny = false;\n tidy(false);\n for (const action of candidates) {\n if (used(movedAny) <= available) break;\n hide(action.element);\n movedAny = true;\n tidy(true);\n }\n // More changes only here, and only when its state changes.\n if (movedAny) reveal(more);\n else if (!more.hasAttribute(overflowAttribute)) hide(more);\n return actions.filter((action) => action.element.hasAttribute(overflowAttribute));\n};\n\nexport const Toolbar = Object.assign(\n (props: ToolbarProps): JSX.Element => {\n // The variant decides the DOM shape, so it is read once.\n const floating = props.variant === \"floating\";\n const orientation = () => (floating ? \"horizontal\" : (props.orientation ?? \"horizontal\"));\n const messages = useToolbarMessages();\n const actions = new Set<RegisteredAction>();\n const [revision, setRevision] = createSignal(0);\n const [moved, setMoved] = createSignal<RegisteredAction[]>([]);\n let root!: HTMLDivElement;\n let strip: HTMLDivElement | undefined;\n let more: HTMLDivElement | undefined;\n let trigger: HTMLButtonElement | undefined;\n let mounted = false;\n let navigation: ReturnType<typeof rovingFocus> | undefined;\n // Only the floating variant moves actions into More; inline toolbars keep every action in place.\n const measure = () => {\n if (!mounted || !strip || !more) return;\n const style = getComputedStyle(strip);\n const available = strip.clientWidth - Number.parseFloat(style.paddingLeft) - Number.parseFloat(style.paddingRight);\n if (available <= 0) return;\n const ordered = [...actions].sort((a, b) =>\n a.element.compareDocumentPosition(b.element) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1,\n );\n const focused = document.activeElement;\n // Cleared before measuring so the pending `visibility: hidden` does not hide every action from the check\n // below; the whole measurement still runs before the next paint.\n root.removeAttribute(\"data-overflow-pending\");\n const next = measureOverflow(root, more, ordered, available);\n setMoved((previous) =>\n previous.length === next.length && previous.every((action, index) => action === next[index]) ? previous : next,\n );\n navigation?.sync();\n // Focus on an action that moved, on a menu row whose action came back, or on a More that disappeared goes to\n // More, or to the toolbar's tab stop when nothing is left in More. Inside an effect the menu rows update after\n // this function returns, so the check waits for that flush; a microtask still runs before the next paint.\n queueMicrotask(() => {\n // A toolbar unmounted meanwhile, as its view closes, owns no focus any more.\n if (!mounted) return;\n const lost =\n next.some((action) => action.element === focused) ||\n (focused instanceof HTMLElement && !focused.isConnected) ||\n (focused === trigger && !next.length);\n if (lost) (next.length ? trigger : root.querySelector<HTMLElement>('[tabindex=\"0\"]'))?.focus();\n });\n };\n const register = (action: RegisteredAction) => {\n actions.add(action);\n setRevision((value) => value + 1);\n return () => {\n actions.delete(action);\n setRevision((value) => value + 1);\n };\n };\n if (floating)\n createEffect(() => {\n revision();\n for (const action of actions) {\n // Content and priority changes can affect intrinsic widths as well as menu rows.\n void action.props.priority;\n void action.props.label;\n void action.props.icon;\n void action.props.keys;\n }\n measure();\n });\n onMount(() => {\n mounted = true;\n navigation = rovingFocus(root, orientation);\n onCleanup(() => {\n mounted = false;\n navigation?.cleanup();\n });\n if (!strip) return;\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(strip);\n observer.observe(root);\n const mutations = new MutationObserver(measure);\n // Visibility an application sets also counts. Measurement writes only data attributes, which stay unobserved.\n mutations.observe(root, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n attributeFilter: [\"hidden\", \"class\", \"style\"],\n });\n onCleanup(() => {\n observer.disconnect();\n mutations.disconnect();\n });\n });\n const menuItems = (): DropdownAction[] => moved().map((action) => action.item);\n const content = (\n <ToolbarOrientationContext.Provider value={orientation}>\n <ToolbarActionsContext.Provider value={floating ? register : undefined}>\n <div\n ref={root}\n onKeyDown={(event) => navigation?.keydown(event)}\n class={`k2b-toolbar ${props.class ?? \"\"}`}\n role=\"toolbar\"\n aria-label={props.label}\n aria-orientation={orientation()}\n data-orientation={orientation()}\n data-variant={floating ? \"floating\" : undefined}\n data-wrap={!floating && props.wrap ? \"true\" : undefined}\n data-overflow-pending={floating ? \"\" : undefined}\n >\n {props.children}\n <Show when={floating}>\n <div ref={more} class=\"k2b-toolbar__more\" data-overflow=\"hidden\">\n <Dropdown.Root\n items={menuItems()}\n position=\"top-left\"\n label={messages().moreActions}\n // An open menu closes when its last row returns to the toolbar.\n disabled={moved().length === 0}\n >\n <Dropdown.Trigger ref={trigger} iconOnly label={messages().moreActions}>\n <i class=\"ti ti-dots\" aria-hidden=\"true\" />\n </Dropdown.Trigger>\n </Dropdown.Root>\n </div>\n </Show>\n </div>\n </ToolbarActionsContext.Provider>\n </ToolbarOrientationContext.Provider>\n );\n return floating ? (\n <div ref={strip} class=\"k2b-toolbar-float\">\n {content}\n </div>\n ) : (\n content\n );\n },\n { Action: ToolbarAction, Label: ToolbarLabel, Group: ToolbarGroup, Separator: ToolbarSeparator, Spacer: ToolbarSpacer },\n) as ToolbarComponent;\n\nexport default Toolbar;\n"],"mappings":";;;;;;;;;;;;;AAAA,SAAS,aAAa,EAAE,YAAY,EAAE,YAAY,EAAY,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,QAAQ,UAAU;AAClI,SAAS,QAAQ,QAAQ,cAAc;AACvC,SAAS,GAAG,QAAQ,gBAAgB;AACpC,SAAS,SAAS,QAAQ,gBAAgB;AAC1C,SAAS,cAAc,EAAyB,gBAAgB,QAAQ,kBAAkB;AAC1F,SAAS,UAAU,QAAQ,UAAU;AACrC,SAAS,QAAQ,QAA6B,YAAY;AAC1D,SAAS,kBAAkB,QAAQ,oBAAoB;AAuCvD,MAAM,yBAAmD,GAAG,MAAM,YAAY;AAC9E,MAAM,yBAAyB,GAAG,aAAa,CAAC,yBAAyB,CAAC;;AAE1E;;AAEA,MAAM,qBAAqB,GAAG,aAAa,CAA2C,CAAC;AACvF,MAAM,iBAAiB,GAAG,eAAe;AACzC,MAAM,IAAI,GAAI,OAAgB,IAAK,OAAO,CAAC,YAAY,CAAC,iBAAiB,EAAE,QAAQ,CAAC;AACpF,MAAM,MAAM,GAAI,OAAgB,IAAK,OAAO,CAAC,eAAe,CAAC,iBAAiB,CAAC;;AAE/E;AACA,MAAM,YAAY,GAAG,CAAC,IAAwB,EAAE,QAA0B,KAAyB;EACjG,IAAI,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE;IAAE,QAAQ;IAAE,MAAM,EAAE;EAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,SAAS;EAC5F,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;EACvC,MAAM,IAAI,GAAG,KAAK,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;EAClD,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC;EAC5D;EACA,MAAM,GAAG,GAAG,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,OAAO;EAClD,IAAI,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;EACrB,MAAM,KAA6B,GAAG;IACpC,GAAG,EAAE,QAAQ,KAAK,OAAO,GAAG,MAAM,GAAG,SAAS;IAC9C,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,WAAW;IACtB,UAAU,EAAE,YAAY;IACxB,MAAM,EAAE,QAAQ;IAChB,GAAG,EAAE,QAAQ;IACb,SAAS,EAAE,WAAW;IACtB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;IACpB,IAAI,EAAE;EACR,CAAC;EACD,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC;EAClG,OAAO,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAE,IAAI,IAAK,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,SAAS;AAC5F,CAAC;AAED,MAAM,aAAa,GAAI,KAAyB,IAAkB;EAChE,MAAM,QAAQ,GAAG,UAAU,CAAC,qBAAqB,CAAC;EAClD,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;EAC1B,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,YAAY,CAAmB,QAAQ,IAAI,YAAY,CAAC,OAAO,GAAG,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC;EAC/H,OAAO,CAAC,MAAM,WAAW,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;EAC9C,MAAM,OAAO,GAAG,MAAM;IACpB,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE;MAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;MAAE,MAAM,EAAE,MAAM,CAAC;IAAE,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;IAC/G,OAAO,QAAQ,GAAG,GAAG,KAAK,CAAC,KAAK,KAAK,QAAQ,GAAG,GAAG,KAAK,CAAC,KAAK;EAChE,CAAC;EACD,yBACG,UAAU;IAAA;IAAA,IAkBT,KAAK;MAAA,OAAE,KAAK,CAAC,KAAK;IAAA;IAClB,OAAO;IAAA,IACP,OAAO;MAAA,OAAE,OAAO,CAAC,CAAC;IAAA;IAAA;MAAA,OACC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAAA;IAAA;MAAA,OACxC,KAAK,CAAC,QAAQ;IAAA;IAAA,IAC7B,QAAQ;MAAA,OAAE,KAAK,CAAC,QAAQ;IAAA;IACxB,OAAO,EAAE,MAAM,KAAK,CAAC,OAAO,GAAG,CAAC;IAAA;MAAA,uDAEtB,KAAK,CAAC,IAAI,oCACnB,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,IAAI;QAAA;QAAA,UAAI,IAAI,sBAAM,GAAG;UAAA,IAAC,IAAI;YAAA,OAAE,IAAI,CAAC,CAAC;UAAA;UAAA;QAAA;MAA2C;IAAA;EAAA;AAGrG,CAAC;AAED,MAAM,YAAY,GAAI,KAAwB,mBAC/B,+BAAsB,KAAK,CAAC,KAAK,IAAI,EAAE,SAAE,WAAG,KAAK,CAAC,QAAQ,EACxE;AAED,MAAM,YAAY,GAAI,KAAwB,mBAChC,+BAAsB,KAAK,CAAC,KAAK,IAAI,EAAE,SAAE,wCAA2B,KAAK,CAAC,KAAK,0BACxF,KAAK,CAAC,QAAQ,EAElB;AAED,MAAM,gBAAgB,GAAI,KAA4B,IAAkB;EACtE,MAAM,kBAAkB,GAAG,UAAU,CAAC,yBAAyB,CAAC;EAChE,MAAM,oBAAoB,GAAG,MAAO,kBAAkB,CAAC,CAAC,KAAK,YAAY,GAAG,UAAU,GAAG,YAAa;EAEtG,sBAEW,mCAA0B,KAAK,CAAC,KAAK,IAAI,EAAE,SAAE,8CAElC,oBAAoB,CAAC,CAAC,8DACtB,oBAAoB,CAAC,CAAC;AAG9C,CAAC;AAED,MAAM,aAAa,GAAG,oBAA0E;AAEhG,MAAM,WAAW,GAAG,CAAC,IAAoB,EAAE,WAAqC,KAAK;EACnF,IAAI,IAA6B;EACjC,MAAM,OAAO,GAAI,IAA6B,IAAK;IACjD,IAAI,IAAI,KAAK,IAAI,EAAE;IACnB,IAAI,IAAI,EAAE,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC;IACxC,IAAI,GAAG,IAAI;IACX,IAAI,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC;EACxC,CAAC;EACD,MAAM,QAAQ,GAAG,MACf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAc,sDAAsD,CAAC,CAAC,CAAC,MAAM,CAAE,IAAI,IAAK;IACtH,IACE,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAChC,IAAI,CAAC,iBAAiB,IACrB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,oDAAoD,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,MAAM,CAAE,EAE1H,OAAO,KAAK;IACd,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,6DAA6D,CAAC;IAC1F,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;EAC1C,CAAC,CAAC;EACJ,MAAM,KAAK,GAAG,MACZ,QAAQ,CAAC,CAAC,CAAC,MAAM,CACd,IAAI,IAAK,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,GAAG,CACtH,CAAC;EACH,MAAM,IAAI,GAAG,MAAM;IACjB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC;IACzB,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC7D,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;EACvE,CAAC;EACD,MAAM,OAAO,GAAI,KAAiB,IAAK;IACrC,IAAI,KAAK,CAAC,MAAM,YAAY,WAAW,IAAI,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;MACzE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;MACrB,IAAI,CAAC,CAAC;IACR;EACF,CAAC;EACD,MAAM,OAAO,GAAI,KAAoB,IAAK;IACxC,IAAI,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE;IAChG,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC;IACzB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM;IAC3B,IAAI,EAAE,MAAM,YAAY,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;IACrE,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,KAAK,UAAU,GAAG,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,KAAK,GAAG,WAAW,GAAG,YAAY;IACpI,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,KAAK,UAAU,GAAG,SAAS,GAAG,OAAO,KAAK,YAAY,GAAG,WAAW,GAAG,YAAY;IACjH,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC;IACvC,MAAM,IAAI,GACR,KAAK,CAAC,GAAG,KAAK,MAAM,GAChB,CAAC,GACD,KAAK,CAAC,GAAG,KAAK,KAAK,GACjB,SAAS,CAAC,MAAM,GAAG,CAAC,GACpB,KAAK,CAAC,GAAG,KAAK,OAAO,GACnB,CAAC,KAAK,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,GAC9B,KAAK,CAAC,GAAG,KAAK,QAAQ,GACpB,CAAC,KAAK,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,GACjD,CAAC,CAAC;IACd,IAAI,IAAI,GAAG,CAAC,EAAE;IACd,KAAK,CAAC,cAAc,CAAC,CAAC;IACtB,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACxB,IAAI,CAAC,CAAC;IACN,IAAI,EAAE,KAAK,CAAC,CAAC;EACf,CAAC;EACD,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC;EAC3C,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE;IACrB,SAAS,EAAE,IAAI;IACf,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,IAAI;IAChB,eAAe,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB;EAC7E,CAAC,CAAC;EACF,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC;EAC/C,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC;EAC5B,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC;EACzC,IAAI,CAAC,CAAC;EACN,OAAO;IACL,OAAO;IACP,IAAI;IACJ,OAAO,EAAE,MAAM;MACb,QAAQ,CAAC,UAAU,CAAC,CAAC;MACrB,cAAc,CAAC,UAAU,CAAC,CAAC;MAC3B,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,OAAO,CAAC;IAC9C;EACF,CAAC;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,MAAM,eAAe,GAAG,CACtB,IAAoB,EACpB,IAAoB,EACpB,OAA2B,EAC3B,SAAiB,KACM;EACvB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,iBAAiB,GAAG,CAAC,EAAE,IAAI,OAAO,KAAK,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC;EAC5G,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAC9C,OAAO,IAA6B,OAAO,YAAY,WAAW,IAAI,OAAO,KAAK,IACrF,CAAC;EACD,MAAM,OAAO,GAAI,OAAgB,IAAK,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;EAC1G,MAAM,SAAS,GAAI,OAAgB,IAAK,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,wBAAwB,CAAC;EAC5F,MAAM,IAAI,GAAI,OAAgB,IAAK,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,qBAAqB,CAAC;EAC5G;EACA,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAE,OAAO,IAA6B,OAAO,YAAY,WAAW,CAAC;EACjH,MAAM,IAAI,GAAI,QAAiB,IAAK;IAClC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,EAAE;MAChE,MAAM,CAAC,KAAK,CAAC;MACb,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;IAC5D;IACA,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC;IACjE,MAAM,KAAK,GAAI,OAAoB,IAAM,OAAO,KAAK,IAAI,GAAG,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAE;IACxF,IAAI,SAAS,GAAG,KAAK;IACrB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;MAC/C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAE;MACzB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;MACnB,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE;QACpB,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAE,IAAI,IAAK,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;QAChF,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,KACrC,SAAS,GAAG,KAAK;MACxB,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI;IAC1C;EACF,CAAC;EACD,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC;EACpC,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC,MAAM,CACzG,CAAC,GAAG,EAAE,KAAK,KAAK,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EACrD,CACF,CAAC;EACD,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;EACnD;EACA;EACA,MAAM,KAAK,GAAI,KAAkB,IAAK;IACpC;IACA,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,CAAC;IAC1C,MAAM,GAAG,GACP,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,KAAK,IAClC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAC9C,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,GAAG;IAC/D,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC;IAClD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,iBAAiB,GAAG,GAAG,CAAC,CAAC;EACvG,CAAC;EACD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG;EACnC,MAAM,IAAI,GAAI,QAAiB,IAAK;IAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;IACtC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,QAAQ,GAAG,SAAS,GAAG,CAAC,CAAC;EACnI,CAAC;EACD;EACA,MAAM,UAAU,GAAG;EACjB;EAAA,CACC,MAAM,CACJ,MAAM,IACL,MAAM,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,UAAU,KAAK,QACtH,CAAC,CACA,OAAO,CAAC,CAAC,CACT,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,GAAI,CAAC,CAAC,KAAK,CAAC,QAAS,CAAC;EACxD,IAAI,QAAQ,GAAG,KAAK;EACpB,IAAI,CAAC,KAAK,CAAC;EACX,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE;IAC/B,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,SAAS,EAAE;IACjC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;IACpB,QAAQ,GAAG,IAAI;IACf,IAAI,CAAC,IAAI,CAAC;EACZ;EACA;EACA,IAAI,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,KACtB,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC;EAC1D,OAAO,OAAO,CAAC,MAAM,CAAE,MAAM,IAAK,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;AACnF,CAAC;AAED,OAAO,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CACjC,KAAmB,IAAkB;EACpC;EACA,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,KAAK,UAAU;EAC7C,MAAM,WAAW,GAAG,MAAO,QAAQ,GAAG,YAAY,GAAI,KAAK,CAAC,WAAW,IAAI,YAAc;EACzF,MAAM,QAAQ,GAAG,kBAAkB,CAAC,CAAC;EACrC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAmB,CAAC;EAC3C,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;EAC/C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAqB,EAAE,CAAC;EAC9D,IAAI,IAAqB;EACzB,IAAI,KAAiC;EACrC,IAAI,IAAgC;EACpC,IAAI,OAAsC;EAC1C,IAAI,OAAO,GAAG,KAAK;EACnB,IAAI,UAAsD;EAC1D;EACA,MAAM,OAAO,GAAG,MAAM;IACpB,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE;IACjC,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC;IAClH,IAAI,SAAS,IAAI,CAAC,EAAE;IACpB,MAAM,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KACrC,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,2BAA2B,GAAG,CAAC,CAAC,GAAG,CACzF,CAAC;IACD,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa;IACtC;IACA;IACA,IAAI,CAAC,eAAe,CAAC,uBAAuB,CAAC;IAC7C,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC;IAC5D,QAAQ,CAAE,QAAQ,IAChB,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,KAAK,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,QAAQ,GAAG,IAC5G,CAAC;IACD,UAAU,EAAE,IAAI,CAAC,CAAC;IAClB;IACA;IACA;IACA,cAAc,CAAC,MAAM;MACnB;MACA,IAAI,CAAC,OAAO,EAAE;MACd,MAAM,IAAI,GACR,IAAI,CAAC,IAAI,CAAE,MAAM,IAAK,MAAM,CAAC,OAAO,KAAK,OAAO,CAAC,IAChD,OAAO,YAAY,WAAW,IAAI,CAAC,OAAO,CAAC,WAAY,IACvD,OAAO,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,MAAO;MACvC,IAAI,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,aAAa,CAAc,gBAAgB,CAAC,GAAG,KAAK,CAAC,CAAC;IAChG,CAAC,CAAC;EACJ,CAAC;EACD,MAAM,QAAQ,GAAI,MAAwB,IAAK;IAC7C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;IACnB,WAAW,CAAE,KAAK,IAAK,KAAK,GAAG,CAAC,CAAC;IACjC,OAAO,MAAM;MACX,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;MACtB,WAAW,CAAE,KAAK,IAAK,KAAK,GAAG,CAAC,CAAC;IACnC,CAAC;EACH,CAAC;EACD,IAAI,QAAQ,EACV,YAAY,CAAC,MAAM;IACjB,QAAQ,CAAC,CAAC;IACV,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;MAC5B;MACA,KAAK,MAAM,CAAC,KAAK,CAAC,QAAQ;MAC1B,KAAK,MAAM,CAAC,KAAK,CAAC,KAAK;MACvB,KAAK,MAAM,CAAC,KAAK,CAAC,IAAI;MACtB,KAAK,MAAM,CAAC,KAAK,CAAC,IAAI;IACxB;IACA,OAAO,CAAC,CAAC;EACX,CAAC,CAAC;EACJ,OAAO,CAAC,MAAM;IACZ,OAAO,GAAG,IAAI;IACd,UAAU,GAAG,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3C,SAAS,CAAC,MAAM;MACd,OAAO,GAAG,KAAK;MACf,UAAU,EAAE,OAAO,CAAC,CAAC;IACvB,CAAC,CAAC;IACF,IAAI,CAAC,KAAK,EAAE;IACZ,OAAO,CAAC,CAAC;IACT,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC;IAC5C,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;IACtB,MAAM,SAAS,GAAG,IAAI,gBAAgB,CAAC,OAAO,CAAC;IAC/C;IACA,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE;MACtB,SAAS,EAAE,IAAI;MACf,OAAO,EAAE,IAAI;MACb,aAAa,EAAE,IAAI;MACnB,UAAU,EAAE,IAAI;MAChB,eAAe,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO;IAC9C,CAAC,CAAC;IACF,SAAS,CAAC,MAAM;MACd,QAAQ,CAAC,UAAU,CAAC,CAAC;MACrB,SAAS,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC,CAAC;EACJ,CAAC,CAAC;EACF,MAAM,SAAS,GAAG,MAAwB,KAAK,CAAC,CAAC,CAAC,GAAG,CAAE,MAAM,IAAK,MAAM,CAAC,IAAI,CAAC;EAC9E,MAAM,OAAO,qBACV,yBAAyB,CAAC,QAAQ;IAAC,KAAK,EAAE,WAAW;IAAA;MAAA,yBACnD,qBAAqB,CAAC,QAAQ;QAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS;QAAA;UAAA,sBAI3D,wBAAe,KAAK,CAAC,KAAK,IAAI,EAAE,SAAE,wCAE7B,KAAK,CAAC,KAAK,8DACL,WAAW,CAAC,CAAC,8DACb,WAAW,CAAC,CAAC,iDACjB,QAAQ,GAAG,UAAU,YAAG,SAAS,8CACpC,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,GAAG,MAAM,YAAG,SAAS,0DAChC,QAAQ,GAAG,EAAE,YAAG,SAAS,0BAE/C,KAAK,CAAC,QAAQ,8BACd,IAAI;YAAC,IAAI,EAAE,QAAQ;YAAA;cAAA,iDAEf,QAAQ,CAAC,IAAI;gBAAA,IACZ,KAAK;kBAAA,OAAE,SAAS,CAAC,CAAC;gBAAA;gBAClB,QAAQ;gBAAA,IACR,KAAK;kBAAA,OAAE,QAAQ,CAAC,CAAC,CAAC,WAAW;gBAAA;gBAAA,IAE7B,QAAQ;kBAAA,OAAE,KAAK,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAA;gBAAA;kBAAA,yBAE7B,QAAQ,CAAC,OAAO;oBAAe,QAAQ;oBAAA,IAAC,KAAK;sBAAA,OAAE,QAAQ,CAAC,CAAC,CAAC,WAAW;oBAAA;oBAAA;sBAAA;oBAAA;kBAAA;gBAAA;cAAA;YAAA;UAAA;QAAA;MAAA;IAAA;EAAA,EASnF;EACD,OAAO,QAAQ,2BAEV,OAAO,KAGV,OACD;AACH,CAAC,EACD;EAAE,MAAM,EAAE,aAAa;EAAE,KAAK,EAAE,YAAY;EAAE,KAAK,EAAE,YAAY;EAAE,SAAS,EAAE,gBAAgB;EAAE,MAAM,EAAE;AAAc,CACxH,CAAqB;AAErB,eAAe,OAAO","ignoreList":[]}
|
|
@@ -61,6 +61,17 @@ export function ChatDecision(props) {
|
|
|
61
61
|
const [answeredHere, setAnsweredHere] = createSignal(false);
|
|
62
62
|
const [arrive, setArrive] = createSignal(false);
|
|
63
63
|
let reopenedHere = false;
|
|
64
|
+
// A press on the sentence focuses it too; only a focus moved there from elsewhere, such as a jump, lights it up.
|
|
65
|
+
// The browser also focuses the sentence again when its window comes back; that is no arrival either.
|
|
66
|
+
let sentencePressed = false;
|
|
67
|
+
let sentenceHeldAcrossWindow = false;
|
|
68
|
+
const windowLeft = () => {
|
|
69
|
+
if (sentence && document.activeElement === sentence) sentenceHeldAcrossWindow = true;
|
|
70
|
+
};
|
|
71
|
+
onMount(() => {
|
|
72
|
+
window.addEventListener("blur", windowLeft);
|
|
73
|
+
onCleanup(() => window.removeEventListener("blur", windowLeft));
|
|
74
|
+
});
|
|
64
75
|
// A press counts only while its action runs: a reopen from elsewhere later must not take the focus.
|
|
65
76
|
const scope = {
|
|
66
77
|
answered: answeredHere,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["chat/ChatDecision.tsx"],"sourcesContent":["import {\n createContext,\n createEffect,\n createMemo,\n createSignal,\n createUniqueId,\n For,\n type JSX,\n on,\n onCleanup,\n onMount,\n Show,\n untrack,\n useContext,\n} from \"solid-js\";\nimport { Button } from \"../actions/Button\";\nimport { Avatar } from \"../surfaces/Avatar\";\nimport { useChatMessages } from \"./chat-messages\";\nimport type {\n ChatDecisionAnswer,\n ChatDecisionReason,\n ChatDecisionState,\n ChatOutcomeLine,\n ChatOutcomeTone,\n ChatPreviewHeaderRow,\n ChatPreviewPerson,\n} from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Decision\n// ---------------------------------------------------------------------------\n\nexport type ChatDecisionProps = {\n /** `open` shows the question; every other state shows `outcome` in its place. */\n state: ChatDecisionState;\n /** The question as one sentence, usually with `ReferenceChip`s. */\n sentence: JSX.Element;\n /** Why this question is asked, in the platform's words. */\n reason: ChatDecisionReason;\n /** The thing itself, usually `Chat.Preview`. */\n preview?: JSX.Element;\n /** The main answer, named by verb and target (\"Send to Lea\"). `danger` for deletions, `primary` for requests. */\n confirm: ChatDecisionAnswer & { variant?: \"ai\" | \"primary\" | \"danger\" };\n /** The other answer (\"Don't send\"). */\n decline: ChatDecisionAnswer;\n /** An optional quiet third answer after the buttons, such as \"Yes, and don't ask again in this chat\". */\n remember?: ChatDecisionAnswer;\n /** Turns `confirm` and `remember` off; this reason replaces `reason` in the same place. */\n unavailable?: ChatDecisionReason;\n /** The result line shown in every state but `open`, usually `Chat.Outcome`. */\n outcome?: JSX.Element;\n /** Receives a rejected promise from an answer's `onSelect`. */\n onAnswerError?: (error: unknown) => void;\n anchorId?: string | number;\n class?: string;\n};\n\n/** What an outcome inside a question needs from it: whether it was just answered here, and a link press inside it. */\nconst DecisionScope = createContext<{ answered: () => boolean; pressed: () => void; released: () => void }>();\n\nconst reasonIcon = (reason: ChatDecisionReason) => reason.icon ?? \"ti ti-info-circle\";\n\n/**\n * A question the person answers in the conversation: one sentence, why it is asked, the thing itself, and two answers.\n * An answer collapses it at once to its outcome line, which takes the focus and is announced.\n */\nexport function ChatDecision(props: ChatDecisionProps): JSX.Element {\n const id = createUniqueId();\n const sentenceId = `k2b-chat-decision-${id}-sentence`;\n const reasonId = `k2b-chat-decision-${id}-reason`;\n let root: HTMLDivElement | undefined;\n let sentence: HTMLParagraphElement | undefined;\n // An answer given here moves the focus to the outcome; a click in the outcome that reopens the question moves it\n // back to the sentence. A state change from elsewhere moves no focus.\n const [answeredHere, setAnsweredHere] = createSignal(false);\n const [arrive, setArrive] = createSignal(false);\n let reopenedHere = false;\n // A press counts only while its action runs: a reopen from elsewhere later must not take the focus.\n const scope = {\n answered: answeredHere,\n pressed: () => {\n reopenedHere = true;\n },\n released: () => {\n reopenedHere = false;\n },\n };\n\n // Read once: an object literal from the host builds its JSX again on every read.\n const reason = createMemo(() => props.unavailable ?? props.reason);\n const open = () => props.state === \"open\";\n\n const answer = (choice: ChatDecisionAnswer, enabled: boolean) => {\n if (!enabled || !open() || answeredHere()) return;\n setAnsweredHere(true);\n try {\n const result = choice.onSelect();\n if (result instanceof Promise) result.catch((error: unknown) => props.onAnswerError?.(error));\n } catch (error) {\n props.onAnswerError?.(error);\n }\n // A host that keeps the question open (it could not take the answer) gets working buttons back.\n queueMicrotask(() => {\n if (open()) setAnsweredHere(false);\n });\n };\n\n createEffect(\n on(\n () => props.state,\n (state, previous) => {\n if (state !== \"open\" && previous === \"open\" && answeredHere()) {\n root?.querySelector<HTMLElement>(\".k2b-chat-outcome\")?.focus({ preventScroll: true });\n }\n if (state === \"open\" && previous !== undefined && previous !== \"open\") {\n // A host that could not take an answer given here returns the question from `sending`; the outcome that held\n // the focus is gone, so the focus goes back to the sentence instead of the page.\n const active = document.activeElement;\n const failedHere = answeredHere() && previous === \"sending\" && (!active || active === document.body);\n setAnsweredHere(false);\n if (reopenedHere || failedHere) {\n sentence?.focus({ preventScroll: true });\n setArrive(true);\n }\n // Handled. Until then the marker holds through states in between, such as `sending` while a reopen loads.\n reopenedHere = false;\n }\n },\n ),\n );\n\n return (\n <div\n ref={root}\n class={`k2b-chat-decision ${props.class ?? \"\"}`}\n data-state={props.state}\n data-chat-anchor={props.anchorId !== undefined ? String(props.anchorId) : undefined}\n >\n <Show when={open()} fallback={<DecisionScope.Provider value={scope}>{props.outcome}</DecisionScope.Provider>}>\n <section class=\"k2b-chat-decision__card\" aria-labelledby={sentenceId} aria-describedby={reasonId}>\n <p\n ref={sentence}\n id={sentenceId}\n class=\"k2b-chat-decision__sentence\"\n tabindex=\"-1\"\n data-arrive={arrive() ? \"true\" : undefined}\n onAnimationEnd={() => setArrive(false)}\n >\n {props.sentence}\n </p>\n <p id={reasonId} class=\"k2b-chat-line k2b-chat-decision__reason\" data-tone={reason().tone ?? \"neutral\"}>\n <i class={`k2b-chat-line__icon ${reasonIcon(reason())}`} aria-hidden=\"true\" />\n <span class=\"k2b-chat-line__text\">{reason().text}</span>\n </p>\n {props.preview}\n <div class=\"k2b-chat-decision__answers\">\n <Button\n class=\"k2b-chat-decision__answer\"\n wrap\n variant={props.confirm.variant ?? \"ai\"}\n disabled={Boolean(props.unavailable)}\n onClick={() => answer(props.confirm, !props.unavailable)}\n >\n <Show when={props.confirm.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n {props.confirm.label}\n </Button>\n <Button class=\"k2b-chat-decision__answer\" wrap variant=\"subtle\" onClick={() => answer(props.decline, true)}>\n <Show when={props.decline.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n {props.decline.label}\n </Button>\n <Show when={props.remember}>\n {(remember) => (\n <Button\n class=\"k2b-chat-decision__remember\"\n wrap\n variant=\"text\"\n disabled={Boolean(props.unavailable)}\n onClick={() => answer(remember(), !props.unavailable)}\n >\n {remember().label}\n </Button>\n )}\n </Show>\n </div>\n </section>\n </Show>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Outcome\n// ---------------------------------------------------------------------------\n\nexport type ChatOutcomeProps = {\n /**\n * Every line one flow can show, such as running and done. All of them share one cell, so the line is as high as\n * the longest and switching between them moves nothing.\n */\n lines: Readonly<Record<string, ChatOutcomeLine>>;\n /** The key of the visible line. */\n current: string;\n /** Receives an error thrown or rejected by a line's `action`. */\n onActionError?: (error: unknown) => void;\n anchorId?: string | number;\n class?: string;\n};\n\nconst OUTCOME_ICONS: Record<ChatOutcomeTone, string> = {\n running: \"ti ti-loader-2 k2b-spin\",\n done: \"ti ti-check\",\n off: \"ti ti-circle-off\",\n waiting: \"ti ti-clock\",\n warning: \"ti ti-alert-triangle\",\n error: \"ti ti-alert-circle\",\n};\n\n/** The visible words of a line, without what screen readers do not hear. */\nconst spokenText = (element: Element): string => {\n const copy = element.cloneNode(true) as Element;\n // Buttons under the line are controls, not part of what happened.\n for (const hidden of copy.querySelectorAll('[aria-hidden=\"true\"], .k2b-chat-outcome__actions')) hidden.remove();\n // The time and the link stand apart by margin only; spoken, they need a space.\n for (const part of copy.querySelectorAll(\".k2b-chat-outcome__time, .k2b-chat-outcome__link\")) part.before(\" \");\n return (copy.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n};\n\n/**\n * One line that says what happened: running, done, off, waiting, warning, or error. Changes are announced through a\n * polite live region; the line itself can take the focus.\n */\nexport function ChatOutcome(props: ChatOutcomeProps): JSX.Element {\n const scope = useContext(DecisionScope);\n // Only a line that replaces a question just answered here fades in; history renders final.\n const entering = untrack(() => scope?.answered() ?? false);\n const [live, setLive] = createSignal(\"\");\n let root: HTMLDivElement | undefined;\n let cell: HTMLDivElement | undefined;\n let pending = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n // Read once: an object literal from the host builds its JSX again on every read.\n const lines = createMemo(() => props.lines);\n const line = () => lines()[props.current];\n const tone = () => line()?.tone ?? \"off\";\n const keys = () => {\n const all = Object.keys(lines());\n return all.includes(props.current) ? all : [props.current, ...all];\n };\n\n // Empty the region first, so the same words spoken again are a change too.\n const announce = () => {\n setLive(\"\");\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n const current = cell?.querySelector('[data-current=\"true\"]');\n setLive(current ? spokenText(current) : \"\");\n }, 40);\n };\n\n onMount(() => {\n if (untrack(() => scope?.answered())) announce();\n });\n createEffect(\n on(\n () => props.current,\n () => {\n // A link pressed in a line that is now hidden would leave the focus on an invisible button, which the browser\n // then drops to the page. The line itself keeps it instead.\n const active = document.activeElement;\n const hidden = active && cell?.contains(active) && !active.closest('[data-current=\"true\"]');\n if (hidden || (pending && active === document.body)) root?.focus({ preventScroll: true });\n announce();\n },\n { defer: true },\n ),\n );\n onCleanup(() => {\n if (timer) clearTimeout(timer);\n });\n\n return (\n <div\n ref={root}\n class={`k2b-chat-outcome ${props.class ?? \"\"}`}\n data-tone={tone()}\n data-chat-anchor={props.anchorId !== undefined ? String(props.anchorId) : undefined}\n data-enter={entering ? \"true\" : undefined}\n tabindex=\"-1\"\n >\n <span class=\"k2b-chat-outcome__icon\" aria-hidden=\"true\">\n <i class={line()?.icon ?? OUTCOME_ICONS[tone()]} />\n </span>\n {/* Busy is set on the words only: a live region inside a busy subtree would be held back. */}\n <div ref={cell} class=\"k2b-chat-outcome__cell\" aria-busy={tone() === \"running\" ? \"true\" : undefined}>\n <For each={keys()}>\n {(key) => {\n const entry = () => lines()[key];\n const current = () => key === props.current;\n return (\n <Show when={entry()}>\n {(item) => (\n <div\n class=\"k2b-chat-outcome__text\"\n data-current={current() ? \"true\" : undefined}\n aria-hidden={current() ? undefined : \"true\"}\n >\n {item().text}\n <Show when={item().detail}>\n {(detail) => (\n <>\n {\" \"}\n <span class=\"k2b-chat-outcome__detail\">{detail()}</span>\n </>\n )}\n </Show>\n <Show when={item().time}>{(time) => <span class=\"k2b-chat-outcome__time\">{time()}</span>}</Show>\n <Show when={item().action}>\n {(action) => (\n <Button\n class=\"k2b-chat-outcome__link\"\n wrap\n variant=\"text\"\n tabIndex={current() ? undefined : -1}\n onClick={() => {\n // A second press while the first is still running would repeat its work.\n if (pending) return;\n scope?.pressed();\n try {\n const result = action().onSelect();\n if (result instanceof Promise) {\n pending = true;\n result\n .catch((error: unknown) => props.onActionError?.(error))\n .finally(() => {\n pending = false;\n scope?.released();\n });\n return;\n }\n } catch (error) {\n props.onActionError?.(error);\n }\n scope?.released();\n }}\n >\n {action().label}\n </Button>\n )}\n </Show>\n {/* Every line keeps its buttons, hidden with its text, so the cell also reserves their row. */}\n <Show when={item().actions}>{(actions) => <div class=\"k2b-chat-outcome__actions\">{actions()}</div>}</Show>\n </div>\n )}\n </Show>\n );\n }}\n </For>\n </div>\n <span class=\"k2b-sr-only\" role=\"status\" aria-live=\"polite\">\n {live()}\n </span>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Preview\n// ---------------------------------------------------------------------------\n\nexport type ChatPreviewProps = { children: JSX.Element; class?: string };\n\n/** The thing a question is about, as calm text on the sentence's edge: no surface, no column. */\nfunction ChatPreviewRoot(props: ChatPreviewProps): JSX.Element {\n return <div class={`k2b-chat-preview ${props.class ?? \"\"}`}>{props.children}</div>;\n}\n\nexport type ChatPreviewHeaderProps = {\n /** One row per field, such as From, To, Cc, and Bcc; the label stands right before its value. */\n rows: readonly ChatPreviewHeaderRow[];\n /** A last line, such as when the message goes out. */\n note?: JSX.Element;\n};\n\nconst PreviewPeople = (props: { people: readonly ChatPreviewPerson[] }) => (\n <For each={props.people}>\n {(person, index) => (\n <>\n {index() > 0 ? \", \" : \"\"}\n <span class=\"k2b-chat-preview__person\">\n <Show when={person.name}>{(name) => <b>{name()}</b>}</Show>\n <Show when={person.address}>\n {(address) => (\n <span class=\"k2b-chat-preview__address\" data-alone={person.name ? undefined : \"true\"}>\n {address()}\n </span>\n )}\n </Show>\n </span>\n </>\n )}\n </For>\n);\n\nfunction ChatPreviewHeader(props: ChatPreviewHeaderProps): JSX.Element {\n return (\n <div class=\"k2b-chat-preview__header\">\n <dl>\n <For each={props.rows}>\n {(row) => (\n <div data-emphasis={row.emphasis ? \"true\" : undefined}>\n <dt>{row.label}</dt>\n <dd>\n <Show when={row.people}>{(people) => <PreviewPeople people={people()} />}</Show>\n {row.value}\n </dd>\n </div>\n )}\n </For>\n </dl>\n <Show when={props.note}>{(note) => <p>{note()}</p>}</Show>\n </div>\n );\n}\n\nexport type ChatPreviewTitleProps = { children: JSX.Element; meta?: JSX.Element };\n\n/** The thing's name in the text's own face, with optional quiet facts after it. */\nfunction ChatPreviewTitle(props: ChatPreviewTitleProps): JSX.Element {\n return (\n <p class=\"k2b-chat-preview__title-line\">\n <span class=\"k2b-chat-preview__title\">{props.children}</span>\n <Show when={props.meta}>\n {(meta) => (\n <>\n {\" \"}\n <span class=\"k2b-chat-preview__meta\">{meta()}</span>\n </>\n )}\n </Show>\n </p>\n );\n}\n\n/** A rule or instruction as one sentence, such as what a routine does; chips and marks may stand inside. */\nfunction ChatPreviewSentence(props: { children: JSX.Element }): JSX.Element {\n return <p class=\"k2b-chat-preview__sentence\">{props.children}</p>;\n}\n\nexport type ChatPreviewExcerptProps = {\n children: JSX.Element;\n /** Shows the whole text in place instead of the first lines, such as after `Chat.Preview.ShowAll`. */\n expanded?: boolean;\n id?: string;\n};\n\n/** The first lines of a longer text. It keeps its line breaks, shows about three lines, and fades out. */\nfunction ChatPreviewExcerpt(props: ChatPreviewExcerptProps): JSX.Element {\n return (\n <p\n class=\"k2b-chat-preview__excerpt\"\n id={props.id}\n data-expanded={props.expanded ? \"true\" : undefined}\n tabindex={props.expanded ? -1 : undefined}\n >\n {props.children}\n </p>\n );\n}\n\nexport type ChatPreviewShowAllProps = {\n /** The id of the `Chat.Preview.Excerpt` this button opens. */\n controls: string;\n onShow: () => void;\n children: JSX.Element;\n};\n\n/**\n * Shows the rest of an excerpt in place, for a text with no page of its own to open. It looks like `ReadMore`; the\n * caller removes it once the text is shown, and the focus moves to the text, so reading goes on where it was.\n */\nfunction ChatPreviewShowAll(props: ChatPreviewShowAllProps): JSX.Element {\n const show = () => {\n props.onShow();\n queueMicrotask(() => document.getElementById(props.controls)?.focus({ preventScroll: true }));\n };\n return (\n <button type=\"button\" class=\"k2b-chat-preview__more\" aria-controls={props.controls} aria-expanded=\"false\" onClick={show}>\n {props.children}\n </button>\n );\n}\n\nexport type ChatPreviewReadMoreProps = {\n href: string;\n children: JSX.Element;\n /** Tooltip, such as \"Opens exactly this version of the draft\". */\n title?: string;\n};\n\n/** Opens the whole thing at exactly the version the question shows. */\nfunction ChatPreviewReadMore(props: ChatPreviewReadMoreProps): JSX.Element {\n return (\n <a class=\"k2b-chat-preview__more\" href={props.href} title={props.title}>\n {props.children}\n </a>\n );\n}\n\nconst InList = createContext(false);\n\n/** A list of lines with a name, such as \"What the routine may do\". */\nfunction ChatPreviewLines(props: { label?: string; children: JSX.Element }): JSX.Element {\n return (\n <ul class=\"k2b-chat-preview__lines\" aria-label={props.label}>\n <InList.Provider value={true}>{props.children}</InList.Provider>\n </ul>\n );\n}\n\nexport type ChatPreviewLineProps = {\n /** Icon class; the text after it starts 1.5rem from the edge. */\n icon: string;\n /** Icon colour, such as the PDF colour of an attachment. */\n accent?: string;\n /** `muted` for limits and notes, `warning` for an application's own warning. */\n tone?: \"default\" | \"muted\" | \"warning\";\n /** Marks the whole line as new or removed. */\n mark?: \"added\" | \"removed\";\n /** Quiet facts after the text, such as a file size. */\n meta?: JSX.Element;\n children: JSX.Element;\n};\n\n/** One line led by an icon: a consequence, a right, an attachment, or a warning. */\nfunction ChatPreviewLine(props: ChatPreviewLineProps): JSX.Element {\n const inList = useContext(InList);\n const messages = useChatMessages();\n const content = () => (\n <>\n <i class={`k2b-chat-line__icon ${props.icon}`} style={props.accent ? { color: props.accent } : undefined} aria-hidden=\"true\" />\n <span class=\"k2b-chat-line__text\">\n {/* One stable wrapper, so marking a line later never moves its mounted children. */}\n <span class=\"k2b-chat-mark\" data-change={props.mark}>\n <Show when={props.mark}>\n {(mark) => <span class=\"k2b-sr-only\">{mark() === \"added\" ? messages().markAdded : messages().markRemoved} </span>}\n </Show>\n {props.children}\n </span>\n <Show when={props.meta}>\n {(meta) => (\n <>\n {\" \"}\n <span class=\"k2b-chat-preview__meta\">{meta()}</span>\n </>\n )}\n </Show>\n </span>\n </>\n );\n const attributes = () => ({\n class: \"k2b-chat-line k2b-chat-preview__line\",\n \"data-tone\": props.tone && props.tone !== \"default\" ? props.tone : undefined,\n });\n return inList ? <li {...attributes()}>{content()}</li> : <p {...attributes()}>{content()}</p>;\n}\n\nexport type ChatPreviewPeopleProps = {\n /** The first few people; their avatars overlap at the start of the line. */\n people: readonly { name: string; src?: string | null }[];\n /** The names as text, such as \"Lea Berg, Tom Weber and 3 others\". */\n children: JSX.Element;\n};\n\nfunction ChatPreviewPeople(props: ChatPreviewPeopleProps): JSX.Element {\n return (\n <p class=\"k2b-chat-preview__people\">\n <span class=\"k2b-chat-preview__faces\" aria-hidden=\"true\">\n <For each={props.people}>{(person) => <Avatar name={person.name} src={person.src} size=\"xs\" />}</For>\n </span>\n <span>{props.children}</span>\n </p>\n );\n}\n\nexport const ChatPreview = Object.assign(ChatPreviewRoot, {\n Header: ChatPreviewHeader,\n Title: ChatPreviewTitle,\n Sentence: ChatPreviewSentence,\n Excerpt: ChatPreviewExcerpt,\n ReadMore: ChatPreviewReadMore,\n ShowAll: ChatPreviewShowAll,\n Lines: ChatPreviewLines,\n Line: ChatPreviewLine,\n People: ChatPreviewPeople,\n});\n\n// ---------------------------------------------------------------------------\n// Mark\n// ---------------------------------------------------------------------------\n\nexport type ChatMarkProps = { change: \"added\" | \"removed\"; children: JSX.Element };\n\n/** Marks new or removed words; screen readers hear \"new:\" or \"removed:\" first. */\nexport function ChatMark(props: ChatMarkProps): JSX.Element {\n const messages = useChatMessages();\n return (\n <Show\n when={props.change === \"removed\"}\n fallback={\n <mark class=\"k2b-chat-mark\" data-change=\"added\">\n <span class=\"k2b-sr-only\">{messages().markAdded} </span>\n {props.children}\n </mark>\n }\n >\n <del class=\"k2b-chat-mark\" data-change=\"removed\">\n <span class=\"k2b-sr-only\">{messages().markRemoved} </span>\n {props.children}\n </del>\n </Show>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["chat/ChatDecision.tsx"],"sourcesContent":["import {\n createContext,\n createEffect,\n createMemo,\n createSignal,\n createUniqueId,\n For,\n type JSX,\n on,\n onCleanup,\n onMount,\n Show,\n untrack,\n useContext,\n} from \"solid-js\";\nimport { Button } from \"../actions/Button\";\nimport { Avatar } from \"../surfaces/Avatar\";\nimport { useChatMessages } from \"./chat-messages\";\nimport type {\n ChatDecisionAnswer,\n ChatDecisionReason,\n ChatDecisionState,\n ChatOutcomeLine,\n ChatOutcomeTone,\n ChatPreviewHeaderRow,\n ChatPreviewPerson,\n} from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Decision\n// ---------------------------------------------------------------------------\n\nexport type ChatDecisionProps = {\n /** `open` shows the question; every other state shows `outcome` in its place. */\n state: ChatDecisionState;\n /** The question as one sentence, usually with `ReferenceChip`s. */\n sentence: JSX.Element;\n /** Why this question is asked, in the platform's words. */\n reason: ChatDecisionReason;\n /** The thing itself, usually `Chat.Preview`. */\n preview?: JSX.Element;\n /** The main answer, named by verb and target (\"Send to Lea\"). `danger` for deletions, `primary` for requests. */\n confirm: ChatDecisionAnswer & { variant?: \"ai\" | \"primary\" | \"danger\" };\n /** The other answer (\"Don't send\"). */\n decline: ChatDecisionAnswer;\n /** An optional quiet third answer after the buttons, such as \"Yes, and don't ask again in this chat\". */\n remember?: ChatDecisionAnswer;\n /** Turns `confirm` and `remember` off; this reason replaces `reason` in the same place. */\n unavailable?: ChatDecisionReason;\n /** The result line shown in every state but `open`, usually `Chat.Outcome`. */\n outcome?: JSX.Element;\n /** Receives a rejected promise from an answer's `onSelect`. */\n onAnswerError?: (error: unknown) => void;\n anchorId?: string | number;\n class?: string;\n};\n\n/** What an outcome inside a question needs from it: whether it was just answered here, and a link press inside it. */\nconst DecisionScope = createContext<{ answered: () => boolean; pressed: () => void; released: () => void }>();\n\nconst reasonIcon = (reason: ChatDecisionReason) => reason.icon ?? \"ti ti-info-circle\";\n\n/**\n * A question the person answers in the conversation: one sentence, why it is asked, the thing itself, and two answers.\n * An answer collapses it at once to its outcome line, which takes the focus and is announced.\n */\nexport function ChatDecision(props: ChatDecisionProps): JSX.Element {\n const id = createUniqueId();\n const sentenceId = `k2b-chat-decision-${id}-sentence`;\n const reasonId = `k2b-chat-decision-${id}-reason`;\n let root: HTMLDivElement | undefined;\n let sentence: HTMLParagraphElement | undefined;\n // An answer given here moves the focus to the outcome; a click in the outcome that reopens the question moves it\n // back to the sentence. A state change from elsewhere moves no focus.\n const [answeredHere, setAnsweredHere] = createSignal(false);\n const [arrive, setArrive] = createSignal(false);\n let reopenedHere = false;\n // A press on the sentence focuses it too; only a focus moved there from elsewhere, such as a jump, lights it up.\n // The browser also focuses the sentence again when its window comes back; that is no arrival either.\n let sentencePressed = false;\n let sentenceHeldAcrossWindow = false;\n const windowLeft = () => {\n if (sentence && document.activeElement === sentence) sentenceHeldAcrossWindow = true;\n };\n onMount(() => {\n window.addEventListener(\"blur\", windowLeft);\n onCleanup(() => window.removeEventListener(\"blur\", windowLeft));\n });\n // A press counts only while its action runs: a reopen from elsewhere later must not take the focus.\n const scope = {\n answered: answeredHere,\n pressed: () => {\n reopenedHere = true;\n },\n released: () => {\n reopenedHere = false;\n },\n };\n\n // Read once: an object literal from the host builds its JSX again on every read.\n const reason = createMemo(() => props.unavailable ?? props.reason);\n const open = () => props.state === \"open\";\n\n const answer = (choice: ChatDecisionAnswer, enabled: boolean) => {\n if (!enabled || !open() || answeredHere()) return;\n setAnsweredHere(true);\n try {\n const result = choice.onSelect();\n if (result instanceof Promise) result.catch((error: unknown) => props.onAnswerError?.(error));\n } catch (error) {\n props.onAnswerError?.(error);\n }\n // A host that keeps the question open (it could not take the answer) gets working buttons back.\n queueMicrotask(() => {\n if (open()) setAnsweredHere(false);\n });\n };\n\n createEffect(\n on(\n () => props.state,\n (state, previous) => {\n if (state !== \"open\" && previous === \"open\" && answeredHere()) {\n root?.querySelector<HTMLElement>(\".k2b-chat-outcome\")?.focus({ preventScroll: true });\n }\n if (state === \"open\" && previous !== undefined && previous !== \"open\") {\n // A host that could not take an answer given here returns the question from `sending`; the outcome that held\n // the focus is gone, so the focus goes back to the sentence instead of the page.\n const active = document.activeElement;\n const failedHere = answeredHere() && previous === \"sending\" && (!active || active === document.body);\n setAnsweredHere(false);\n if (reopenedHere || failedHere) {\n sentence?.focus({ preventScroll: true });\n setArrive(true);\n }\n // Handled. Until then the marker holds through states in between, such as `sending` while a reopen loads.\n reopenedHere = false;\n }\n },\n ),\n );\n\n return (\n <div\n ref={root}\n class={`k2b-chat-decision ${props.class ?? \"\"}`}\n data-state={props.state}\n data-chat-anchor={props.anchorId !== undefined ? String(props.anchorId) : undefined}\n >\n <Show when={open()} fallback={<DecisionScope.Provider value={scope}>{props.outcome}</DecisionScope.Provider>}>\n <section class=\"k2b-chat-decision__card\" aria-labelledby={sentenceId} aria-describedby={reasonId}>\n <p\n ref={sentence}\n id={sentenceId}\n class=\"k2b-chat-decision__sentence\"\n tabindex=\"-1\"\n data-arrive={arrive() ? \"true\" : undefined}\n onPointerDown={() => {\n sentencePressed = true;\n }}\n onPointerUp={() => {\n sentencePressed = false;\n }}\n onPointerCancel={() => {\n sentencePressed = false;\n }}\n onFocus={() => {\n if (!sentencePressed && !sentenceHeldAcrossWindow) setArrive(true);\n sentencePressed = false;\n sentenceHeldAcrossWindow = false;\n }}\n onAnimationEnd={() => setArrive(false)}\n >\n {props.sentence}\n </p>\n <p id={reasonId} class=\"k2b-chat-line k2b-chat-decision__reason\" data-tone={reason().tone ?? \"neutral\"}>\n <i class={`k2b-chat-line__icon ${reasonIcon(reason())}`} aria-hidden=\"true\" />\n <span class=\"k2b-chat-line__text\">{reason().text}</span>\n </p>\n {props.preview}\n <div class=\"k2b-chat-decision__answers\">\n <Button\n class=\"k2b-chat-decision__answer\"\n wrap\n variant={props.confirm.variant ?? \"ai\"}\n disabled={Boolean(props.unavailable)}\n onClick={() => answer(props.confirm, !props.unavailable)}\n >\n <Show when={props.confirm.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n {props.confirm.label}\n </Button>\n <Button class=\"k2b-chat-decision__answer\" wrap variant=\"subtle\" onClick={() => answer(props.decline, true)}>\n <Show when={props.decline.icon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n {props.decline.label}\n </Button>\n <Show when={props.remember}>\n {(remember) => (\n <Button\n class=\"k2b-chat-decision__remember\"\n wrap\n variant=\"text\"\n disabled={Boolean(props.unavailable)}\n onClick={() => answer(remember(), !props.unavailable)}\n >\n {remember().label}\n </Button>\n )}\n </Show>\n </div>\n </section>\n </Show>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Outcome\n// ---------------------------------------------------------------------------\n\nexport type ChatOutcomeProps = {\n /**\n * Every line one flow can show, such as running and done. All of them share one cell, so the line is as high as\n * the longest and switching between them moves nothing.\n */\n lines: Readonly<Record<string, ChatOutcomeLine>>;\n /** The key of the visible line. */\n current: string;\n /** Receives an error thrown or rejected by a line's `action`. */\n onActionError?: (error: unknown) => void;\n anchorId?: string | number;\n class?: string;\n};\n\nconst OUTCOME_ICONS: Record<ChatOutcomeTone, string> = {\n running: \"ti ti-loader-2 k2b-spin\",\n done: \"ti ti-check\",\n off: \"ti ti-circle-off\",\n waiting: \"ti ti-clock\",\n warning: \"ti ti-alert-triangle\",\n error: \"ti ti-alert-circle\",\n};\n\n/** The visible words of a line, without what screen readers do not hear. */\nconst spokenText = (element: Element): string => {\n const copy = element.cloneNode(true) as Element;\n // Buttons under the line are controls, not part of what happened.\n for (const hidden of copy.querySelectorAll('[aria-hidden=\"true\"], .k2b-chat-outcome__actions')) hidden.remove();\n // The time and the link stand apart by margin only; spoken, they need a space.\n for (const part of copy.querySelectorAll(\".k2b-chat-outcome__time, .k2b-chat-outcome__link\")) part.before(\" \");\n return (copy.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n};\n\n/**\n * One line that says what happened: running, done, off, waiting, warning, or error. Changes are announced through a\n * polite live region; the line itself can take the focus.\n */\nexport function ChatOutcome(props: ChatOutcomeProps): JSX.Element {\n const scope = useContext(DecisionScope);\n // Only a line that replaces a question just answered here fades in; history renders final.\n const entering = untrack(() => scope?.answered() ?? false);\n const [live, setLive] = createSignal(\"\");\n let root: HTMLDivElement | undefined;\n let cell: HTMLDivElement | undefined;\n let pending = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n // Read once: an object literal from the host builds its JSX again on every read.\n const lines = createMemo(() => props.lines);\n const line = () => lines()[props.current];\n const tone = () => line()?.tone ?? \"off\";\n const keys = () => {\n const all = Object.keys(lines());\n return all.includes(props.current) ? all : [props.current, ...all];\n };\n\n // Empty the region first, so the same words spoken again are a change too.\n const announce = () => {\n setLive(\"\");\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n const current = cell?.querySelector('[data-current=\"true\"]');\n setLive(current ? spokenText(current) : \"\");\n }, 40);\n };\n\n onMount(() => {\n if (untrack(() => scope?.answered())) announce();\n });\n createEffect(\n on(\n () => props.current,\n () => {\n // A link pressed in a line that is now hidden would leave the focus on an invisible button, which the browser\n // then drops to the page. The line itself keeps it instead.\n const active = document.activeElement;\n const hidden = active && cell?.contains(active) && !active.closest('[data-current=\"true\"]');\n if (hidden || (pending && active === document.body)) root?.focus({ preventScroll: true });\n announce();\n },\n { defer: true },\n ),\n );\n onCleanup(() => {\n if (timer) clearTimeout(timer);\n });\n\n return (\n <div\n ref={root}\n class={`k2b-chat-outcome ${props.class ?? \"\"}`}\n data-tone={tone()}\n data-chat-anchor={props.anchorId !== undefined ? String(props.anchorId) : undefined}\n data-enter={entering ? \"true\" : undefined}\n tabindex=\"-1\"\n >\n <span class=\"k2b-chat-outcome__icon\" aria-hidden=\"true\">\n <i class={line()?.icon ?? OUTCOME_ICONS[tone()]} />\n </span>\n {/* Busy is set on the words only: a live region inside a busy subtree would be held back. */}\n <div ref={cell} class=\"k2b-chat-outcome__cell\" aria-busy={tone() === \"running\" ? \"true\" : undefined}>\n <For each={keys()}>\n {(key) => {\n const entry = () => lines()[key];\n const current = () => key === props.current;\n return (\n <Show when={entry()}>\n {(item) => (\n <div\n class=\"k2b-chat-outcome__text\"\n data-current={current() ? \"true\" : undefined}\n aria-hidden={current() ? undefined : \"true\"}\n >\n {item().text}\n <Show when={item().detail}>\n {(detail) => (\n <>\n {\" \"}\n <span class=\"k2b-chat-outcome__detail\">{detail()}</span>\n </>\n )}\n </Show>\n <Show when={item().time}>{(time) => <span class=\"k2b-chat-outcome__time\">{time()}</span>}</Show>\n <Show when={item().action}>\n {(action) => (\n <Button\n class=\"k2b-chat-outcome__link\"\n wrap\n variant=\"text\"\n tabIndex={current() ? undefined : -1}\n onClick={() => {\n // A second press while the first is still running would repeat its work.\n if (pending) return;\n scope?.pressed();\n try {\n const result = action().onSelect();\n if (result instanceof Promise) {\n pending = true;\n result\n .catch((error: unknown) => props.onActionError?.(error))\n .finally(() => {\n pending = false;\n scope?.released();\n });\n return;\n }\n } catch (error) {\n props.onActionError?.(error);\n }\n scope?.released();\n }}\n >\n {action().label}\n </Button>\n )}\n </Show>\n {/* Every line keeps its buttons, hidden with its text, so the cell also reserves their row. */}\n <Show when={item().actions}>{(actions) => <div class=\"k2b-chat-outcome__actions\">{actions()}</div>}</Show>\n </div>\n )}\n </Show>\n );\n }}\n </For>\n </div>\n <span class=\"k2b-sr-only\" role=\"status\" aria-live=\"polite\">\n {live()}\n </span>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Preview\n// ---------------------------------------------------------------------------\n\nexport type ChatPreviewProps = { children: JSX.Element; class?: string };\n\n/** The thing a question is about, as calm text on the sentence's edge: no surface, no column. */\nfunction ChatPreviewRoot(props: ChatPreviewProps): JSX.Element {\n return <div class={`k2b-chat-preview ${props.class ?? \"\"}`}>{props.children}</div>;\n}\n\nexport type ChatPreviewHeaderProps = {\n /** One row per field, such as From, To, Cc, and Bcc; the label stands right before its value. */\n rows: readonly ChatPreviewHeaderRow[];\n /** A last line, such as when the message goes out. */\n note?: JSX.Element;\n};\n\nconst PreviewPeople = (props: { people: readonly ChatPreviewPerson[] }) => (\n <For each={props.people}>\n {(person, index) => (\n <>\n {index() > 0 ? \", \" : \"\"}\n <span class=\"k2b-chat-preview__person\">\n <Show when={person.name}>{(name) => <b>{name()}</b>}</Show>\n <Show when={person.address}>\n {(address) => (\n <span class=\"k2b-chat-preview__address\" data-alone={person.name ? undefined : \"true\"}>\n {address()}\n </span>\n )}\n </Show>\n </span>\n </>\n )}\n </For>\n);\n\nfunction ChatPreviewHeader(props: ChatPreviewHeaderProps): JSX.Element {\n return (\n <div class=\"k2b-chat-preview__header\">\n <dl>\n <For each={props.rows}>\n {(row) => (\n <div data-emphasis={row.emphasis ? \"true\" : undefined}>\n <dt>{row.label}</dt>\n <dd>\n <Show when={row.people}>{(people) => <PreviewPeople people={people()} />}</Show>\n {row.value}\n </dd>\n </div>\n )}\n </For>\n </dl>\n <Show when={props.note}>{(note) => <p>{note()}</p>}</Show>\n </div>\n );\n}\n\nexport type ChatPreviewTitleProps = { children: JSX.Element; meta?: JSX.Element };\n\n/** The thing's name in the text's own face, with optional quiet facts after it. */\nfunction ChatPreviewTitle(props: ChatPreviewTitleProps): JSX.Element {\n return (\n <p class=\"k2b-chat-preview__title-line\">\n <span class=\"k2b-chat-preview__title\">{props.children}</span>\n <Show when={props.meta}>\n {(meta) => (\n <>\n {\" \"}\n <span class=\"k2b-chat-preview__meta\">{meta()}</span>\n </>\n )}\n </Show>\n </p>\n );\n}\n\n/** A rule or instruction as one sentence, such as what a routine does; chips and marks may stand inside. */\nfunction ChatPreviewSentence(props: { children: JSX.Element }): JSX.Element {\n return <p class=\"k2b-chat-preview__sentence\">{props.children}</p>;\n}\n\nexport type ChatPreviewExcerptProps = {\n children: JSX.Element;\n /** Shows the whole text in place instead of the first lines, such as after `Chat.Preview.ShowAll`. */\n expanded?: boolean;\n id?: string;\n};\n\n/** The first lines of a longer text. It keeps its line breaks, shows about three lines, and fades out. */\nfunction ChatPreviewExcerpt(props: ChatPreviewExcerptProps): JSX.Element {\n return (\n <p\n class=\"k2b-chat-preview__excerpt\"\n id={props.id}\n data-expanded={props.expanded ? \"true\" : undefined}\n tabindex={props.expanded ? -1 : undefined}\n >\n {props.children}\n </p>\n );\n}\n\nexport type ChatPreviewShowAllProps = {\n /** The id of the `Chat.Preview.Excerpt` this button opens. */\n controls: string;\n onShow: () => void;\n children: JSX.Element;\n};\n\n/**\n * Shows the rest of an excerpt in place, for a text with no page of its own to open. It looks like `ReadMore`; the\n * caller removes it once the text is shown, and the focus moves to the text, so reading goes on where it was.\n */\nfunction ChatPreviewShowAll(props: ChatPreviewShowAllProps): JSX.Element {\n const show = () => {\n props.onShow();\n queueMicrotask(() => document.getElementById(props.controls)?.focus({ preventScroll: true }));\n };\n return (\n <button type=\"button\" class=\"k2b-chat-preview__more\" aria-controls={props.controls} aria-expanded=\"false\" onClick={show}>\n {props.children}\n </button>\n );\n}\n\nexport type ChatPreviewReadMoreProps = {\n href: string;\n children: JSX.Element;\n /** Tooltip, such as \"Opens exactly this version of the draft\". */\n title?: string;\n};\n\n/** Opens the whole thing at exactly the version the question shows. */\nfunction ChatPreviewReadMore(props: ChatPreviewReadMoreProps): JSX.Element {\n return (\n <a class=\"k2b-chat-preview__more\" href={props.href} title={props.title}>\n {props.children}\n </a>\n );\n}\n\nconst InList = createContext(false);\n\n/** A list of lines with a name, such as \"What the routine may do\". */\nfunction ChatPreviewLines(props: { label?: string; children: JSX.Element }): JSX.Element {\n return (\n <ul class=\"k2b-chat-preview__lines\" aria-label={props.label}>\n <InList.Provider value={true}>{props.children}</InList.Provider>\n </ul>\n );\n}\n\nexport type ChatPreviewLineProps = {\n /** Icon class; the text after it starts 1.5rem from the edge. */\n icon: string;\n /** Icon colour, such as the PDF colour of an attachment. */\n accent?: string;\n /** `muted` for limits and notes, `warning` for an application's own warning. */\n tone?: \"default\" | \"muted\" | \"warning\";\n /** Marks the whole line as new or removed. */\n mark?: \"added\" | \"removed\";\n /** Quiet facts after the text, such as a file size. */\n meta?: JSX.Element;\n children: JSX.Element;\n};\n\n/** One line led by an icon: a consequence, a right, an attachment, or a warning. */\nfunction ChatPreviewLine(props: ChatPreviewLineProps): JSX.Element {\n const inList = useContext(InList);\n const messages = useChatMessages();\n const content = () => (\n <>\n <i class={`k2b-chat-line__icon ${props.icon}`} style={props.accent ? { color: props.accent } : undefined} aria-hidden=\"true\" />\n <span class=\"k2b-chat-line__text\">\n {/* One stable wrapper, so marking a line later never moves its mounted children. */}\n <span class=\"k2b-chat-mark\" data-change={props.mark}>\n <Show when={props.mark}>\n {(mark) => <span class=\"k2b-sr-only\">{mark() === \"added\" ? messages().markAdded : messages().markRemoved} </span>}\n </Show>\n {props.children}\n </span>\n <Show when={props.meta}>\n {(meta) => (\n <>\n {\" \"}\n <span class=\"k2b-chat-preview__meta\">{meta()}</span>\n </>\n )}\n </Show>\n </span>\n </>\n );\n const attributes = () => ({\n class: \"k2b-chat-line k2b-chat-preview__line\",\n \"data-tone\": props.tone && props.tone !== \"default\" ? props.tone : undefined,\n });\n return inList ? <li {...attributes()}>{content()}</li> : <p {...attributes()}>{content()}</p>;\n}\n\nexport type ChatPreviewPeopleProps = {\n /** The first few people; their avatars overlap at the start of the line. */\n people: readonly { name: string; src?: string | null }[];\n /** The names as text, such as \"Lea Berg, Tom Weber and 3 others\". */\n children: JSX.Element;\n};\n\nfunction ChatPreviewPeople(props: ChatPreviewPeopleProps): JSX.Element {\n return (\n <p class=\"k2b-chat-preview__people\">\n <span class=\"k2b-chat-preview__faces\" aria-hidden=\"true\">\n <For each={props.people}>{(person) => <Avatar name={person.name} src={person.src} size=\"xs\" />}</For>\n </span>\n <span>{props.children}</span>\n </p>\n );\n}\n\nexport const ChatPreview = Object.assign(ChatPreviewRoot, {\n Header: ChatPreviewHeader,\n Title: ChatPreviewTitle,\n Sentence: ChatPreviewSentence,\n Excerpt: ChatPreviewExcerpt,\n ReadMore: ChatPreviewReadMore,\n ShowAll: ChatPreviewShowAll,\n Lines: ChatPreviewLines,\n Line: ChatPreviewLine,\n People: ChatPreviewPeople,\n});\n\n// ---------------------------------------------------------------------------\n// Mark\n// ---------------------------------------------------------------------------\n\nexport type ChatMarkProps = { change: \"added\" | \"removed\"; children: JSX.Element };\n\n/** Marks new or removed words; screen readers hear \"new:\" or \"removed:\" first. */\nexport function ChatMark(props: ChatMarkProps): JSX.Element {\n const messages = useChatMessages();\n return (\n <Show\n when={props.change === \"removed\"}\n fallback={\n <mark class=\"k2b-chat-mark\" data-change=\"added\">\n <span class=\"k2b-sr-only\">{messages().markAdded} </span>\n {props.children}\n </mark>\n }\n >\n <del class=\"k2b-chat-mark\" data-change=\"removed\">\n <span class=\"k2b-sr-only\">{messages().markRemoved} </span>\n {props.children}\n </del>\n </Show>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|