diff --git a/package.json b/package.json index 1757fcd..6cc2e17 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@kyvg/vue3-notification": "^2.9.1", "@mdi/font": "^7.4.47", "@vueuse/core": "^13.1.0", + "@wwtelescope/engine": "^7.30.1", "@wwtelescope/engine-pinia": "^0.9.0", "leaflet": "^1.9.4", "pinia": "~2.1.7", diff --git a/src/components/FolderView.vue b/src/components/FolderView.vue new file mode 100644 index 0000000..4f21ec5 --- /dev/null +++ b/src/components/FolderView.vue @@ -0,0 +1,322 @@ + + + + + diff --git a/src/index.ts b/src/index.ts index 5917d6e..b67a74d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,7 @@ import { useWWTKeyboardControls } from "./composables/wwtKeyboard"; import CreditLogos from "./components/CreditLogos.vue"; import DateTimePicker from "./components/DateTimePicker.vue"; +import FolderView from "./components/FolderView.vue"; import FundingAcknowledgement from "./components/FundingAcknowledgement.vue"; import Gallery from "./components/Gallery.vue"; import GeolocationButton from "./components/GeolocationButton.vue"; @@ -38,6 +39,7 @@ export { CreditLogos, DateTimePicker, + FolderView, FundingAcknowledgement, Gallery, GeolocationButton, diff --git a/src/stories/FolderView.stories.ts b/src/stories/FolderView.stories.ts new file mode 100644 index 0000000..117bb2a --- /dev/null +++ b/src/stories/FolderView.stories.ts @@ -0,0 +1,63 @@ +/* eslint-disable @typescript-eslint/naming-convention */ + +import { Meta, StoryContext, StoryObj } from "@storybook/vue3"; +import { FolderView, FolderViewProps } from ".."; +import { Folder, FolderUp, Place } from "@wwtelescope/engine"; +import { Thumbnail } from "@wwtelescope/engine-types"; +import { engineStore, WWTComponent } from "@wwtelescope/engine-pinia"; + +import "./stories.css"; + +interface LoadedData { + loaded: { + folder: Folder; + } +} + +const meta: Meta = { + component: FolderView, + tags: ["autodocs"], + title: "Vue Toolkit/Components/Folder View", +}; + +export default meta; +type Story = StoryObj; +type Context = StoryContext; + + +export const Primary: Story = { + render: (args: FolderViewProps, _context: Context) => { + const store = engineStore(); + return { + components: { FolderView, WWTComponent }, + template: ` +
+
+ +
+ +
+ `, + setup() { + return { args, store, Place }; + } + }; + }, + args: { + orientation: "row", + gap: "10px", + backgroundColor: "black", + thumbnailColor: "black", + highlightColor: "dodgerblue", + textColor: "white", + startExpanded: true, + lazy: true, + filter: (item: Thumbnail) => item instanceof Place || item instanceof Folder || item instanceof FolderUp, + rootUrl: "https://cdn.worldwidetelescope.org/wwtweb/catalog.aspx?W=explorerootweb", + } +}; diff --git a/src/types.ts b/src/types.ts index cac41de..e765956 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,7 @@ import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import { CircleMarkerOptions, TileLayerOptions } from "leaflet"; +import { Folder } from "@wwtelescope/engine"; +import { Thumbnail } from "@wwtelescope/engine-types"; import { engineStore } from "@wwtelescope/engine-pinia"; import { MapBoxFeatureCollection } from "./mapbox"; @@ -394,3 +396,37 @@ export interface ShareButtonProps { /** The ARIA label for the button */ ariaLabel?: string; } + +export interface FolderViewProps { + /** The root folder of the tree to display in the view. One of either this or `rootUrl` must be specified */ + rootFolder?: Folder; + /** A URL for the root folder of the tree to display in the view. One of either this or `rootFolder` must be specified */ + rootUrl?: string; + /** Specifies the orientation of the folder view */ + orientation: "row" | "column"; + /** The gap between folder view items. Any CSS flex gap size is valid. */ + gap?: string; + /** The color of the folder view background. Should be a valid CSS color */ + backgroundColor?: string; + /** The color of the thumbnail view background. Should be a valid CSS color */ + thumbnailColor?: string; + /** The color marking the currently highlighted item. Should be a valid CSS color */ + highlightColor?: string; + /** The color of item name text. Should be a valid CSS color */ + textColor?: string; + /** Whether the folder view should start expanded or not. */ + startExpanded?: boolean; + /** Whether to select the first non-folder item automatically on when the component is mounted. */ + selectFirst?: boolean; + /** The URL of an image to use as a default thumbnail, for items that don't have one. */ + defaultThumbnail?: string; + /** + * If true, subfolders are only loaded when they are first visited. + * If false, the entire folder tree is loaded right away. + * */ + lazy?: boolean; + /** A predicate for filtering which folder items are displayed. Items to be displayed should return true. */ + filter?: (item: Thumbnail) => boolean; +} + +export type ItemSelectionType = "click" | "dblclick" | "keyup" | "folder"; diff --git a/yarn.lock b/yarn.lock index d62959e..3f24bc1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -555,6 +555,7 @@ __metadata: "@vue/eslint-config-typescript": ^12.0.0 "@vueuse/core": ^13.1.0 "@wdns/vue-code-block": ^2.3.5 + "@wwtelescope/engine": ^7.30.1 "@wwtelescope/engine-pinia": ^0.9.0 copy-webpack-plugin: ^12.0.2 css-loader: ^7.1.1 @@ -3001,7 +3002,7 @@ __metadata: languageName: node linkType: hard -"@wwtelescope/engine@npm:^7.29.1": +"@wwtelescope/engine@npm:^7.29.1, @wwtelescope/engine@npm:^7.30.1": version: 7.30.1 resolution: "@wwtelescope/engine@npm:7.30.1" dependencies: