@scalar/sidebar 0.8.8 → 0.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/components/ScalarSidebar.vue.d.ts +2 -2
  2. package/dist/components/SidebarItem.vue.d.ts +2 -2
  3. package/dist/components/SidebarItemLabel.vue.d.ts +1 -1
  4. package/dist/helpers/filter-items.d.ts +1 -1
  5. package/dist/helpers/has-children.d.ts +1 -1
  6. package/dist/helpers/is-sidebar-folder.d.ts +1 -1
  7. package/dist/index.d.ts +9 -9
  8. package/dist/index.js +832 -20
  9. package/dist/index.js.map +1 -0
  10. package/dist/style.css +4535 -1
  11. package/package.json +12 -18
  12. package/dist/_virtual/_plugin-vue_export-helper.js +0 -9
  13. package/dist/components/HttpMethod.vue.js +0 -30
  14. package/dist/components/HttpMethod.vue2.js +0 -4
  15. package/dist/components/ScalarSidebar.vue.js +0 -82
  16. package/dist/components/ScalarSidebar.vue2.js +0 -4
  17. package/dist/components/SidebarHttpBadge.vue.js +0 -7
  18. package/dist/components/SidebarHttpBadge.vue2.js +0 -41
  19. package/dist/components/SidebarItem.vue.js +0 -264
  20. package/dist/components/SidebarItem.vue2.js +0 -4
  21. package/dist/components/SidebarItemDecorator.vue.js +0 -12
  22. package/dist/components/SidebarItemLabel.vue.js +0 -22
  23. package/dist/components/SidebarItemLabel.vue2.js +0 -4
  24. package/dist/helpers/create-sidebar-state.js +0 -38
  25. package/dist/helpers/filter-items.js +0 -4
  26. package/dist/helpers/generate-reverse-index.js +0 -14
  27. package/dist/helpers/get-child-entry.js +0 -14
  28. package/dist/helpers/has-children.js +0 -4
  29. package/dist/helpers/is-sidebar-folder.js +0 -5
  30. package/dist/helpers/scroll-sidebar-to-top.js +0 -27
  31. package/dist/hooks/use-draggable.js +0 -82
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/components/HttpMethod.vue","../src/components/HttpMethod.vue","../src/helpers/filter-items.ts","../src/components/SidebarItemDecorator.vue","../src/helpers/has-children.ts","../src/helpers/is-sidebar-folder.ts","../src/hooks/use-draggable.ts","../src/components/SidebarHttpBadge.vue","../src/components/SidebarHttpBadge.vue","../src/components/SidebarItemLabel.vue","../src/components/SidebarItemLabel.vue","../src/components/SidebarItem.vue","../src/components/SidebarItem.vue","../src/components/ScalarSidebar.vue","../src/components/ScalarSidebar.vue","../src/helpers/generate-reverse-index.ts","../src/helpers/create-sidebar-state.ts","../src/helpers/get-child-entry.ts","../src/helpers/scroll-sidebar-to-top.ts"],"sourcesContent":["<script setup lang=\"ts\">\nimport { getHttpMethodInfo } from '@scalar/helpers/http/http-info'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { normalizeHttpMethod } from '@scalar/helpers/http/normalize-http-method'\nimport { computed, type Component } from 'vue'\n\nconst props = defineProps<{\n /** The type of element to render as, defaults to `span` */\n as?: Component | string\n /** The css style property or variable that will be set to the request method color, defaults to `color` */\n property?: string\n /** Whether or not to abbreviated the slot content */\n short?: boolean\n /** The HTTP method to show */\n method: HttpMethod | string\n}>()\n\n/** Grabs the method info object which contains abbreviation, color, and background color etc */\nconst httpMethodInfo = computed(() =>\n getHttpMethodInfo(String(props.method || '')),\n)\n\n/** Full method name */\nconst normalized = computed(() => normalizeHttpMethod(props.method))\n</script>\n\n<template>\n <component\n :is=\"as ?? 'span'\"\n class=\"uppercase\"\n :style=\"{ [property || 'color']: httpMethodInfo.colorVar }\">\n <slot />\n {{ short ? httpMethodInfo.short : normalized }}\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { getHttpMethodInfo } from '@scalar/helpers/http/http-info'\nimport type { HttpMethod } from '@scalar/helpers/http/http-methods'\nimport { normalizeHttpMethod } from '@scalar/helpers/http/normalize-http-method'\nimport { computed, type Component } from 'vue'\n\nconst props = defineProps<{\n /** The type of element to render as, defaults to `span` */\n as?: Component | string\n /** The css style property or variable that will be set to the request method color, defaults to `color` */\n property?: string\n /** Whether or not to abbreviated the slot content */\n short?: boolean\n /** The HTTP method to show */\n method: HttpMethod | string\n}>()\n\n/** Grabs the method info object which contains abbreviation, color, and background color etc */\nconst httpMethodInfo = computed(() =>\n getHttpMethodInfo(String(props.method || '')),\n)\n\n/** Full method name */\nconst normalized = computed(() => normalizeHttpMethod(props.method))\n</script>\n\n<template>\n <component\n :is=\"as ?? 'span'\"\n class=\"uppercase\"\n :style=\"{ [property || 'color']: httpMethodInfo.colorVar }\">\n <slot />\n {{ short ? httpMethodInfo.short : normalized }}\n </component>\n</template>\n","import type { Item, Layout } from '@/types'\n\n/** The type of items we want to */\nconst API_CLIENT_TYPES_SET = new Set(['document', 'operation', 'example', 'tag'])\n\nexport const filterItems = (layout: Layout, items: Item[]) => {\n if (layout === 'reference') {\n return items\n }\n\n // For client layout, filter to only show documents, operations, examples, and tags\n return items.filter((c) => API_CLIENT_TYPES_SET.has(c.type))\n}\n","<template>\n <div\n class=\"bg-b-2 absolute top-[1lh] right-0.75 flex -translate-y-1/2 rounded border p-0.25 opacity-0 peer-hover/button:opacity-100 peer-focus-visible/button:opacity-100 focus-within:opacity-100 hover:opacity-100 has-[&[aria-expanded=true]]:opacity-100\">\n <slot />\n </div>\n</template>\n","import type { Item } from '@/types'\n\n/**\n * Type guard to check if the given Item has a non-empty array of children.\n * Returns true if `currentItem` has a `children` property that is an array with at least one element.\n */\nexport const hasChildren = (currentItem: Item): currentItem is Item & { children: Item[] } => {\n return 'children' in currentItem && Array.isArray(currentItem.children) && currentItem.children.length > 0\n}\n","import { hasChildren } from '@/helpers/has-children'\nimport type { Item, Layout } from '@/types'\n\n/**\n * Determines if a sidebar item should be treated as a \"folder\",\n * i.e. a collapsible group, depending on the layout, its type,\n * whether it has children, and special slot rules.\n *\n * @param layout - The sidebar layout ('client' or 'reference')\n * @param item - The sidebar item to check\n * @param hasEmptySlot - True if there is an empty slot to display as a group (client layout only)\n * @returns True if the item should be rendered as a folder/group node\n */\nexport const isSidebarFolder = (\n layout: Layout,\n item: Item,\n hasEmptySlot: boolean,\n): item is Item & { children?: Item[] } => {\n // If the item has no children, check if there is an empty slot.\n if (!hasChildren(item)) {\n // In 'client' layout, allow \"document\" or \"tag\" items to act as group if there's an empty slot\n if (layout === 'client' && hasEmptySlot) {\n return item.type === 'document' || item.type === 'tag'\n }\n // Otherwise, not a folder if it has no children\n return false\n }\n\n // 'client' layout: any item with children is a folder\n if (layout === 'client') {\n return true\n }\n\n // 'reference' layout: only non-'operation' and non-'webhook' are groups/folders\n if (layout === 'reference') {\n return item.type !== 'operation' && item.type !== 'webhook'\n }\n\n // Fallback: not a folder in other cases/layouts\n return false\n}\n","import { cva } from '@scalar/use-hooks/useBindCx'\nimport { type MaybeRef, type Ref, computed, ref, toValue } from 'vue'\n\n/**\n * Drag offsets\n */\nexport type DragOffset =\n | 'before' // Insert before the hovered item\n | 'after' // Insert after the hovered item\n | 'into' // Drop into the hovered item\n | null\n\n/**\n * Item you are currently dragging over\n */\nexport type HoveredItem = {\n id: string\n parentId: string | null\n offset: DragOffset\n}\n\n/**\n * Item you are currently dragging\n */\nexport type DraggingItem = Omit<HoveredItem, 'offset'>\n\n/**\n * Simple throttle function to avoid package dependencies\n */\nconst throttle = <TArgs extends Array<unknown>>(\n callback: (...args: TArgs) => void,\n limit: number,\n): ((...args: TArgs) => void) => {\n let wait = false\n\n return (...args: TArgs) => {\n if (wait) {\n return\n }\n\n callback(...args)\n wait = true\n setTimeout(() => (wait = false), limit)\n }\n}\n\n/** Draggable class variants to apply to the draggable element */\nconst draggableVariants = cva({\n base: 'relative after:absolute after:inset-x-0 after:block after:bg-blue after:opacity-15 after:pointer-events-none after:rounded',\n variants: {\n position: {\n before: 'after:-top-0.5 after:h-0.75',\n after: 'after:-bottom-0.5 after:h-0.75',\n into: 'after:inset-0',\n } as const satisfies Record<NonNullable<DragOffset>, string>,\n },\n})\n\n/**\n * Shared state for drag and drop operations\n * These are module-level refs so all draggable instances share the same state\n */\nconst draggingItem = ref<DraggingItem | null>(null)\nconst hoveredItem = ref<HoveredItem | null>(null)\n\nexport type UseDraggableOptions = {\n /**\n * Upper threshold (gets multiplied with height)\n *\n * @default 0.8\n */\n ceiling?: number\n /**\n * Lower threshold (gets multiplied with height)\n *\n * @default 0.2\n */\n floor?: number\n /**\n * Enable dragging. Can be a reactive ref or computed.\n *\n * @default true\n */\n isDraggable?: MaybeRef<boolean>\n /**\n * Prevents items from being hovered and dropped into. Can be either a function or a boolean\n *\n * @default true\n */\n isDroppable?: MaybeRef<boolean> | ((draggingItem: DraggingItem, hoveredItem: HoveredItem) => boolean)\n /**\n * We pass an array of parents to make it easier to reverse traverse\n */\n parentIds?: string[]\n /**\n * ID for the current item\n */\n id: string\n /**\n * Callback when drag starts\n */\n onDragStart?: (draggingItem: DraggingItem) => void\n /**\n * Callback when drag ends\n */\n onDragEnd?: (draggingItem: DraggingItem, hoveredItem: HoveredItem) => void\n}\n\n/**\n * Composable for handling drag and drop functionality\n */\nexport function useDraggable(options: UseDraggableOptions) {\n const {\n ceiling = 0.8,\n floor = 0.2,\n isDraggable = true,\n isDroppable = true,\n parentIds = [],\n id,\n onDragStart,\n onDragEnd,\n } = options\n\n // The latest parentId in the arr should be the current parent\n const parentId = computed(() => parentIds.at(-1) ?? null)\n\n /** Check if isDroppable guard */\n const _isDroppable = (offset: DragOffset): boolean =>\n typeof isDroppable === 'function'\n ? isDroppable(draggingItem.value!, {\n id: id,\n parentId: parentId.value,\n offset,\n })\n : toValue(isDroppable)\n\n // Start dragging, we want to store the uid + parentUid\n const handleDragStart = (ev: DragEvent) => {\n if (!toValue(isDraggable) || !ev.dataTransfer || !(ev.target instanceof HTMLElement)) {\n return\n }\n\n ev.target.setAttribute('data-dragging', 'true')\n ev.dataTransfer.dropEffect = 'move'\n ev.dataTransfer.effectAllowed = 'move'\n\n // Store dragging item\n const item = { id: id, parentId: parentId.value }\n draggingItem.value = item\n onDragStart?.(item)\n }\n\n // On dragging over we decide which highlight to show\n const handleDragOver = throttle((ev: DragEvent) => {\n // Don't highlight if hovering over self or child\n if (!draggingItem.value || draggingItem.value.id === id || parentIds.includes(draggingItem.value?.id ?? '')) {\n return\n }\n\n const previousOffset = hoveredItem.value?.offset\n const height = (ev.target as HTMLDivElement).offsetHeight\n const _floor = floor * height\n const _ceiling = ceiling * height\n let offset: DragOffset = null\n\n // handle negative offset to be previous offset\n if (ev.offsetY <= 0 && previousOffset && previousOffset !== 'after') {\n offset = previousOffset\n }\n // Above\n else if (ev.offsetY <= _floor) {\n offset = 'before'\n }\n // Below\n else if (ev.offsetY >= _ceiling) {\n offset = 'after'\n }\n // between\n else if (ev.offsetY > _floor && ev.offsetY < _ceiling) {\n offset = 'into'\n }\n\n // Hover guard\n if (!_isDroppable(offset)) {\n return\n }\n\n hoveredItem.value = { id: id, parentId: parentId.value, offset }\n }, 25)\n\n const handleDragEnd = () => {\n if (!hoveredItem.value || !draggingItem.value) {\n return\n }\n\n const _draggingItem = { ...draggingItem.value }\n const _hoveredItem = { ...hoveredItem.value }\n\n // Remove hover and dragging\n draggingItem.value = null\n hoveredItem.value = null\n document.querySelectorAll('[data-dragging]').forEach((el) => el.removeAttribute('data-dragging'))\n\n if (_draggingItem.id === _hoveredItem.id) {\n return\n }\n\n onDragEnd?.(_draggingItem, _hoveredItem)\n }\n\n const draggableClass = computed(() => {\n const position = id === hoveredItem.value?.id ? hoveredItem.value.offset : undefined\n\n if (!position) {\n return ''\n }\n\n return draggableVariants({ position })\n })\n\n /**\n * Props object to bind to the draggable element.\n * Contains the class and draggable attribute.\n */\n const draggableAttrs = computed(() => ({\n class: draggableClass.value || undefined,\n // Only set the draggable attribute if isDraggable is true\n draggable: toValue(isDraggable) ? true : undefined,\n }))\n\n return {\n /**\n * Props object to bind to the draggable element.\n * Contains the class and draggable attribute.\n */\n draggableAttrs,\n /**\n * Event handlers object to bind to the draggable element.\n * Contains dragend, dragover, and dragstart handlers with proper event prevention.\n */\n draggableEvents: {\n dragend: handleDragEnd,\n dragover: (ev: DragEvent) => {\n ev.preventDefault()\n ev.stopPropagation()\n handleDragOver(ev)\n },\n dragstart: (ev: DragEvent) => {\n ev.stopPropagation()\n handleDragStart(ev)\n },\n },\n draggingItem: draggingItem as Readonly<Ref<DraggingItem | null>>,\n hoveredItem: hoveredItem as Readonly<Ref<HoveredItem | null>>,\n }\n}\n","<script setup lang=\"ts\">\nimport { getHttpMethodInfo } from '@scalar/helpers/http/http-info'\nimport { ScalarIconWebhooksLogo } from '@scalar/icons'\n\nimport HttpMethod from './HttpMethod.vue'\n\ndefineProps<{\n method: string\n active?: boolean\n webhook?: boolean\n}>()\n</script>\n<template>\n <HttpMethod\n :class=\"[\n 'sidebar-heading-type',\n `sidebar-heading-type--${method.toLowerCase()}`,\n { 'sidebar-heading-type-active': active },\n ]\"\n :method=\"method\"\n property=\"--method-color\"\n short>\n <span class=\"sr-only\">HTTP Method:&nbsp;</span>\n <slot>\n <ScalarIconWebhooksLogo\n v-if=\"webhook\"\n :style=\"{\n color: getHttpMethodInfo(method).colorVar,\n }\"\n weight=\"bold\" />\n </slot>\n </HttpMethod>\n</template>\n\n<style scoped>\n.sidebar-heading-type {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n overflow: hidden;\n line-height: 14px;\n flex-shrink: 0;\n text-transform: uppercase;\n color: var(--method-color, var(--scalar-color-1));\n font-size: 10px;\n font-weight: var(--scalar-bold);\n font-family: var(--scalar-font-code);\n white-space: nowrap;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { getHttpMethodInfo } from '@scalar/helpers/http/http-info'\nimport { ScalarIconWebhooksLogo } from '@scalar/icons'\n\nimport HttpMethod from './HttpMethod.vue'\n\ndefineProps<{\n method: string\n active?: boolean\n webhook?: boolean\n}>()\n</script>\n<template>\n <HttpMethod\n :class=\"[\n 'sidebar-heading-type',\n `sidebar-heading-type--${method.toLowerCase()}`,\n { 'sidebar-heading-type-active': active },\n ]\"\n :method=\"method\"\n property=\"--method-color\"\n short>\n <span class=\"sr-only\">HTTP Method:&nbsp;</span>\n <slot>\n <ScalarIconWebhooksLogo\n v-if=\"webhook\"\n :style=\"{\n color: getHttpMethodInfo(method).colorVar,\n }\"\n weight=\"bold\" />\n </slot>\n </HttpMethod>\n</template>\n\n<style scoped>\n.sidebar-heading-type {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n overflow: hidden;\n line-height: 14px;\n flex-shrink: 0;\n text-transform: uppercase;\n color: var(--method-color, var(--scalar-color-1));\n font-size: 10px;\n font-weight: var(--scalar-bold);\n font-family: var(--scalar-font-code);\n white-space: nowrap;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { ScalarWrappingText } from '@scalar/components'\n\nimport type { Item } from '@/types'\n\nconst { item } = defineProps<{\n /**\n * The sidebar item to render.\n */\n item: Item\n /**\n * The source of the operation title.\n */\n operationTitleSource?: 'path' | 'summary'\n}>()\n</script>\n<template>\n <template v-if=\"item.type === 'model'\">\n <ScalarWrappingText\n preset=\"property\"\n :text=\"item.title\" />\n </template>\n <template v-else>\n <ScalarWrappingText\n :text=\"\n operationTitleSource === 'path' && 'path' in item\n ? (item.path as string)\n : (item.title as string)\n \" />\n </template>\n</template>\n","<script lang=\"ts\" setup>\nimport { ScalarWrappingText } from '@scalar/components'\n\nimport type { Item } from '@/types'\n\nconst { item } = defineProps<{\n /**\n * The sidebar item to render.\n */\n item: Item\n /**\n * The source of the operation title.\n */\n operationTitleSource?: 'path' | 'summary'\n}>()\n</script>\n<template>\n <template v-if=\"item.type === 'model'\">\n <ScalarWrappingText\n preset=\"property\"\n :text=\"item.title\" />\n </template>\n <template v-else>\n <ScalarWrappingText\n :text=\"\n operationTitleSource === 'path' && 'path' in item\n ? (item.path as string)\n : (item.title as string)\n \" />\n </template>\n</template>\n","<script lang=\"ts\" setup>\nimport {\n ScalarSidebarGroup,\n ScalarSidebarItem,\n ScalarSidebarSection,\n} from '@scalar/components'\nimport { LibraryIcon } from '@scalar/icons/library'\n\nimport SidebarItemDecorator from '@/components/SidebarItemDecorator.vue'\nimport { filterItems } from '@/helpers/filter-items'\nimport { hasChildren } from '@/helpers/has-children'\nimport { isSidebarFolder } from '@/helpers/is-sidebar-folder'\nimport {\n useDraggable,\n type DraggingItem,\n type HoveredItem,\n type UseDraggableOptions,\n} from '@/hooks/use-draggable'\nimport type { Item, Layout } from '@/types'\n\nimport SidebarHttpBadge from './SidebarHttpBadge.vue'\nimport SidebarItemLabel from './SidebarItemLabel.vue'\n\nconst { item, layout, isSelected, isExpanded, isDraggable, isDroppable } =\n defineProps<{\n /**\n * The sidebar item to render.\n */\n item: Item\n /**\n * The layout mode for the sidebar ('client' or 'reference').\n */\n layout: Layout\n /**\n * Function to determine if an item is currently selected by id.\n */\n isSelected: (id: string) => boolean\n /**\n * Function to determine if an item is currently expanded (showing its children) by id.\n */\n isExpanded: (id: string) => boolean\n /**\n * Sidebar configuration options.\n * - operationTitleSource: sets whether operations show their path or summary as the display title.\n */\n options:\n | {\n operationTitleSource: 'path' | 'summary' | undefined\n }\n | undefined\n\n /**\n * Prevents this item from being dragged.\n *\n * @default true\n */\n isDraggable?: UseDraggableOptions['isDraggable']\n /**\n * Prevents this item from being hovered and dropped into. Can be either a function or a boolean.\n *\n * @default true\n */\n isDroppable?: UseDraggableOptions['isDroppable']\n }>()\n\nconst emit = defineEmits<{\n /**\n * Emitted when the item is selected\n * @param id - The id of the selected item\n */\n (e: 'selectItem', id: string): void\n /**\n * Emitted when a drag operation ends for this item\n * @param draggingItem - The item being dragged\n * @param hoveredItem - The item currently being hovered over\n */\n (e: 'onDragEnd', draggingItem: DraggingItem, hoveredItem: HoveredItem): void\n\n /**\n * Emitted when the group is toggled\n * @param id - The id of the group\n */\n (e: 'toggleGroup', id: string): void\n}>()\n\nconst slots = defineSlots<{\n /**\n * Adds an optional decorator for each item, such as an edit menu.\n * The slot receives an object with the current item.\n */\n decorator?(props: { item: Item }): unknown\n /**\n * Adds an optional empty state for an item.\n * The slot receives an object with the current item.\n */\n empty?(props: { item: Item }): unknown\n /**\n * Adds an optional icon for each item.\n * The slot receives an object with the current item and the open state.\n */\n icon?(props: { item: Item; open: boolean }): unknown\n}>()\n\nconst isGroup = (\n currentItem: Item,\n): currentItem is Item & { isGroup: true } => {\n return 'isGroup' in currentItem && currentItem.isGroup\n}\n\nconst isDeprecated = (\n currentItem: Item,\n): currentItem is Item & { isDeprecated: true } => {\n return ('isDeprecated' in currentItem && currentItem.isDeprecated) ?? false\n}\n\n/**\n * Handle drag end event and bubble it up to parent.\n */\nconst onDragEnd = (draggingItem: DraggingItem, hoveredItem: HoveredItem) => {\n emit('onDragEnd', draggingItem, hoveredItem)\n}\nconst { draggableAttrs, draggableEvents } = useDraggable({\n id: item.id,\n isDraggable,\n isDroppable,\n onDragEnd,\n})\n</script>\n<template>\n <!-- Sidebar section -->\n <ScalarSidebarSection\n v-if=\"hasChildren(item) && isGroup(item)\"\n :data-sidebar-id=\"item.id\"\n v-bind=\"draggableAttrs\"\n v-on=\"draggableEvents\">\n {{ item.title }}\n <template #items>\n <SidebarItem\n v-for=\"child in filterItems(layout, item.children)\"\n :key=\"child.id\"\n :isDraggable=\"isDraggable\"\n :isDroppable=\"isDroppable\"\n :isExpanded=\"isExpanded\"\n :isSelected=\"isSelected\"\n :item=\"child\"\n :layout=\"layout\"\n :options=\"options\"\n @onDragEnd=\"onDragEnd\"\n @selectItem=\"(id) => emit('selectItem', id)\"\n @toggleGroup=\"(id) => emit('toggleGroup', id)\">\n <template\n v-if=\"slots.decorator\"\n #decorator=\"slotProps\">\n <slot\n v-bind=\"slotProps\"\n name=\"decorator\" />\n </template>\n <template\n v-if=\"slots.empty\"\n #empty=\"slotProps\">\n <slot\n v-bind=\"slotProps\"\n name=\"empty\" />\n </template>\n <template\n v-if=\"slots.icon\"\n #icon=\"slotProps\">\n <slot\n v-bind=\"slotProps\"\n name=\"icon\" />\n </template>\n </SidebarItem>\n </template>\n </ScalarSidebarSection>\n\n <!-- Sidebar group (folder) -->\n <ScalarSidebarGroup\n v-else-if=\"isSidebarFolder(layout, item, slots.empty !== undefined)\"\n :active=\"isSelected(item.id)\"\n class=\"relative\"\n controlled\n :data-sidebar-id=\"item.id\"\n v-bind=\"draggableAttrs\"\n :discrete=\"layout === 'reference' && item.type === 'text'\"\n :open=\"isExpanded(item.id)\"\n v-on=\"draggableEvents\"\n @click=\"() => emit('selectItem', item.id)\"\n @toggle=\"() => emit('toggleGroup', item.id)\">\n <template\n v-if=\"item.type === 'document'\"\n #icon=\"{ open }\">\n <slot\n :item=\"item\"\n name=\"icon\"\n :open=\"open\">\n <LibraryIcon\n class=\"block\"\n :src=\"('icon' in item && item.icon) || 'interface-content-folder'\" />\n </slot>\n </template>\n <span\n v-if=\"isDeprecated(item)\"\n class=\"line-through\">\n <SidebarItemLabel\n :item\n :operationTitleSource=\"options?.operationTitleSource\" />\n </span>\n <SidebarItemLabel\n v-else\n :item\n :operationTitleSource=\"options?.operationTitleSource\" />\n <template\n v-if=\"'method' in item\"\n #aside>\n <SidebarHttpBadge\n :active=\"isSelected(item.id)\"\n class=\"mr-1 ml-2 h-4 self-start\"\n :class=\"{\n // Hide the badge when we're showing the decorator\n 'group-hover/button:opacity-0 group-focus-visible/button:opacity-0 group-has-[~*_[aria-expanded=true]]/button:opacity-0 group-has-[~*:focus-within]/button:opacity-0 group-has-[~*:hover]/button:opacity-0':\n slots.decorator,\n }\"\n :method=\"item.method\"\n :webhook=\"item.type === 'webhook'\" />\n </template>\n <template\n v-if=\"slots.decorator\"\n #after>\n <SidebarItemDecorator>\n <slot\n :item\n name=\"decorator\" />\n </SidebarItemDecorator>\n </template>\n <template #items>\n <SidebarItem\n v-for=\"child in filterItems(layout, item.children ?? [])\"\n :key=\"child.id\"\n :isDraggable=\"isDraggable\"\n :isDroppable=\"isDroppable\"\n :isExpanded=\"isExpanded\"\n :isSelected=\"isSelected\"\n :item=\"child\"\n :layout=\"layout\"\n :options=\"options\"\n :parentIds=\"[]\"\n @onDragEnd=\"onDragEnd\"\n @selectItem=\"(id) => emit('selectItem', id)\"\n @toggleGroup=\"(id) => emit('toggleGroup', id)\">\n <template\n v-if=\"slots.decorator\"\n #decorator=\"slotProps\">\n <slot\n v-bind=\"slotProps\"\n name=\"decorator\" />\n </template>\n <template\n v-if=\"slots.empty\"\n #empty=\"slotProps\">\n <slot\n v-bind=\"slotProps\"\n name=\"empty\" />\n </template>\n <template\n v-if=\"slots.icon\"\n #icon=\"slotProps\">\n <slot\n v-bind=\"slotProps\"\n name=\"icon\" />\n </template>\n </SidebarItem>\n <template v-if=\"slots.empty && (item.children?.length ?? 0) === 0\">\n <slot\n :item\n name=\"empty\" />\n </template>\n </template>\n </ScalarSidebarGroup>\n\n <!-- Sidebar item (leaf node) -->\n <ScalarSidebarItem\n is=\"button\"\n v-else\n v-bind=\"draggableAttrs\"\n class=\"relative\"\n :data-sidebar-id=\"item.id\"\n :selected=\"isSelected(item.id)\"\n v-on=\"draggableEvents\"\n @click=\"() => emit('selectItem', item.id)\">\n <template\n v-if=\"slots.icon\"\n #icon>\n <slot\n :item=\"item\"\n name=\"icon\"\n :open=\"true\" />\n </template>\n <span\n v-if=\"isDeprecated(item)\"\n class=\"line-through\">\n <SidebarItemLabel\n :item\n :operationTitleSource=\"options?.operationTitleSource\" />\n </span>\n <SidebarItemLabel\n v-else\n :item\n :operationTitleSource=\"options?.operationTitleSource\" />\n <template\n v-if=\"'method' in item\"\n #aside>\n <SidebarHttpBadge\n v-if=\"'method' in item\"\n :active=\"isSelected(item.id)\"\n class=\"ml-2 h-4 self-start\"\n :class=\"{\n // Hide the badge when we're showing the decorator\n 'group-hover/button:opacity-0 group-focus-visible/button:opacity-0 group-has-[~*_[aria-expanded=true]]/button:opacity-0 group-has-[~*:focus-within]/button:opacity-0 group-has-[~*:hover]/button:opacity-0':\n slots.decorator,\n }\"\n :method=\"item.method\"\n :webhook=\"item.type === 'webhook'\" />\n </template>\n <template\n v-if=\"slots.decorator\"\n #after>\n <SidebarItemDecorator>\n <slot\n :item\n name=\"decorator\" />\n </SidebarItemDecorator>\n </template>\n </ScalarSidebarItem>\n</template>\n","<script lang=\"ts\" setup>\nimport {\n ScalarSidebarGroup,\n ScalarSidebarItem,\n ScalarSidebarSection,\n} from '@scalar/components'\nimport { LibraryIcon } from '@scalar/icons/library'\n\nimport SidebarItemDecorator from '@/components/SidebarItemDecorator.vue'\nimport { filterItems } from '@/helpers/filter-items'\nimport { hasChildren } from '@/helpers/has-children'\nimport { isSidebarFolder } from '@/helpers/is-sidebar-folder'\nimport {\n useDraggable,\n type DraggingItem,\n type HoveredItem,\n type UseDraggableOptions,\n} from '@/hooks/use-draggable'\nimport type { Item, Layout } from '@/types'\n\nimport SidebarHttpBadge from './SidebarHttpBadge.vue'\nimport SidebarItemLabel from './SidebarItemLabel.vue'\n\nconst { item, layout, isSelected, isExpanded, isDraggable, isDroppable } =\n defineProps<{\n /**\n * The sidebar item to render.\n */\n item: Item\n /**\n * The layout mode for the sidebar ('client' or 'reference').\n */\n layout: Layout\n /**\n * Function to determine if an item is currently selected by id.\n */\n isSelected: (id: string) => boolean\n /**\n * Function to determine if an item is currently expanded (showing its children) by id.\n */\n isExpanded: (id: string) => boolean\n /**\n * Sidebar configuration options.\n * - operationTitleSource: sets whether operations show their path or summary as the display title.\n */\n options:\n | {\n operationTitleSource: 'path' | 'summary' | undefined\n }\n | undefined\n\n /**\n * Prevents this item from being dragged.\n *\n * @default true\n */\n isDraggable?: UseDraggableOptions['isDraggable']\n /**\n * Prevents this item from being hovered and dropped into. Can be either a function or a boolean.\n *\n * @default true\n */\n isDroppable?: UseDraggableOptions['isDroppable']\n }>()\n\nconst emit = defineEmits<{\n /**\n * Emitted when the item is selected\n * @param id - The id of the selected item\n */\n (e: 'selectItem', id: string): void\n /**\n * Emitted when a drag operation ends for this item\n * @param draggingItem - The item being dragged\n * @param hoveredItem - The item currently being hovered over\n */\n (e: 'onDragEnd', draggingItem: DraggingItem, hoveredItem: HoveredItem): void\n\n /**\n * Emitted when the group is toggled\n * @param id - The id of the group\n */\n (e: 'toggleGroup', id: string): void\n}>()\n\nconst slots = defineSlots<{\n /**\n * Adds an optional decorator for each item, such as an edit menu.\n * The slot receives an object with the current item.\n */\n decorator?(props: { item: Item }): unknown\n /**\n * Adds an optional empty state for an item.\n * The slot receives an object with the current item.\n */\n empty?(props: { item: Item }): unknown\n /**\n * Adds an optional icon for each item.\n * The slot receives an object with the current item and the open state.\n */\n icon?(props: { item: Item; open: boolean }): unknown\n}>()\n\nconst isGroup = (\n currentItem: Item,\n): currentItem is Item & { isGroup: true } => {\n return 'isGroup' in currentItem && currentItem.isGroup\n}\n\nconst isDeprecated = (\n currentItem: Item,\n): currentItem is Item & { isDeprecated: true } => {\n return ('isDeprecated' in currentItem && currentItem.isDeprecated) ?? false\n}\n\n/**\n * Handle drag end event and bubble it up to parent.\n */\nconst onDragEnd = (draggingItem: DraggingItem, hoveredItem: HoveredItem) => {\n emit('onDragEnd', draggingItem, hoveredItem)\n}\nconst { draggableAttrs, draggableEvents } = useDraggable({\n id: item.id,\n isDraggable,\n isDroppable,\n onDragEnd,\n})\n</script>\n<template>\n <!-- Sidebar section -->\n <ScalarSidebarSection\n v-if=\"hasChildren(item) && isGroup(item)\"\n :data-sidebar-id=\"item.id\"\n v-bind=\"draggableAttrs\"\n v-on=\"draggableEvents\">\n {{ item.title }}\n <template #items>\n <SidebarItem\n v-for=\"child in filterItems(layout, item.children)\"\n :key=\"child.id\"\n :isDraggable=\"isDraggable\"\n :isDroppable=\"isDroppable\"\n :isExpanded=\"isExpanded\"\n :isSelected=\"isSelected\"\n :item=\"child\"\n :layout=\"layout\"\n :options=\"options\"\n @onDragEnd=\"onDragEnd\"\n @selectItem=\"(id) => emit('selectItem', id)\"\n @toggleGroup=\"(id) => emit('toggleGroup', id)\">\n <template\n v-if=\"slots.decorator\"\n #decorator=\"slotProps\">\n <slot\n v-bind=\"slotProps\"\n name=\"decorator\" />\n </template>\n <template\n v-if=\"slots.empty\"\n #empty=\"slotProps\">\n <slot\n v-bind=\"slotProps\"\n name=\"empty\" />\n </template>\n <template\n v-if=\"slots.icon\"\n #icon=\"slotProps\">\n <slot\n v-bind=\"slotProps\"\n name=\"icon\" />\n </template>\n </SidebarItem>\n </template>\n </ScalarSidebarSection>\n\n <!-- Sidebar group (folder) -->\n <ScalarSidebarGroup\n v-else-if=\"isSidebarFolder(layout, item, slots.empty !== undefined)\"\n :active=\"isSelected(item.id)\"\n class=\"relative\"\n controlled\n :data-sidebar-id=\"item.id\"\n v-bind=\"draggableAttrs\"\n :discrete=\"layout === 'reference' && item.type === 'text'\"\n :open=\"isExpanded(item.id)\"\n v-on=\"draggableEvents\"\n @click=\"() => emit('selectItem', item.id)\"\n @toggle=\"() => emit('toggleGroup', item.id)\">\n <template\n v-if=\"item.type === 'document'\"\n #icon=\"{ open }\">\n <slot\n :item=\"item\"\n name=\"icon\"\n :open=\"open\">\n <LibraryIcon\n class=\"block\"\n :src=\"('icon' in item && item.icon) || 'interface-content-folder'\" />\n </slot>\n </template>\n <span\n v-if=\"isDeprecated(item)\"\n class=\"line-through\">\n <SidebarItemLabel\n :item\n :operationTitleSource=\"options?.operationTitleSource\" />\n </span>\n <SidebarItemLabel\n v-else\n :item\n :operationTitleSource=\"options?.operationTitleSource\" />\n <template\n v-if=\"'method' in item\"\n #aside>\n <SidebarHttpBadge\n :active=\"isSelected(item.id)\"\n class=\"mr-1 ml-2 h-4 self-start\"\n :class=\"{\n // Hide the badge when we're showing the decorator\n 'group-hover/button:opacity-0 group-focus-visible/button:opacity-0 group-has-[~*_[aria-expanded=true]]/button:opacity-0 group-has-[~*:focus-within]/button:opacity-0 group-has-[~*:hover]/button:opacity-0':\n slots.decorator,\n }\"\n :method=\"item.method\"\n :webhook=\"item.type === 'webhook'\" />\n </template>\n <template\n v-if=\"slots.decorator\"\n #after>\n <SidebarItemDecorator>\n <slot\n :item\n name=\"decorator\" />\n </SidebarItemDecorator>\n </template>\n <template #items>\n <SidebarItem\n v-for=\"child in filterItems(layout, item.children ?? [])\"\n :key=\"child.id\"\n :isDraggable=\"isDraggable\"\n :isDroppable=\"isDroppable\"\n :isExpanded=\"isExpanded\"\n :isSelected=\"isSelected\"\n :item=\"child\"\n :layout=\"layout\"\n :options=\"options\"\n :parentIds=\"[]\"\n @onDragEnd=\"onDragEnd\"\n @selectItem=\"(id) => emit('selectItem', id)\"\n @toggleGroup=\"(id) => emit('toggleGroup', id)\">\n <template\n v-if=\"slots.decorator\"\n #decorator=\"slotProps\">\n <slot\n v-bind=\"slotProps\"\n name=\"decorator\" />\n </template>\n <template\n v-if=\"slots.empty\"\n #empty=\"slotProps\">\n <slot\n v-bind=\"slotProps\"\n name=\"empty\" />\n </template>\n <template\n v-if=\"slots.icon\"\n #icon=\"slotProps\">\n <slot\n v-bind=\"slotProps\"\n name=\"icon\" />\n </template>\n </SidebarItem>\n <template v-if=\"slots.empty && (item.children?.length ?? 0) === 0\">\n <slot\n :item\n name=\"empty\" />\n </template>\n </template>\n </ScalarSidebarGroup>\n\n <!-- Sidebar item (leaf node) -->\n <ScalarSidebarItem\n is=\"button\"\n v-else\n v-bind=\"draggableAttrs\"\n class=\"relative\"\n :data-sidebar-id=\"item.id\"\n :selected=\"isSelected(item.id)\"\n v-on=\"draggableEvents\"\n @click=\"() => emit('selectItem', item.id)\">\n <template\n v-if=\"slots.icon\"\n #icon>\n <slot\n :item=\"item\"\n name=\"icon\"\n :open=\"true\" />\n </template>\n <span\n v-if=\"isDeprecated(item)\"\n class=\"line-through\">\n <SidebarItemLabel\n :item\n :operationTitleSource=\"options?.operationTitleSource\" />\n </span>\n <SidebarItemLabel\n v-else\n :item\n :operationTitleSource=\"options?.operationTitleSource\" />\n <template\n v-if=\"'method' in item\"\n #aside>\n <SidebarHttpBadge\n v-if=\"'method' in item\"\n :active=\"isSelected(item.id)\"\n class=\"ml-2 h-4 self-start\"\n :class=\"{\n // Hide the badge when we're showing the decorator\n 'group-hover/button:opacity-0 group-focus-visible/button:opacity-0 group-has-[~*_[aria-expanded=true]]/button:opacity-0 group-has-[~*:focus-within]/button:opacity-0 group-has-[~*:hover]/button:opacity-0':\n slots.decorator,\n }\"\n :method=\"item.method\"\n :webhook=\"item.type === 'webhook'\" />\n </template>\n <template\n v-if=\"slots.decorator\"\n #after>\n <SidebarItemDecorator>\n <slot\n :item\n name=\"decorator\" />\n </SidebarItemDecorator>\n </template>\n </ScalarSidebarItem>\n</template>\n","<script setup lang=\"ts\">\nimport { ScalarSidebar, ScalarSidebarItems } from '@scalar/components'\n\nimport { filterItems } from '@/helpers/filter-items'\nimport type {\n DraggingItem,\n HoveredItem,\n UseDraggableOptions,\n} from '@/hooks/use-draggable'\nimport type { Item, Layout } from '@/types'\n\nimport SidebarItem from './SidebarItem.vue'\n\nconst {\n layout,\n items,\n indent = 20,\n} = defineProps<{\n /**\n * Layout type for the sidebar.\n * Determines whether the sidebar should behave in 'client' or 'reference' mode.\n */\n layout: Layout\n /**\n * List of items to render in the sidebar.\n */\n items: Item[]\n /**\n * Function to determine whether a given item (by id) is currently selected.\n */\n isSelected: (id: string) => boolean\n /**\n * Function to determine whether a given item (by id) is currently expanded (open to show children).\n */\n isExpanded: (id: string) => boolean\n /**\n * Sidebar configuration options.\n * - operationTitleSource: sets whether operations show their path or summary as the display title.\n */\n options?: {\n operationTitleSource: 'path' | 'summary' | undefined\n }\n /**\n * The indentation in pixels to apply to nested items/groups in the sidebar.\n */\n indent?: number\n /**\n * Prevents this item from being dragged.\n *\n * @default true\n */\n isDraggable?: UseDraggableOptions['isDraggable']\n /**\n * Prevents this item from being hovered and dropped into. Can be either a function or a boolean.\n *\n * @default true\n */\n isDroppable?: UseDraggableOptions['isDroppable']\n}>()\n\nconst emit = defineEmits<{\n /**\n * Emitted when the user reorders sidebar items via drag-and-drop.\n * @param draggingItem - The item being dragged.\n * @param hoveredItem - The item currently being hovered over.\n */\n (e: 'reorder', draggingItem: DraggingItem, hoveredItem: HoveredItem): void\n\n /**\n * Emitted when a sidebar item is selected.\n * @param id - The id of the selected item.\n */\n (e: 'selectItem', id: string): void\n\n /**\n * Emitted when the group is toggled.\n * @param id - The id of the group.\n */\n (e: 'toggleGroup', id: string): void\n}>()\n\nconst slots = defineSlots<{\n /** Overrides the main items list */\n default?(): unknown\n /** Adds an optional decorator for each item like an edit menu */\n decorator?(props: { item: Item }): unknown\n /** Places content at the top of the sidebar outside of the items list */\n header?(): unknown\n /** Places content between the header and the items list */\n spacer?(): unknown\n /** Places content at the bottom of the sidebar outside of the items list */\n footer?(): unknown\n /** Places content before the first item in the items list */\n before?(): unknown\n /** Places content when an item is empty */\n empty?(props: { item: Item }): unknown\n /** Places content when an item is empty */\n icon?(props: { item: Item; open: boolean }): unknown\n}>()\n\n/**\n * Handle drag and drop reordering of sidebar items.\n * Emit the reorder event to the parent component for handling.\n */\nconst handleDragEnd = (\n draggingItem: DraggingItem,\n hoveredItem: HoveredItem,\n) => {\n emit('reorder', draggingItem, hoveredItem)\n}\n</script>\n<template>\n <ScalarSidebar\n class=\"flex min-h-0 flex-col\"\n :style=\"{ '--scalar-sidebar-indent': indent + 'px' }\">\n <slot name=\"header\" />\n <slot>\n <ScalarSidebarItems class=\"custom-scroll\">\n <!-- First item -->\n <slot name=\"before\" />\n <SidebarItem\n v-for=\"item in filterItems(layout, items)\"\n :key=\"item.id\"\n :isDraggable=\"isDraggable ?? layout === 'client'\"\n :isDroppable=\"isDroppable\"\n :isExpanded=\"isExpanded\"\n :isSelected=\"isSelected\"\n :item=\"item\"\n :layout=\"layout\"\n :options=\"options\"\n @onDragEnd=\"handleDragEnd\"\n @selectItem=\"(id) => emit('selectItem', id)\"\n @toggleGroup=\"(id) => emit('toggleGroup', id)\">\n <template\n v-if=\"slots.decorator\"\n #decorator=\"props\">\n <slot\n name=\"decorator\"\n v-bind=\"props\" />\n </template>\n <template\n v-if=\"slots.empty\"\n #empty=\"props\">\n <slot\n name=\"empty\"\n v-bind=\"props\" />\n </template>\n <template\n v-if=\"slots.icon\"\n #icon=\"props\">\n <slot\n name=\"icon\"\n v-bind=\"props\" />\n </template>\n </SidebarItem>\n </ScalarSidebarItems>\n <!-- Spacer -->\n <slot name=\"spacer\">\n <div class=\"flex-1\"></div>\n </slot>\n </slot>\n <slot name=\"footer\" />\n </ScalarSidebar>\n</template>\n","<script setup lang=\"ts\">\nimport { ScalarSidebar, ScalarSidebarItems } from '@scalar/components'\n\nimport { filterItems } from '@/helpers/filter-items'\nimport type {\n DraggingItem,\n HoveredItem,\n UseDraggableOptions,\n} from '@/hooks/use-draggable'\nimport type { Item, Layout } from '@/types'\n\nimport SidebarItem from './SidebarItem.vue'\n\nconst {\n layout,\n items,\n indent = 20,\n} = defineProps<{\n /**\n * Layout type for the sidebar.\n * Determines whether the sidebar should behave in 'client' or 'reference' mode.\n */\n layout: Layout\n /**\n * List of items to render in the sidebar.\n */\n items: Item[]\n /**\n * Function to determine whether a given item (by id) is currently selected.\n */\n isSelected: (id: string) => boolean\n /**\n * Function to determine whether a given item (by id) is currently expanded (open to show children).\n */\n isExpanded: (id: string) => boolean\n /**\n * Sidebar configuration options.\n * - operationTitleSource: sets whether operations show their path or summary as the display title.\n */\n options?: {\n operationTitleSource: 'path' | 'summary' | undefined\n }\n /**\n * The indentation in pixels to apply to nested items/groups in the sidebar.\n */\n indent?: number\n /**\n * Prevents this item from being dragged.\n *\n * @default true\n */\n isDraggable?: UseDraggableOptions['isDraggable']\n /**\n * Prevents this item from being hovered and dropped into. Can be either a function or a boolean.\n *\n * @default true\n */\n isDroppable?: UseDraggableOptions['isDroppable']\n}>()\n\nconst emit = defineEmits<{\n /**\n * Emitted when the user reorders sidebar items via drag-and-drop.\n * @param draggingItem - The item being dragged.\n * @param hoveredItem - The item currently being hovered over.\n */\n (e: 'reorder', draggingItem: DraggingItem, hoveredItem: HoveredItem): void\n\n /**\n * Emitted when a sidebar item is selected.\n * @param id - The id of the selected item.\n */\n (e: 'selectItem', id: string): void\n\n /**\n * Emitted when the group is toggled.\n * @param id - The id of the group.\n */\n (e: 'toggleGroup', id: string): void\n}>()\n\nconst slots = defineSlots<{\n /** Overrides the main items list */\n default?(): unknown\n /** Adds an optional decorator for each item like an edit menu */\n decorator?(props: { item: Item }): unknown\n /** Places content at the top of the sidebar outside of the items list */\n header?(): unknown\n /** Places content between the header and the items list */\n spacer?(): unknown\n /** Places content at the bottom of the sidebar outside of the items list */\n footer?(): unknown\n /** Places content before the first item in the items list */\n before?(): unknown\n /** Places content when an item is empty */\n empty?(props: { item: Item }): unknown\n /** Places content when an item is empty */\n icon?(props: { item: Item; open: boolean }): unknown\n}>()\n\n/**\n * Handle drag and drop reordering of sidebar items.\n * Emit the reorder event to the parent component for handling.\n */\nconst handleDragEnd = (\n draggingItem: DraggingItem,\n hoveredItem: HoveredItem,\n) => {\n emit('reorder', draggingItem, hoveredItem)\n}\n</script>\n<template>\n <ScalarSidebar\n class=\"flex min-h-0 flex-col\"\n :style=\"{ '--scalar-sidebar-indent': indent + 'px' }\">\n <slot name=\"header\" />\n <slot>\n <ScalarSidebarItems class=\"custom-scroll\">\n <!-- First item -->\n <slot name=\"before\" />\n <SidebarItem\n v-for=\"item in filterItems(layout, items)\"\n :key=\"item.id\"\n :isDraggable=\"isDraggable ?? layout === 'client'\"\n :isDroppable=\"isDroppable\"\n :isExpanded=\"isExpanded\"\n :isSelected=\"isSelected\"\n :item=\"item\"\n :layout=\"layout\"\n :options=\"options\"\n @onDragEnd=\"handleDragEnd\"\n @selectItem=\"(id) => emit('selectItem', id)\"\n @toggleGroup=\"(id) => emit('toggleGroup', id)\">\n <template\n v-if=\"slots.decorator\"\n #decorator=\"props\">\n <slot\n name=\"decorator\"\n v-bind=\"props\" />\n </template>\n <template\n v-if=\"slots.empty\"\n #empty=\"props\">\n <slot\n name=\"empty\"\n v-bind=\"props\" />\n </template>\n <template\n v-if=\"slots.icon\"\n #icon=\"props\">\n <slot\n name=\"icon\"\n v-bind=\"props\" />\n </template>\n </SidebarItem>\n </ScalarSidebarItems>\n <!-- Spacer -->\n <slot name=\"spacer\">\n <div class=\"flex-1\"></div>\n </slot>\n </slot>\n <slot name=\"footer\" />\n </ScalarSidebar>\n</template>\n","/**\n * Builds a reverse index for fast ID-based lookup and attaches a `parent` property to each node for upward traversal.\n *\n * @template T - The node type (must include `id`).\n * @template Key - The key pointing to nested children arrays (defaults to 'children').\n *\n * @param items - The root-level array of entities to index.\n * @param nestedKey - The property name that contains child nodes within an entity (defaults to 'children').\n * @param filter - Optional. A predicate to determine which nodes are included in the map (default: includes all).\n * @param getId - Optional. A function to obtain the unique ID from a node (defaults to `node.id`).\n * @returns A Map where each key is a node's ID and each value is the node, extended with an optional `parent` property.\n *\n * @example\n * const data = [\n * { id: '1', name: 'Root', children: [\n * { id: '2', name: 'Child 1' },\n * { id: '3', name: 'Child 2', children: [\n * { id: '4', name: 'Grandchild' }\n * ]}\n * ]}\n * ];\n * const index = generateReverseIndex({ items: data });\n * // index.get('3') => { id: '3', name: 'Child 2', children: [...], parent: { id: '1', ... } }\n * // index.get('4') => { id: '4', name: 'Grandchild', parent: { id: '3', ... } }\n */\nexport const generateReverseIndex = <T extends { id: string } & Record<string, unknown>, Key extends string>({\n items,\n nestedKey = 'children' as Key,\n filter = () => true,\n getId = (node: T) => node.id,\n}: {\n items: T[]\n nestedKey?: Key\n filter?: (node: T) => boolean\n getId?: (node: T) => string\n}) => {\n // Create a mapping from id to node (with parent reference)\n const mapping = new Map<string, T & { parent?: T }>()\n\n const dfs = (node: T & { parent?: T }) => {\n if (filter(node)) {\n mapping.set(getId(node), node)\n }\n\n if (nestedKey in node && Array.isArray(node[nestedKey])) {\n // Recursively traverse children and add the current node as their parent\n node[nestedKey]?.forEach((it) => dfs({ ...it, parent: node }))\n }\n }\n\n items.forEach(dfs)\n\n return mapping\n}\n","import { type MaybeRefOrGetter, computed, ref, toValue } from 'vue'\n\nimport { generateReverseIndex } from './generate-reverse-index'\n\ntype SidebarStateOptions = Partial<{\n /** The key used to access child items in the sidebar tree. Defaults to \"children\". */\n key: string\n /** Optional event hooks for sidebar item lifecycle */\n hooks: Partial<{\n /**\n * Called before an item is expanded.\n * @param id - The ID of the item to expand.\n */\n onBeforeExpand: (id: string) => void\n /**\n * Called after an item is expanded.\n * @param id - The ID of the item that was expanded.\n */\n onAfterExpand: (id: string) => void\n /**\n * Called just before a sidebar item selection changes.\n * @param id - The ID of the item that is about to be selected, or null if deselecting.\n */\n onBeforeSelect: (id: string | null) => void\n /**\n * Called immediately after a sidebar item has been selected.\n * @param id - The ID of the item that was selected, or null if selection was cleared.\n */\n onAfterSelect: (id: string | null) => void\n }>\n}>\n\n/**\n * Creates and manages the state for a sidebar tree, including selection and expansion of items.\n *\n * @template T - The type of sidebar items, which must include an `id` property.\n * @param items - The array of sidebar items.\n * @param options - Optional configuration for customizing behavior and hooks.\n * @returns An object containing sidebar state and methods to manipulate it.\n *\n * ## Example Usage\n *\n * ```ts\n * // Example sidebar items\n * const sidebarItems = [\n * { id: 'root', label: 'Root', children: [\n * { id: 'child1', label: 'Child 1' },\n * { id: 'child2', label: 'Child 2', children: [\n * { id: 'grandchild1', label: 'Grandchild 1' }\n * ]}\n * ]}\n * ]\n *\n * // Create sidebar state\n * const sidebarState = createSidebarState(sidebarItems, {\n * key: 'children',\n * hooks: {\n * onBeforeSelect: (id) => console.log('Before select:', id),\n * onAfterSelect: (id) => console.log('After select:', id),\n * onBeforeExpand: (id) => console.log('Before expand:', id),\n * onAfterExpand: (id) => console.log('After expand:', id),\n * }\n * })\n *\n * // Select an item\n * await sidebarState.setSelected('grandchild1')\n * // Expand an item\n * await sidebarState.setExpanded('child2', true)\n * ```\n */\nexport const createSidebarState = <T extends { id: string }>(\n items: MaybeRefOrGetter<T[]>,\n options?: SidebarStateOptions,\n) => {\n // Reverse index for quick lookup of items and their parents\n const index = computed(() =>\n generateReverseIndex({\n items: toValue(items),\n nestedKey: options?.key ?? 'children',\n }),\n )\n // Reactive record of selected item ids\n const selectedItems = ref<Record<string, boolean>>({})\n // Reactive record of expanded item ids\n const expandedItems = ref<Record<string, boolean>>({})\n\n // Lowest level selected item\n const selectedItem = ref<string | null>(null)\n\n /**\n * Selects the given item by id, and recursively marks all its parent items as selected.\n * Triggers optional lifecycle hooks before and after selection.\n *\n * @param id - The ID of the item to select.\n *\n * ## Example\n * ```ts\n * await sidebarState.setSelected('grandchild1')\n * // selectedItems.value will include 'grandchild1', 'child2', and 'root'\n * ```\n */\n const setSelected = (id: string | null) => {\n /**\n * Recursively mark all parent items as selected.\n * @param node - The current node to mark as selected.\n */\n const markSelected = (node: (T & { parent?: T }) | undefined) => {\n if (!node) {\n return\n }\n selectedItems.value[node.id] = true\n if ('parent' in node && node.parent) {\n markSelected(node.parent)\n }\n }\n\n // Call onBeforeSelect hook if provided\n if (options?.hooks?.onBeforeSelect) {\n options.hooks.onBeforeSelect(id)\n }\n\n // Clear previous selection\n selectedItems.value = {}\n selectedItem.value = id\n\n // If id is null, do not select anything\n // We already cleared the selection above\n if (id !== null) {\n // Mark the selected item and all its parents as selected\n markSelected(index.value.get(id))\n }\n\n // Call onAfterSelect hook if provided\n if (options?.hooks?.onAfterSelect) {\n options.hooks.onAfterSelect(id)\n }\n }\n\n /**\n * Expands or collapses the given item by id.\n * When expanding, recursively expands all parent items.\n * Triggers optional lifecycle hooks before and after expansion.\n *\n * @param id - The ID of the item to expand or collapse.\n * @param value - true to expand, false to collapse.\n *\n * ## Example\n * ```ts\n * await sidebarState.setExpanded('child2', true)\n * // expandedItems.value will include 'child2' and 'root'\n *\n * await sidebarState.setExpanded('child2', false)\n * // expandedItems.value['child2'] will be false\n * ```\n */\n const setExpanded = (id: string, value: boolean) => {\n /**\n * Recursively expand all parent items of the given node.\n * @param node - The current node to expand.\n */\n const openParents = (node: (T & { parent?: T }) | undefined) => {\n if (!node) {\n return\n }\n expandedItems.value[node.id] = true\n if ('parent' in node && node.parent) {\n openParents(node.parent)\n }\n }\n\n // Call onBeforeExpand hook if provided\n if (options?.hooks?.onBeforeExpand) {\n options.hooks.onBeforeExpand(id)\n }\n\n // When collapsing, only collapse the specified item, not its parents\n if (value === false) {\n expandedItems.value[id] = false\n } else {\n // When expanding, ensure all parents are expanded as well\n openParents(index.value.get(id))\n }\n\n // Call onAfterExpand hook if provided\n if (options?.hooks?.onAfterExpand) {\n options.hooks.onAfterExpand(id)\n }\n }\n\n const isExpanded = (id: string) => {\n return expandedItems.value[id] ?? false\n }\n\n const isSelected = (id: string) => {\n return selectedItems.value[id] ?? false\n }\n\n const getEntryById = (id: string) => index.value.get(id)\n\n return {\n items: computed(() => toValue(items)),\n index,\n selectedItems,\n expandedItems,\n selectedItem,\n setSelected,\n setExpanded,\n isExpanded,\n isSelected,\n getEntryById,\n reset: () => {\n selectedItems.value = {}\n expandedItems.value = {}\n },\n }\n}\n\nexport type SidebarState<Item extends { id: string }> = ReturnType<typeof createSidebarState<Item>>\n","import type { TraversedEntry } from '@scalar/workspace-store/schemas/navigation'\n\n/**\n * Recursively searches for and returns the first child node (including the given node itself)\n * of a specific type within the provided node's subtree.\n *\n * @template Type - The type of node to search for.\n * @param type - The node type to match.\n * @param node - The root node to begin searching from.\n * @returns The first child node of the specified type, or null if not found.\n */\nexport const getChildEntry = <Type extends TraversedEntry['type']>(\n type: Type,\n node: TraversedEntry,\n): (TraversedEntry & { type: Type }) | null => {\n if (node.type === type) {\n return node as TraversedEntry & { type: Type }\n }\n\n if ('children' in node) {\n for (const child of node.children ?? []) {\n const result = getChildEntry(type, child)\n\n if (result) {\n return result\n }\n }\n }\n\n return null\n}\n","const DEFAULT_SCROLL_OFFSET_TOP = 100\n\n/**\n * Returns the element that should be used for vertical position measurement.\n */\nconst getMeasurableElement = (element: HTMLElement): HTMLElement => {\n if (window.getComputedStyle(element).display !== 'contents') {\n return element\n }\n\n /**\n * `display: contents` does not render a layout box, so use the first child with\n * a measurable offset to keep the scroll target aligned with what users see.\n */\n for (const child of element.children) {\n if (child instanceof HTMLElement && child.offsetParent !== null) {\n return child\n }\n }\n\n return element\n}\n\n/**\n * Adds extra offset for heading rows so the selected item stays visible below labels.\n */\nconst getHeadingOffset = (element: HTMLElement): number => {\n if (element.dataset.sidebarType !== 'heading') {\n return 0\n }\n\n return element.querySelector<HTMLElement>('.sidebar-heading')?.offsetHeight ?? 0\n}\n\n/**\n * Computes an element top position relative to the provided scroll container.\n */\nconst getTopRelativeToScroller = (element: HTMLElement, scroller: HTMLElement): number => {\n let top = element.offsetTop\n let currentOffsetParent = element.offsetParent as HTMLElement | null\n\n while (currentOffsetParent && currentOffsetParent !== scroller) {\n top += currentOffsetParent.offsetTop\n currentOffsetParent = currentOffsetParent.offsetParent as HTMLElement | null\n }\n\n return top\n}\n\n/**\n * Scrolls the sidebar container so the requested item appears near the top.\n */\nexport const scrollSidebarToTop = (id: string, offsetTop: number = DEFAULT_SCROLL_OFFSET_TOP): void => {\n if (typeof window === 'undefined') {\n return\n }\n\n const element = document.querySelector<HTMLElement>(`[data-sidebar-id=\"${id}\"]`)\n const scroller = element?.closest<HTMLElement>('.custom-scroll, .custom-scrollbar') ?? null\n if (!element || !scroller) {\n return\n }\n\n const measurableElement = getMeasurableElement(element)\n const itemTop = getTopRelativeToScroller(measurableElement, scroller)\n const itemOffset = getHeadingOffset(element)\n const targetTop = itemTop + itemOffset - offsetTop\n\n scroller.scrollTo({\n top: targetTop > 0 ? targetTop : 0,\n behavior: 'smooth',\n })\n}\n"],"mappings":"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"}