@k2b/ui 0.27.0 → 0.29.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/base.css +147 -2
- package/dist/browser/actions/ContextMenu.js +35 -4
- package/dist/browser/actions/ContextMenu.js.map +1 -1
- package/dist/browser/actions/DragAndDrop.js +89 -0
- package/dist/browser/actions/DragAndDrop.js.map +1 -0
- package/dist/browser/actions/Dropdown.js +184 -158
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/GestureMenu.js +95 -139
- package/dist/browser/actions/GestureMenu.js.map +1 -1
- package/dist/browser/actions/Toolbar.js +379 -48
- package/dist/browser/actions/Toolbar.js.map +1 -1
- package/dist/browser/actions/drag-and-drop-messages.js +75 -0
- package/dist/browser/actions/drag-and-drop-messages.js.map +1 -0
- package/dist/browser/actions/drag-and-drop.js +692 -0
- package/dist/browser/actions/drag-and-drop.js.map +1 -0
- package/dist/browser/actions/index.js +1 -0
- package/dist/browser/actions/index.js.map +1 -1
- package/dist/browser/actions/menu-rows.js +15 -0
- package/dist/browser/actions/menu-rows.js.map +1 -0
- package/dist/browser/actions/menu-sheet.js +154 -0
- package/dist/browser/actions/menu-sheet.js.map +1 -0
- package/dist/browser/actions/toolbar-messages.js +20 -0
- package/dist/browser/actions/toolbar-messages.js.map +1 -0
- package/dist/browser/chart-inspection.js +3 -0
- package/dist/browser/chart-inspection.js.map +1 -0
- package/dist/browser/chat/ChatComposer.js +714 -410
- package/dist/browser/chat/ChatComposer.js.map +1 -1
- package/dist/browser/chat/ChatDecision.js +778 -0
- package/dist/browser/chat/ChatDecision.js.map +1 -0
- package/dist/browser/chat/ChatPrimitives.js +34 -28
- package/dist/browser/chat/ChatPrimitives.js.map +1 -1
- package/dist/browser/chat/ChatTimeline.js.map +1 -1
- package/dist/browser/chat/chat-messages.js +25 -1
- package/dist/browser/chat/chat-messages.js.map +1 -1
- package/dist/browser/chat/command-search.js +13 -3
- package/dist/browser/chat/command-search.js.map +1 -1
- package/dist/browser/chat/index.js +8 -1
- package/dist/browser/chat/index.js.map +1 -1
- package/dist/browser/chat/reaction-people.js +15 -0
- package/dist/browser/chat/reaction-people.js.map +1 -0
- package/dist/browser/chat/types.js.map +1 -1
- package/dist/browser/content/Calendar.js +3 -3
- package/dist/browser/content/Calendar.js.map +1 -1
- package/dist/browser/content/Chart.js +60 -86
- package/dist/browser/content/Chart.js.map +1 -1
- package/dist/browser/content/ChartSnapshotView.js +7 -10
- package/dist/browser/content/ChartSnapshotView.js.map +1 -1
- package/dist/browser/content/FileBrowser.js +2 -2
- package/dist/browser/content/FileBrowser.js.map +1 -1
- package/dist/browser/content/FileTree.js +42 -36
- package/dist/browser/content/FileTree.js.map +1 -1
- package/dist/browser/content/FileTypeIcon.js +72 -0
- package/dist/browser/content/FileTypeIcon.js.map +1 -0
- package/dist/browser/content/FileView.js +2 -2
- package/dist/browser/content/FileView.js.map +1 -1
- package/dist/browser/content/MessageRow.js +330 -448
- package/dist/browser/content/MessageRow.js.map +1 -1
- package/dist/browser/content/ReactionBar.js +419 -0
- package/dist/browser/content/ReactionBar.js.map +1 -0
- package/dist/browser/content/ReferenceChip.js +162 -0
- package/dist/browser/content/ReferenceChip.js.map +1 -0
- package/dist/browser/content/calendar-pointer.js +9 -0
- package/dist/browser/content/calendar-pointer.js.map +1 -1
- package/dist/browser/content/calendar-time-view.js +6 -3
- package/dist/browser/content/calendar-time-view.js.map +1 -1
- package/dist/browser/content/chart-inspection-core.js +557 -0
- package/dist/browser/content/chart-inspection-core.js.map +1 -0
- package/dist/browser/content/chart-inspection.js +10 -445
- package/dist/browser/content/chart-inspection.js.map +1 -1
- package/dist/browser/content/chart-line-gaps.js +1 -1
- package/dist/browser/content/chart-line-gaps.js.map +1 -1
- package/dist/browser/content/chart-snapshot.js +1 -1
- package/dist/browser/content/chart-snapshot.js.map +1 -1
- package/dist/browser/content/index.js +3 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/feedback/dialog-core.js +135 -23
- package/dist/browser/feedback/dialog-core.js.map +1 -1
- package/dist/browser/index.js +1 -0
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/input-mode.js +40 -0
- package/dist/browser/input-mode.js.map +1 -0
- package/dist/browser/inputs/FileDropTarget.js +24 -9
- package/dist/browser/inputs/FileDropTarget.js.map +1 -1
- package/dist/browser/inputs/FileInputs.js +2 -2
- package/dist/browser/inputs/FileInputs.js.map +1 -1
- package/dist/browser/inputs/SelectChip.js +9 -0
- package/dist/browser/inputs/SelectChip.js.map +1 -1
- package/dist/browser/inputs/emoji/EmojiPicker.js +13 -0
- package/dist/browser/inputs/emoji/EmojiPicker.js.map +1 -1
- package/dist/browser/inputs/file-drop.js.map +1 -1
- package/dist/browser/layout/AppOverview.js +1 -1
- package/dist/browser/layout/AppOverview.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +644 -445
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/DetailPanel.js +283 -197
- package/dist/browser/layout/DetailPanel.js.map +1 -1
- package/dist/browser/layout/Discussion.js +233 -185
- package/dist/browser/layout/Discussion.js.map +1 -1
- package/dist/browser/layout/PanelDialog.js +88 -86
- package/dist/browser/layout/PanelDialog.js.map +1 -1
- package/dist/browser/layout/ResizeSeparator.js +81 -0
- package/dist/browser/layout/ResizeSeparator.js.map +1 -0
- package/dist/browser/layout/SidebarSwitcher.js +9 -2
- package/dist/browser/layout/SidebarSwitcher.js.map +1 -1
- package/dist/browser/layout/TabBar.js +15 -12
- package/dist/browser/layout/TabBar.js.map +1 -1
- package/dist/browser/layout/TableOfContents.js +10 -2
- package/dist/browser/layout/TableOfContents.js.map +1 -1
- package/dist/browser/layout/app-workspace-controller.js +130 -17
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/layout/detail-panel-messages.js +35 -0
- package/dist/browser/layout/detail-panel-messages.js.map +1 -0
- package/dist/browser/layout/index.js +3 -1
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/layout/resize-separator.js +90 -0
- package/dist/browser/layout/resize-separator.js.map +1 -0
- package/dist/browser/layout/workspace-messages.js +12 -2
- package/dist/browser/layout/workspace-messages.js.map +1 -1
- package/dist/browser/surfaces/Avatar.js +50 -20
- package/dist/browser/surfaces/Avatar.js.map +1 -1
- package/dist/browser/surfaces/AvatarStack.js +406 -0
- package/dist/browser/surfaces/AvatarStack.js.map +1 -0
- package/dist/browser/surfaces/LinkCard.js +1 -1
- package/dist/browser/surfaces/LinkCard.js.map +1 -1
- package/dist/browser/surfaces/Placeholder.js +14 -3
- package/dist/browser/surfaces/Placeholder.js.map +1 -1
- package/dist/browser/surfaces/StatCell.js +23 -0
- package/dist/browser/surfaces/StatCell.js.map +1 -1
- package/dist/browser/surfaces/avatar-messages.js +8 -2
- package/dist/browser/surfaces/avatar-messages.js.map +1 -1
- package/dist/browser/surfaces/index.js +1 -0
- package/dist/browser/surfaces/index.js.map +1 -1
- package/dist/browser/widgets/Widget.js +1 -1
- package/dist/browser/widgets/Widget.js.map +1 -1
- package/dist/ssr/actions/ContextMenu.js +26 -3
- package/dist/ssr/actions/ContextMenu.js.map +1 -1
- package/dist/ssr/actions/DragAndDrop.js +63 -0
- package/dist/ssr/actions/DragAndDrop.js.map +1 -0
- package/dist/ssr/actions/Dropdown.js +140 -72
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/GestureMenu.js +76 -107
- package/dist/ssr/actions/GestureMenu.js.map +1 -1
- package/dist/ssr/actions/Toolbar.js +294 -14
- package/dist/ssr/actions/Toolbar.js.map +1 -1
- package/dist/ssr/actions/drag-and-drop-messages.js +75 -0
- package/dist/ssr/actions/drag-and-drop-messages.js.map +1 -0
- package/dist/ssr/actions/drag-and-drop.js +692 -0
- package/dist/ssr/actions/drag-and-drop.js.map +1 -0
- package/dist/ssr/actions/index.js +1 -0
- package/dist/ssr/actions/index.js.map +1 -1
- package/dist/ssr/actions/menu-rows.js +15 -0
- package/dist/ssr/actions/menu-rows.js.map +1 -0
- package/dist/ssr/actions/menu-sheet.js +138 -0
- package/dist/ssr/actions/menu-sheet.js.map +1 -0
- package/dist/ssr/actions/toolbar-messages.js +20 -0
- package/dist/ssr/actions/toolbar-messages.js.map +1 -0
- package/dist/ssr/chart-inspection.js +3 -0
- package/dist/ssr/chart-inspection.js.map +1 -0
- package/dist/ssr/chat/ChatComposer.js +393 -102
- package/dist/ssr/chat/ChatComposer.js.map +1 -1
- package/dist/ssr/chat/ChatDecision.js +465 -0
- package/dist/ssr/chat/ChatDecision.js.map +1 -0
- package/dist/ssr/chat/ChatPrimitives.js +2 -2
- package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
- package/dist/ssr/chat/ChatTimeline.js.map +1 -1
- package/dist/ssr/chat/chat-messages.js +25 -1
- package/dist/ssr/chat/chat-messages.js.map +1 -1
- package/dist/ssr/chat/command-search.js +13 -3
- package/dist/ssr/chat/command-search.js.map +1 -1
- package/dist/ssr/chat/index.js +8 -1
- package/dist/ssr/chat/index.js.map +1 -1
- package/dist/ssr/chat/reaction-people.js +15 -0
- package/dist/ssr/chat/reaction-people.js.map +1 -0
- package/dist/ssr/chat/types.js.map +1 -1
- package/dist/ssr/content/Calendar.js +3 -3
- package/dist/ssr/content/Calendar.js.map +1 -1
- package/dist/ssr/content/Chart.js +25 -38
- package/dist/ssr/content/Chart.js.map +1 -1
- package/dist/ssr/content/ChartSnapshotView.js +7 -10
- package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
- package/dist/ssr/content/FileBrowser.js +2 -2
- package/dist/ssr/content/FileBrowser.js.map +1 -1
- package/dist/ssr/content/FileTree.js +21 -14
- package/dist/ssr/content/FileTree.js.map +1 -1
- package/dist/ssr/content/FileTypeIcon.js +50 -0
- package/dist/ssr/content/FileTypeIcon.js.map +1 -0
- package/dist/ssr/content/FileView.js +2 -2
- package/dist/ssr/content/FileView.js.map +1 -1
- package/dist/ssr/content/MessageRow.js +98 -152
- package/dist/ssr/content/MessageRow.js.map +1 -1
- package/dist/ssr/content/ReactionBar.js +304 -0
- package/dist/ssr/content/ReactionBar.js.map +1 -0
- package/dist/ssr/content/ReferenceChip.js +121 -0
- package/dist/ssr/content/ReferenceChip.js.map +1 -0
- package/dist/ssr/content/calendar-pointer.js +9 -0
- package/dist/ssr/content/calendar-pointer.js.map +1 -1
- package/dist/ssr/content/calendar-time-view.js +6 -3
- package/dist/ssr/content/calendar-time-view.js.map +1 -1
- package/dist/ssr/content/chart-inspection-core.js +557 -0
- package/dist/ssr/content/chart-inspection-core.js.map +1 -0
- package/dist/ssr/content/chart-inspection.js +10 -445
- package/dist/ssr/content/chart-inspection.js.map +1 -1
- package/dist/ssr/content/chart-line-gaps.js +1 -1
- package/dist/ssr/content/chart-line-gaps.js.map +1 -1
- package/dist/ssr/content/chart-snapshot.js +1 -1
- package/dist/ssr/content/chart-snapshot.js.map +1 -1
- package/dist/ssr/content/index.js +3 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/feedback/dialog-core.js +135 -23
- package/dist/ssr/feedback/dialog-core.js.map +1 -1
- package/dist/ssr/index.js +1 -0
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/input-mode.js +40 -0
- package/dist/ssr/input-mode.js.map +1 -0
- package/dist/ssr/inputs/FileDropTarget.js +17 -5
- package/dist/ssr/inputs/FileDropTarget.js.map +1 -1
- package/dist/ssr/inputs/FileInputs.js +2 -2
- package/dist/ssr/inputs/FileInputs.js.map +1 -1
- package/dist/ssr/inputs/SelectChip.js +9 -0
- package/dist/ssr/inputs/SelectChip.js.map +1 -1
- package/dist/ssr/inputs/emoji/EmojiPicker.js +12 -0
- package/dist/ssr/inputs/emoji/EmojiPicker.js.map +1 -1
- package/dist/ssr/inputs/file-drop.js.map +1 -1
- package/dist/ssr/layout/AppOverview.js +1 -1
- package/dist/ssr/layout/AppOverview.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +272 -95
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/DetailPanel.js +112 -58
- package/dist/ssr/layout/DetailPanel.js.map +1 -1
- package/dist/ssr/layout/Discussion.js +63 -36
- package/dist/ssr/layout/Discussion.js.map +1 -1
- package/dist/ssr/layout/PanelDialog.js +7 -6
- package/dist/ssr/layout/PanelDialog.js.map +1 -1
- package/dist/ssr/layout/ResizeSeparator.js +45 -0
- package/dist/ssr/layout/ResizeSeparator.js.map +1 -0
- package/dist/ssr/layout/SidebarSwitcher.js +9 -2
- package/dist/ssr/layout/SidebarSwitcher.js.map +1 -1
- package/dist/ssr/layout/TabBar.js +1 -1
- package/dist/ssr/layout/TabBar.js.map +1 -1
- package/dist/ssr/layout/TableOfContents.js +10 -2
- package/dist/ssr/layout/TableOfContents.js.map +1 -1
- package/dist/ssr/layout/app-workspace-controller.js +130 -17
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/layout/detail-panel-messages.js +35 -0
- package/dist/ssr/layout/detail-panel-messages.js.map +1 -0
- package/dist/ssr/layout/index.js +3 -1
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/layout/resize-separator.js +90 -0
- package/dist/ssr/layout/resize-separator.js.map +1 -0
- package/dist/ssr/layout/workspace-messages.js +12 -2
- package/dist/ssr/layout/workspace-messages.js.map +1 -1
- package/dist/ssr/surfaces/Avatar.js +20 -2
- package/dist/ssr/surfaces/Avatar.js.map +1 -1
- package/dist/ssr/surfaces/AvatarStack.js +286 -0
- package/dist/ssr/surfaces/AvatarStack.js.map +1 -0
- package/dist/ssr/surfaces/LinkCard.js +1 -1
- package/dist/ssr/surfaces/LinkCard.js.map +1 -1
- package/dist/ssr/surfaces/Placeholder.js +4 -2
- package/dist/ssr/surfaces/Placeholder.js.map +1 -1
- package/dist/ssr/surfaces/StatCell.js +23 -0
- package/dist/ssr/surfaces/StatCell.js.map +1 -1
- package/dist/ssr/surfaces/avatar-messages.js +8 -2
- package/dist/ssr/surfaces/avatar-messages.js.map +1 -1
- package/dist/ssr/surfaces/index.js +1 -0
- package/dist/ssr/surfaces/index.js.map +1 -1
- package/dist/ssr/widgets/Widget.js +1 -1
- package/dist/ssr/widgets/Widget.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/ContextMenu.d.ts +9 -0
- package/dist/types/actions/DragAndDrop.d.ts +29 -0
- package/dist/types/actions/Dropdown.d.ts +12 -5
- package/dist/types/actions/GestureMenu.d.ts +6 -4
- package/dist/types/actions/Toolbar.d.ts +20 -0
- package/dist/types/actions/drag-and-drop-messages.d.ts +35 -0
- package/dist/types/actions/drag-and-drop.d.ts +36 -0
- package/dist/types/actions/index.d.ts +3 -1
- package/dist/types/actions/menu-rows.d.ts +5 -0
- package/dist/types/actions/menu-sheet.d.ts +22 -0
- package/dist/types/actions/toolbar-messages.d.ts +8 -0
- package/dist/types/chart-inspection.d.ts +2 -0
- package/dist/types/chat/ChatComposer.d.ts +26 -1
- package/dist/types/chat/ChatDecision.d.ts +133 -0
- package/dist/types/chat/ChatPrimitives.d.ts +4 -1
- package/dist/types/chat/ChatTimeline.d.ts +2 -1
- package/dist/types/chat/chat-messages.d.ts +13 -2
- package/dist/types/chat/command-search.d.ts +5 -0
- package/dist/types/chat/index.d.ts +25 -1
- package/dist/types/chat/reaction-people.d.ts +9 -0
- package/dist/types/chat/types.d.ts +54 -1
- package/dist/types/content/Chart.d.ts +11 -5
- package/dist/types/content/FileTypeIcon.d.ts +27 -0
- package/dist/types/content/MessageRow.d.ts +3 -10
- package/dist/types/content/ReactionBar.d.ts +32 -0
- package/dist/types/content/ReferenceChip.d.ts +49 -0
- package/dist/types/content/calendar-pointer.d.ts +6 -0
- package/dist/types/content/chart-inspection-core.d.ts +61 -0
- package/dist/types/content/chart-inspection.d.ts +4 -20
- package/dist/types/content/chart-snapshot.d.ts +1 -1
- package/dist/types/content/index.d.ts +5 -1
- package/dist/types/feedback/dialog-core.d.ts +16 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/input-mode.d.ts +7 -0
- package/dist/types/inputs/FileDropTarget.d.ts +6 -3
- package/dist/types/inputs/SelectChip.d.ts +2 -0
- package/dist/types/inputs/file-drop.d.ts +2 -0
- package/dist/types/layout/AppWorkspace.d.ts +5 -3
- package/dist/types/layout/DetailPanel.d.ts +11 -0
- package/dist/types/layout/Discussion.d.ts +8 -0
- package/dist/types/layout/ResizeSeparator.d.ts +9 -0
- package/dist/types/layout/TabBar.d.ts +7 -0
- package/dist/types/layout/TableOfContents.d.ts +2 -0
- package/dist/types/layout/app-workspace-controller.d.ts +2 -0
- package/dist/types/layout/detail-panel-messages.d.ts +15 -0
- package/dist/types/layout/index.d.ts +3 -1
- package/dist/types/layout/resize-separator.d.ts +18 -0
- package/dist/types/layout/workspace-messages.d.ts +5 -0
- package/dist/types/surfaces/Avatar.d.ts +12 -0
- package/dist/types/surfaces/AvatarStack.d.ts +41 -0
- package/dist/types/surfaces/StatCell.d.ts +6 -0
- package/dist/types/surfaces/avatar-messages.d.ts +3 -0
- package/dist/types/surfaces/index.d.ts +3 -1
- package/package.json +7 -2
|
@@ -10,7 +10,7 @@ var _tmpl$ = ["<ul class=\"", "\"", " role=\"tree\"", ">", "</ul>"],
|
|
|
10
10
|
_tmpl$4 = ["<span class=\"k2b-content-file-tree__badge\">", "</span>"],
|
|
11
11
|
_tmpl$5 = "<i class=\"ti ti-dots\" aria-hidden=\"true\"></i>",
|
|
12
12
|
_tmpl$6 = ["<span class=\"k2b-sr-only\">Actions for ", "</span>"],
|
|
13
|
-
_tmpl$7 = ["<div", " class=\"k2b-content-file-tree__row\"><button type=\"button\" tabindex=\"-1\" class=\"k2b-content-file-tree__select\" style=\"", "\"", "
|
|
13
|
+
_tmpl$7 = ["<div", " class=\"k2b-content-file-tree__row\"><button type=\"button\" tabindex=\"-1\" class=\"k2b-content-file-tree__select\" style=\"", "\"", ">", "<span class=\"k2b-content-file-tree__name\">", "</span>", "</button>", "</div>"];
|
|
14
14
|
/**
|
|
15
15
|
* FileTree — path-first tree over a flat entry list (folders derived from
|
|
16
16
|
* paths, explicit folder entries allowed for empty dirs). Capabilities are
|
|
@@ -18,19 +18,13 @@ var _tmpl$ = ["<ul class=\"", "\"", " role=\"tree\"", ">", "</ul>"],
|
|
|
18
18
|
* pure read-only browser. Context menus render through the platform
|
|
19
19
|
* ContextMenu. Minimal look: text rows, bevel on selection, no hover motion.
|
|
20
20
|
*/
|
|
21
|
-
import { fileIcons } from "@k2b/stdlib";
|
|
22
21
|
import { createEffect, createMemo, createSignal, For, Show } from "solid-js";
|
|
23
22
|
import ContextMenu from "../actions/ContextMenu";
|
|
24
23
|
import Dropdown from "../actions/Dropdown";
|
|
25
24
|
import { useUiMessages } from "../intl/messages";
|
|
25
|
+
import { FileTypeIcon } from "./FileTypeIcon";
|
|
26
26
|
import { useFileBrowserMessages } from "./file-browser-messages";
|
|
27
27
|
import { allFolderPaths, buildTree, flattenVisible, parentOf } from "./file-tree";
|
|
28
|
-
/**
|
|
29
|
-
* `fileIcons` (and app-supplied entry icons) may carry Tailwind colour classes.
|
|
30
|
-
* @k2b/ui ships no Tailwind utilities, so only the `ti-*` glyph is kept — the
|
|
31
|
-
* row owns the icon colour.
|
|
32
|
-
*/
|
|
33
|
-
const glyphOnly = icon => icon.split(/\s+/).filter(token => token.startsWith("ti-")).join(" ");
|
|
34
28
|
|
|
35
29
|
/** Presence of a callback enables the matching UI affordance. */
|
|
36
30
|
|
|
@@ -239,18 +233,31 @@ export default function FileTree(props) {
|
|
|
239
233
|
};
|
|
240
234
|
const isSelected = () => props.selectedPath === currentNode().entry.path;
|
|
241
235
|
const isDropTarget = () => currentNode().isFolder && dropTarget() === currentNode().entry.path;
|
|
242
|
-
const icon = () => currentNode().isFolder ? expanded().has(currentNode().entry.path) ? "ti-folder-open" : "ti-folder" : glyphOnly(currentNode().entry.icon ?? fileIcons.getFileIcon({
|
|
243
|
-
name: currentNode().name,
|
|
244
|
-
type: "file",
|
|
245
|
-
mimeType: currentNode().entry.mediaType ?? "text/plain"
|
|
246
|
-
}));
|
|
247
236
|
const hasItems = () => menuItems(node).length > 0;
|
|
248
237
|
return _$ssr(_tmpl$3, _$ssrAttribute("tabindex", renamingPath() === node.entry.path ? -1 : focusedPath() === node.entry.path ? 0 : -1, false) + _$ssrAttribute("aria-label", _$escape(currentNode().entry.displayName ?? currentNode().name, true), false) + _$ssrAttribute("aria-level", _$escape(currentNode().depth, true) + 1, false) + _$ssrAttribute("aria-selected", _$escape(isSelected(), true), false) + _$ssrAttribute("aria-expanded", currentNode().isFolder ? _$escape(expanded().has(currentNode().entry.path), true) : _$escape(undefined, true), false) + _$ssrAttribute("aria-haspopup", hasItems() ? "menu" : _$escape(undefined, true), false) + _$ssrAttribute("data-context-open", contextMenuOpen() && contextPath() === node.entry.path ? "true" : _$escape(undefined, true), false), _$escape(_$createComponent(Show, {
|
|
249
238
|
get when() {
|
|
250
239
|
return renamingPath() === node.entry.path;
|
|
251
240
|
},
|
|
252
241
|
get fallback() {
|
|
253
|
-
return _$ssr(_tmpl$7, _$ssrAttribute("data-state", isSelected() ? "selected" : isDropTarget() ? "drop-target" : "idle", false), _$ssrStyleProperty("padding-left:", `${6 + _$escape(currentNode().depth, true) * 14}px`), _$ssrAttribute("title", _$escape(currentNode().entry.path, true), false) + _$ssrAttribute("draggable", _$escape(Boolean(props.actions?.move), true), false),
|
|
242
|
+
return _$ssr(_tmpl$7, _$ssrAttribute("data-state", isSelected() ? "selected" : isDropTarget() ? "drop-target" : "idle", false), _$ssrStyleProperty("padding-left:", `${6 + _$escape(currentNode().depth, true) * 14}px`), _$ssrAttribute("title", _$escape(currentNode().entry.path, true), false) + _$ssrAttribute("draggable", _$escape(Boolean(props.actions?.move), true), false), _$escape(_$createComponent(FileTypeIcon, {
|
|
243
|
+
size: "sm",
|
|
244
|
+
"class": "k2b-content-file-tree__icon",
|
|
245
|
+
get name() {
|
|
246
|
+
return currentNode().name;
|
|
247
|
+
},
|
|
248
|
+
get folder() {
|
|
249
|
+
return currentNode().isFolder;
|
|
250
|
+
},
|
|
251
|
+
get open() {
|
|
252
|
+
return _$memo(() => !!currentNode().isFolder)() && expanded().has(currentNode().entry.path);
|
|
253
|
+
},
|
|
254
|
+
get icon() {
|
|
255
|
+
return _$memo(() => !!currentNode().isFolder)() ? undefined : currentNode().entry.icon;
|
|
256
|
+
},
|
|
257
|
+
get mediaType() {
|
|
258
|
+
return currentNode().entry.mediaType ?? "text/plain";
|
|
259
|
+
}
|
|
260
|
+
})), _$escape(currentNode().entry.displayName ?? currentNode().name), _$escape(_$createComponent(Show, {
|
|
254
261
|
get when() {
|
|
255
262
|
return currentNode().entry.badge;
|
|
256
263
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["content/FileTree.tsx"],"sourcesContent":["/**\n * FileTree — path-first tree over a flat entry list (folders derived from\n * paths, explicit folder entries allowed for empty dirs). Capabilities are\n * enabled by the presence of action callbacks; without them the tree is a\n * pure read-only browser. Context menus render through the platform\n * ContextMenu. Minimal look: text rows, bevel on selection, no hover motion.\n */\nimport { fileIcons } from \"@k2b/stdlib\";\nimport { createEffect, createMemo, createSignal, For, Show } from \"solid-js\";\nimport ContextMenu from \"../actions/ContextMenu\";\nimport Dropdown, { type DropdownItem } from \"../actions/Dropdown\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { useFileBrowserMessages } from \"./file-browser-messages\";\nimport { allFolderPaths, buildTree, type FileTreeEntry, flattenVisible, parentOf, type TreeNode } from \"./file-tree\";\n\nexport type { FileTreeEntry } from \"./file-tree\";\n\n/**\n * `fileIcons` (and app-supplied entry icons) may carry Tailwind colour classes.\n * @k2b/ui ships no Tailwind utilities, so only the `ti-*` glyph is kept — the\n * row owns the icon colour.\n */\nconst glyphOnly = (icon: string): string =>\n icon\n .split(/\\s+/)\n .filter((token) => token.startsWith(\"ti-\"))\n .join(\" \");\n\n/** Presence of a callback enables the matching UI affordance. */\nexport type FileTreeActions = {\n rename?: (path: string, nextName: string) => void | Promise<void>;\n remove?: (path: string) => void | Promise<void>;\n createFile?: (dirPath: string) => void | Promise<void>;\n createFolder?: (dirPath: string) => void | Promise<void>;\n /** Enables drag & drop of files and folders onto folders (and the tree root). */\n move?: (path: string, targetDir: string) => void | Promise<void>;\n /** Download menu entry — folders arrive as \"Download as ZIP\". */\n download?: (path: string, isFolder: boolean) => void | Promise<void>;\n};\n\nexport type FileTreeProps = {\n entries: FileTreeEntry[];\n selectedPath?: string | null;\n onSelect?: (entry: FileTreeEntry) => void;\n /** Controlled expansion; omit for internal state (folders start expanded). */\n expandedPaths?: Set<string>;\n onExpandedChange?: (expanded: Set<string>) => void;\n /** Extra context-menu items per entry, merged above the built-in actions. */\n contextMenu?: (entry: FileTreeEntry) => DropdownItem[];\n actions?: FileTreeActions;\n /** Accessible name for the tree. */\n label?: string;\n class?: string;\n};\n\nexport default function FileTree(props: FileTreeProps) {\n const messages = useUiMessages();\n const fileBrowserMessages = useFileBrowserMessages();\n let previousTree: TreeNode[] = [];\n const tree = createMemo(() => (previousTree = buildTree(props.entries, previousTree)));\n\n const [internalExpanded, setInternalExpanded] = createSignal<Set<string>>(new Set(allFolderPaths(tree())), { equals: false });\n // Newly appearing folders start expanded in uncontrolled mode.\n createEffect((previous: Set<string>) => {\n const current = new Set(allFolderPaths(tree()));\n const added = [...current].filter((path) => !previous.has(path));\n if (added.length > 0 && !props.expandedPaths) setInternalExpanded((expanded) => new Set([...expanded, ...added]));\n return current;\n }, new Set<string>());\n\n const expanded = () => props.expandedPaths ?? internalExpanded();\n const setExpanded = (next: Set<string>) => {\n if (props.onExpandedChange) props.onExpandedChange(next);\n if (!props.expandedPaths) setInternalExpanded(next);\n };\n const toggleFolder = (path: string) => {\n const next = new Set(expanded());\n if (next.has(path)) next.delete(path);\n else next.add(path);\n setExpanded(next);\n };\n\n const visible = createMemo(() => flattenVisible(tree(), expanded()));\n const [renamingPath, setRenamingPath] = createSignal<string | null>(null);\n const [renameDraft, setRenameDraft] = createSignal(\"\");\n const [focusedPath, setFocusedPath] = createSignal(props.selectedPath ?? \"\");\n const [pendingFocusPath, setPendingFocusPath] = createSignal<string | null>(null);\n const [contextPath, setContextPath] = createSignal<string | null>(props.selectedPath ?? null);\n const [contextMenuOpen, setContextMenuOpen] = createSignal(false);\n const rowRefs = new Map<string, HTMLLIElement>();\n /** Folder currently hovered by a drag (\"/\" = tree root). */\n const [dropTarget, setDropTarget] = createSignal<string | null>(null);\n\n const focusRow = (path: string, restoreDomFocus = true) => {\n setFocusedPath(path);\n if (!restoreDomFocus) return;\n const row = rowRefs.get(path);\n if (row?.isConnected) row.focus();\n else queueMicrotask(() => rowRefs.get(path)?.focus());\n };\n\n createEffect(() => {\n const rows = visible();\n const paths = new Set(rows.map((node) => node.entry.path));\n for (const path of rowRefs.keys()) if (!paths.has(path)) rowRefs.delete(path);\n const pending = pendingFocusPath();\n if (pending && rows.some((node) => node.entry.path === pending)) {\n setPendingFocusPath(null);\n focusRow(pending);\n return;\n }\n if (rows.some((node) => node.entry.path === focusedPath())) return;\n const selected = rows.find((node) => node.entry.path === props.selectedPath);\n setFocusedPath(selected?.entry.path ?? rows[0]?.entry.path ?? \"\");\n });\n\n const DRAG_MIME = \"application/x-filetree-path\";\n const canDrop = (event: DragEvent) => props.actions?.move && event.dataTransfer?.types.includes(DRAG_MIME);\n const handleDrop = (event: DragEvent, targetDir: string) => {\n event.preventDefault();\n event.stopPropagation();\n setDropTarget(null);\n const path = event.dataTransfer?.getData(DRAG_MIME);\n if (!path || parentOf(path) === targetDir || path === targetDir || targetDir.startsWith(`${path}/`)) return;\n void props.actions?.move?.(path, targetDir);\n };\n\n const select = (node: TreeNode) => {\n if (node.isFolder) toggleFolder(node.entry.path);\n else props.onSelect?.(node.entry);\n };\n\n const commitRename = async (node: TreeNode, value: string) => {\n if (renamingPath() !== node.entry.path) return;\n setRenamingPath(null);\n const nextName = value.trim();\n focusRow(node.entry.path);\n if (!nextName || nextName === node.name || nextName.includes(\"/\")) return;\n const parent = parentOf(node.entry.path);\n setPendingFocusPath(`${parent === \"/\" ? \"\" : parent}/${nextName}`);\n await props.actions?.rename?.(node.entry.path, nextName);\n };\n\n const cancelRename = (node: TreeNode) => {\n setRenamingPath(null);\n focusRow(node.entry.path);\n };\n\n const beginRename = (node: TreeNode) => {\n setRenameDraft(node.name);\n setRenamingPath(node.entry.path);\n };\n\n const menuItems = (node: TreeNode): DropdownItem[] => {\n tree();\n const items: DropdownItem[] = [...(props.contextMenu?.(node.entry) ?? [])];\n if (node.isFolder && props.actions?.createFile) {\n items.push({\n icon: \"ti ti-file-plus\",\n label: fileBrowserMessages().newFile,\n action: () => void props.actions?.createFile?.(node.entry.path),\n });\n }\n if (node.isFolder && props.actions?.createFolder) {\n items.push({\n icon: \"ti ti-folder-plus\",\n label: fileBrowserMessages().newFolder,\n action: () => void props.actions?.createFolder?.(node.entry.path),\n });\n }\n if (props.actions?.download) {\n items.push({\n icon: node.isFolder ? \"ti ti-file-zip\" : \"ti ti-download\",\n label: node.isFolder ? fileBrowserMessages().downloadAsZip : messages().download,\n action: () => void props.actions?.download?.(node.entry.path, node.isFolder),\n });\n }\n if (!node.isFolder && props.actions?.rename) {\n items.push({ icon: \"ti ti-cursor-text\", label: fileBrowserMessages().rename, action: () => beginRename(node) });\n }\n if (props.actions?.remove) {\n items.push({\n icon: \"ti ti-trash\",\n label: messages().delete,\n variant: \"danger\",\n action: () => void props.actions?.remove?.(node.entry.path),\n });\n }\n return items;\n };\n\n const contextNode = createMemo(() => visible().find((node) => node.entry.path === contextPath()));\n const contextItems = createMemo(() => {\n const node = contextNode();\n return node ? menuItems(node) : [];\n });\n\n const onKeyDown = (event: KeyboardEvent, node: TreeNode) => {\n if (renamingPath()) return;\n const target = event.target;\n if (target instanceof Element && target !== rowRefs.get(node.entry.path)) return;\n const rows = visible();\n const index = rows.findIndex((row) => row.entry.path === node.entry.path);\n const focus = (next: TreeNode | undefined) => {\n if (!next) return;\n focusRow(next.entry.path);\n };\n if (event.key === \"ContextMenu\" || (event.shiftKey && event.key === \"F10\")) {\n setContextPath(node.entry.path);\n return;\n }\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n focus(rows[Math.min(index + 1, rows.length - 1)] ?? rows[0]);\n } else if (event.key === \"ArrowUp\") {\n event.preventDefault();\n focus(rows[Math.max(index - 1, 0)] ?? rows[0]);\n } else if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n focus(rows[event.key === \"Home\" ? 0 : rows.length - 1]);\n } else if (event.key === \"ArrowRight\" && node.isFolder) {\n event.preventDefault();\n if (!expanded().has(node.entry.path)) toggleFolder(node.entry.path);\n else focus(rows[index + 1]?.depth === node.depth + 1 ? rows[index + 1] : undefined);\n } else if (event.key === \"ArrowLeft\" && node.isFolder && expanded().has(node.entry.path)) {\n event.preventDefault();\n toggleFolder(node.entry.path);\n } else if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n const parent = parentOf(node.entry.path);\n focus(rows.find((row) => row.entry.path === parent));\n } else if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n select(node);\n } else if (event.key === \"F2\" && !node.isFolder && props.actions?.rename) {\n event.preventDefault();\n beginRename(node);\n }\n };\n\n return (\n <ContextMenu\n class=\"k2b-content-file-tree__context-host\"\n tabIndex={-1}\n label={contextNode() ? fileBrowserMessages().actionsFor({ name: contextNode()!.name }) : fileBrowserMessages().fileActions}\n items={contextItems()}\n disabled={contextItems().length === 0}\n onOpen={() => setContextMenuOpen(true)}\n onClose={() => {\n setContextMenuOpen(false);\n const path = contextPath();\n if (path) focusRow(path);\n }}\n >\n <ul\n class={`k2b-content-file-tree ${props.class ?? \"\"}`}\n data-drop-root={dropTarget() === \"/\" ? \"true\" : undefined}\n role=\"tree\"\n aria-label={props.label ?? fileBrowserMessages().files}\n onDragOver={(event) => {\n if (!canDrop(event)) return;\n event.preventDefault();\n if (dropTarget() === null) setDropTarget(\"/\");\n }}\n onDragLeave={(event) => {\n if (event.currentTarget === event.target) setDropTarget(null);\n }}\n onDrop={(event) => handleDrop(event, \"/\")}\n >\n <For each={visible()}>\n {(node) => {\n const currentNode = () => {\n tree();\n return node;\n };\n const isSelected = () => props.selectedPath === currentNode().entry.path;\n const isDropTarget = () => currentNode().isFolder && dropTarget() === currentNode().entry.path;\n const icon = () =>\n currentNode().isFolder\n ? expanded().has(currentNode().entry.path)\n ? \"ti-folder-open\"\n : \"ti-folder\"\n : glyphOnly(\n currentNode().entry.icon ??\n fileIcons.getFileIcon({\n name: currentNode().name,\n type: \"file\",\n mimeType: currentNode().entry.mediaType ?? \"text/plain\",\n }),\n );\n const hasItems = () => menuItems(node).length > 0;\n return (\n <li\n ref={(element) => {\n rowRefs.set(node.entry.path, element);\n }}\n class=\"k2b-content-file-tree__item\"\n role=\"treeitem\"\n tabIndex={renamingPath() === node.entry.path ? -1 : focusedPath() === node.entry.path ? 0 : -1}\n aria-label={currentNode().entry.displayName ?? currentNode().name}\n aria-level={currentNode().depth + 1}\n aria-selected={isSelected()}\n aria-expanded={currentNode().isFolder ? expanded().has(currentNode().entry.path) : undefined}\n aria-haspopup={hasItems() ? \"menu\" : undefined}\n data-context-open={contextMenuOpen() && contextPath() === node.entry.path ? \"true\" : undefined}\n onFocus={() => {\n setFocusedPath(node.entry.path);\n setContextPath(node.entry.path);\n }}\n onKeyDown={(event) => onKeyDown(event, node)}\n onContextMenu={() => setContextPath(node.entry.path)}\n >\n <Show\n when={renamingPath() === node.entry.path}\n fallback={\n <div\n data-state={isSelected() ? \"selected\" : isDropTarget() ? \"drop-target\" : \"idle\"}\n class=\"k2b-content-file-tree__row\"\n >\n <button\n type=\"button\"\n tabIndex={-1}\n class=\"k2b-content-file-tree__select\"\n style={{ \"padding-left\": `${6 + currentNode().depth * 14}px` }}\n title={currentNode().entry.path}\n draggable={Boolean(props.actions?.move)}\n onDragStart={(event) => event.dataTransfer?.setData(DRAG_MIME, node.entry.path)}\n onDragOver={(event) => {\n if (!node.isFolder || !canDrop(event)) return;\n event.preventDefault();\n event.stopPropagation();\n setDropTarget(node.entry.path);\n }}\n onDragLeave={() => {\n if (isDropTarget()) setDropTarget(null);\n }}\n onDrop={(event) => node.isFolder && handleDrop(event, node.entry.path)}\n onClick={(event) => {\n event.currentTarget.closest<HTMLElement>('[role=\"treeitem\"]')?.focus();\n select(node);\n }}\n >\n <i class={`ti ${icon()} k2b-content-file-tree__icon`} aria-hidden=\"true\" />\n <span class=\"k2b-content-file-tree__name\">{currentNode().entry.displayName ?? currentNode().name}</span>\n <Show when={currentNode().entry.badge}>\n <span class=\"k2b-content-file-tree__badge\">{currentNode().entry.badge}</span>\n </Show>\n </button>\n <Show when={hasItems()}>\n <Dropdown.Root position=\"bottom-left\" items={menuItems(node)} label={`Actions for ${currentNode().name}`}>\n <Dropdown.Trigger\n appearance=\"plain\"\n tabIndex={-1}\n class=\"k2b-content-file-tree__actions\"\n label={`Actions for ${currentNode().name}`}\n tooltip={messages().actions}\n >\n <i class=\"ti ti-dots\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\">Actions for {currentNode().name}</span>\n </Dropdown.Trigger>\n </Dropdown.Root>\n </Show>\n </div>\n }\n >\n <input\n class=\"k2b-content-file-tree__rename\"\n style={{\n \"margin-left\": `${6 + currentNode().depth * 14}px`,\n width: `calc(100% - ${6 + currentNode().depth * 14}px)`,\n }}\n value={renameDraft()}\n ref={(element) =>\n requestAnimationFrame(() => {\n element.focus();\n element.select();\n })\n }\n onInput={(event) => setRenameDraft(event.currentTarget.value)}\n onKeyDown={(event) => {\n event.stopPropagation();\n if (event.key === \"Enter\") void commitRename(node, event.currentTarget.value);\n if (event.key === \"Escape\") cancelRename(node);\n }}\n onBlur={(event) => void commitRename(node, event.currentTarget.value)}\n />\n </Show>\n </li>\n );\n }}\n </For>\n </ul>\n </ContextMenu>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["content/FileTree.tsx"],"sourcesContent":["/**\n * FileTree — path-first tree over a flat entry list (folders derived from\n * paths, explicit folder entries allowed for empty dirs). Capabilities are\n * enabled by the presence of action callbacks; without them the tree is a\n * pure read-only browser. Context menus render through the platform\n * ContextMenu. Minimal look: text rows, bevel on selection, no hover motion.\n */\nimport { createEffect, createMemo, createSignal, For, Show } from \"solid-js\";\nimport ContextMenu from \"../actions/ContextMenu\";\nimport Dropdown, { type DropdownItem } from \"../actions/Dropdown\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { FileTypeIcon } from \"./FileTypeIcon\";\nimport { useFileBrowserMessages } from \"./file-browser-messages\";\nimport { allFolderPaths, buildTree, type FileTreeEntry, flattenVisible, parentOf, type TreeNode } from \"./file-tree\";\n\nexport type { FileTreeEntry } from \"./file-tree\";\n\n/** Presence of a callback enables the matching UI affordance. */\nexport type FileTreeActions = {\n rename?: (path: string, nextName: string) => void | Promise<void>;\n remove?: (path: string) => void | Promise<void>;\n createFile?: (dirPath: string) => void | Promise<void>;\n createFolder?: (dirPath: string) => void | Promise<void>;\n /** Enables drag & drop of files and folders onto folders (and the tree root). */\n move?: (path: string, targetDir: string) => void | Promise<void>;\n /** Download menu entry — folders arrive as \"Download as ZIP\". */\n download?: (path: string, isFolder: boolean) => void | Promise<void>;\n};\n\nexport type FileTreeProps = {\n entries: FileTreeEntry[];\n selectedPath?: string | null;\n onSelect?: (entry: FileTreeEntry) => void;\n /** Controlled expansion; omit for internal state (folders start expanded). */\n expandedPaths?: Set<string>;\n onExpandedChange?: (expanded: Set<string>) => void;\n /** Extra context-menu items per entry, merged above the built-in actions. */\n contextMenu?: (entry: FileTreeEntry) => DropdownItem[];\n actions?: FileTreeActions;\n /** Accessible name for the tree. */\n label?: string;\n class?: string;\n};\n\nexport default function FileTree(props: FileTreeProps) {\n const messages = useUiMessages();\n const fileBrowserMessages = useFileBrowserMessages();\n let previousTree: TreeNode[] = [];\n const tree = createMemo(() => (previousTree = buildTree(props.entries, previousTree)));\n\n const [internalExpanded, setInternalExpanded] = createSignal<Set<string>>(new Set(allFolderPaths(tree())), { equals: false });\n // Newly appearing folders start expanded in uncontrolled mode.\n createEffect((previous: Set<string>) => {\n const current = new Set(allFolderPaths(tree()));\n const added = [...current].filter((path) => !previous.has(path));\n if (added.length > 0 && !props.expandedPaths) setInternalExpanded((expanded) => new Set([...expanded, ...added]));\n return current;\n }, new Set<string>());\n\n const expanded = () => props.expandedPaths ?? internalExpanded();\n const setExpanded = (next: Set<string>) => {\n if (props.onExpandedChange) props.onExpandedChange(next);\n if (!props.expandedPaths) setInternalExpanded(next);\n };\n const toggleFolder = (path: string) => {\n const next = new Set(expanded());\n if (next.has(path)) next.delete(path);\n else next.add(path);\n setExpanded(next);\n };\n\n const visible = createMemo(() => flattenVisible(tree(), expanded()));\n const [renamingPath, setRenamingPath] = createSignal<string | null>(null);\n const [renameDraft, setRenameDraft] = createSignal(\"\");\n const [focusedPath, setFocusedPath] = createSignal(props.selectedPath ?? \"\");\n const [pendingFocusPath, setPendingFocusPath] = createSignal<string | null>(null);\n const [contextPath, setContextPath] = createSignal<string | null>(props.selectedPath ?? null);\n const [contextMenuOpen, setContextMenuOpen] = createSignal(false);\n const rowRefs = new Map<string, HTMLLIElement>();\n /** Folder currently hovered by a drag (\"/\" = tree root). */\n const [dropTarget, setDropTarget] = createSignal<string | null>(null);\n\n const focusRow = (path: string, restoreDomFocus = true) => {\n setFocusedPath(path);\n if (!restoreDomFocus) return;\n const row = rowRefs.get(path);\n if (row?.isConnected) row.focus();\n else queueMicrotask(() => rowRefs.get(path)?.focus());\n };\n\n createEffect(() => {\n const rows = visible();\n const paths = new Set(rows.map((node) => node.entry.path));\n for (const path of rowRefs.keys()) if (!paths.has(path)) rowRefs.delete(path);\n const pending = pendingFocusPath();\n if (pending && rows.some((node) => node.entry.path === pending)) {\n setPendingFocusPath(null);\n focusRow(pending);\n return;\n }\n if (rows.some((node) => node.entry.path === focusedPath())) return;\n const selected = rows.find((node) => node.entry.path === props.selectedPath);\n setFocusedPath(selected?.entry.path ?? rows[0]?.entry.path ?? \"\");\n });\n\n const DRAG_MIME = \"application/x-filetree-path\";\n const canDrop = (event: DragEvent) => props.actions?.move && event.dataTransfer?.types.includes(DRAG_MIME);\n const handleDrop = (event: DragEvent, targetDir: string) => {\n event.preventDefault();\n event.stopPropagation();\n setDropTarget(null);\n const path = event.dataTransfer?.getData(DRAG_MIME);\n if (!path || parentOf(path) === targetDir || path === targetDir || targetDir.startsWith(`${path}/`)) return;\n void props.actions?.move?.(path, targetDir);\n };\n\n const select = (node: TreeNode) => {\n if (node.isFolder) toggleFolder(node.entry.path);\n else props.onSelect?.(node.entry);\n };\n\n const commitRename = async (node: TreeNode, value: string) => {\n if (renamingPath() !== node.entry.path) return;\n setRenamingPath(null);\n const nextName = value.trim();\n focusRow(node.entry.path);\n if (!nextName || nextName === node.name || nextName.includes(\"/\")) return;\n const parent = parentOf(node.entry.path);\n setPendingFocusPath(`${parent === \"/\" ? \"\" : parent}/${nextName}`);\n await props.actions?.rename?.(node.entry.path, nextName);\n };\n\n const cancelRename = (node: TreeNode) => {\n setRenamingPath(null);\n focusRow(node.entry.path);\n };\n\n const beginRename = (node: TreeNode) => {\n setRenameDraft(node.name);\n setRenamingPath(node.entry.path);\n };\n\n const menuItems = (node: TreeNode): DropdownItem[] => {\n tree();\n const items: DropdownItem[] = [...(props.contextMenu?.(node.entry) ?? [])];\n if (node.isFolder && props.actions?.createFile) {\n items.push({\n icon: \"ti ti-file-plus\",\n label: fileBrowserMessages().newFile,\n action: () => void props.actions?.createFile?.(node.entry.path),\n });\n }\n if (node.isFolder && props.actions?.createFolder) {\n items.push({\n icon: \"ti ti-folder-plus\",\n label: fileBrowserMessages().newFolder,\n action: () => void props.actions?.createFolder?.(node.entry.path),\n });\n }\n if (props.actions?.download) {\n items.push({\n icon: node.isFolder ? \"ti ti-file-zip\" : \"ti ti-download\",\n label: node.isFolder ? fileBrowserMessages().downloadAsZip : messages().download,\n action: () => void props.actions?.download?.(node.entry.path, node.isFolder),\n });\n }\n if (!node.isFolder && props.actions?.rename) {\n items.push({ icon: \"ti ti-cursor-text\", label: fileBrowserMessages().rename, action: () => beginRename(node) });\n }\n if (props.actions?.remove) {\n items.push({\n icon: \"ti ti-trash\",\n label: messages().delete,\n variant: \"danger\",\n action: () => void props.actions?.remove?.(node.entry.path),\n });\n }\n return items;\n };\n\n const contextNode = createMemo(() => visible().find((node) => node.entry.path === contextPath()));\n const contextItems = createMemo(() => {\n const node = contextNode();\n return node ? menuItems(node) : [];\n });\n\n const onKeyDown = (event: KeyboardEvent, node: TreeNode) => {\n if (renamingPath()) return;\n const target = event.target;\n if (target instanceof Element && target !== rowRefs.get(node.entry.path)) return;\n const rows = visible();\n const index = rows.findIndex((row) => row.entry.path === node.entry.path);\n const focus = (next: TreeNode | undefined) => {\n if (!next) return;\n focusRow(next.entry.path);\n };\n if (event.key === \"ContextMenu\" || (event.shiftKey && event.key === \"F10\")) {\n setContextPath(node.entry.path);\n return;\n }\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n focus(rows[Math.min(index + 1, rows.length - 1)] ?? rows[0]);\n } else if (event.key === \"ArrowUp\") {\n event.preventDefault();\n focus(rows[Math.max(index - 1, 0)] ?? rows[0]);\n } else if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n focus(rows[event.key === \"Home\" ? 0 : rows.length - 1]);\n } else if (event.key === \"ArrowRight\" && node.isFolder) {\n event.preventDefault();\n if (!expanded().has(node.entry.path)) toggleFolder(node.entry.path);\n else focus(rows[index + 1]?.depth === node.depth + 1 ? rows[index + 1] : undefined);\n } else if (event.key === \"ArrowLeft\" && node.isFolder && expanded().has(node.entry.path)) {\n event.preventDefault();\n toggleFolder(node.entry.path);\n } else if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n const parent = parentOf(node.entry.path);\n focus(rows.find((row) => row.entry.path === parent));\n } else if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n select(node);\n } else if (event.key === \"F2\" && !node.isFolder && props.actions?.rename) {\n event.preventDefault();\n beginRename(node);\n }\n };\n\n return (\n <ContextMenu\n class=\"k2b-content-file-tree__context-host\"\n tabIndex={-1}\n label={contextNode() ? fileBrowserMessages().actionsFor({ name: contextNode()!.name }) : fileBrowserMessages().fileActions}\n items={contextItems()}\n disabled={contextItems().length === 0}\n onOpen={() => setContextMenuOpen(true)}\n onClose={() => {\n setContextMenuOpen(false);\n const path = contextPath();\n if (path) focusRow(path);\n }}\n >\n <ul\n class={`k2b-content-file-tree ${props.class ?? \"\"}`}\n data-drop-root={dropTarget() === \"/\" ? \"true\" : undefined}\n role=\"tree\"\n aria-label={props.label ?? fileBrowserMessages().files}\n onDragOver={(event) => {\n if (!canDrop(event)) return;\n event.preventDefault();\n if (dropTarget() === null) setDropTarget(\"/\");\n }}\n onDragLeave={(event) => {\n if (event.currentTarget === event.target) setDropTarget(null);\n }}\n onDrop={(event) => handleDrop(event, \"/\")}\n >\n <For each={visible()}>\n {(node) => {\n const currentNode = () => {\n tree();\n return node;\n };\n const isSelected = () => props.selectedPath === currentNode().entry.path;\n const isDropTarget = () => currentNode().isFolder && dropTarget() === currentNode().entry.path;\n const hasItems = () => menuItems(node).length > 0;\n return (\n <li\n ref={(element) => {\n rowRefs.set(node.entry.path, element);\n }}\n class=\"k2b-content-file-tree__item\"\n role=\"treeitem\"\n tabIndex={renamingPath() === node.entry.path ? -1 : focusedPath() === node.entry.path ? 0 : -1}\n aria-label={currentNode().entry.displayName ?? currentNode().name}\n aria-level={currentNode().depth + 1}\n aria-selected={isSelected()}\n aria-expanded={currentNode().isFolder ? expanded().has(currentNode().entry.path) : undefined}\n aria-haspopup={hasItems() ? \"menu\" : undefined}\n data-context-open={contextMenuOpen() && contextPath() === node.entry.path ? \"true\" : undefined}\n onFocus={() => {\n setFocusedPath(node.entry.path);\n setContextPath(node.entry.path);\n }}\n onKeyDown={(event) => onKeyDown(event, node)}\n onContextMenu={() => setContextPath(node.entry.path)}\n >\n <Show\n when={renamingPath() === node.entry.path}\n fallback={\n <div\n data-state={isSelected() ? \"selected\" : isDropTarget() ? \"drop-target\" : \"idle\"}\n class=\"k2b-content-file-tree__row\"\n >\n <button\n type=\"button\"\n tabIndex={-1}\n class=\"k2b-content-file-tree__select\"\n style={{ \"padding-left\": `${6 + currentNode().depth * 14}px` }}\n title={currentNode().entry.path}\n draggable={Boolean(props.actions?.move)}\n onDragStart={(event) => event.dataTransfer?.setData(DRAG_MIME, node.entry.path)}\n onDragOver={(event) => {\n if (!node.isFolder || !canDrop(event)) return;\n event.preventDefault();\n event.stopPropagation();\n setDropTarget(node.entry.path);\n }}\n onDragLeave={() => {\n if (isDropTarget()) setDropTarget(null);\n }}\n onDrop={(event) => node.isFolder && handleDrop(event, node.entry.path)}\n onClick={(event) => {\n event.currentTarget.closest<HTMLElement>('[role=\"treeitem\"]')?.focus();\n select(node);\n }}\n >\n <FileTypeIcon\n size=\"sm\"\n class=\"k2b-content-file-tree__icon\"\n name={currentNode().name}\n folder={currentNode().isFolder}\n open={currentNode().isFolder && expanded().has(currentNode().entry.path)}\n icon={currentNode().isFolder ? undefined : currentNode().entry.icon}\n mediaType={currentNode().entry.mediaType ?? \"text/plain\"}\n />\n <span class=\"k2b-content-file-tree__name\">{currentNode().entry.displayName ?? currentNode().name}</span>\n <Show when={currentNode().entry.badge}>\n <span class=\"k2b-content-file-tree__badge\">{currentNode().entry.badge}</span>\n </Show>\n </button>\n <Show when={hasItems()}>\n <Dropdown.Root position=\"bottom-left\" items={menuItems(node)} label={`Actions for ${currentNode().name}`}>\n <Dropdown.Trigger\n appearance=\"plain\"\n tabIndex={-1}\n class=\"k2b-content-file-tree__actions\"\n label={`Actions for ${currentNode().name}`}\n tooltip={messages().actions}\n >\n <i class=\"ti ti-dots\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\">Actions for {currentNode().name}</span>\n </Dropdown.Trigger>\n </Dropdown.Root>\n </Show>\n </div>\n }\n >\n <input\n class=\"k2b-content-file-tree__rename\"\n style={{\n \"margin-left\": `${6 + currentNode().depth * 14}px`,\n width: `calc(100% - ${6 + currentNode().depth * 14}px)`,\n }}\n value={renameDraft()}\n ref={(element) =>\n requestAnimationFrame(() => {\n element.focus();\n element.select();\n })\n }\n onInput={(event) => setRenameDraft(event.currentTarget.value)}\n onKeyDown={(event) => {\n event.stopPropagation();\n if (event.key === \"Enter\") void commitRename(node, event.currentTarget.value);\n if (event.key === \"Escape\") cancelRename(node);\n }}\n onBlur={(event) => void commitRename(node, event.currentTarget.value)}\n />\n </Show>\n </li>\n );\n }}\n </For>\n </ul>\n </ContextMenu>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ssr as _$ssr } from "solid-js/web";
|
|
2
|
+
import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
|
|
3
|
+
import { escape as _$escape } from "solid-js/web";
|
|
4
|
+
var _tmpl$ = ["<span class=\"", "\"", " aria-hidden=\"true\"><i class=\"", "\"></i></span>"];
|
|
5
|
+
import { fileIcons } from "@k2b/stdlib";
|
|
6
|
+
|
|
7
|
+
/** The colour family a file's icon tile uses. `other` covers code, text, and unknown files. */
|
|
8
|
+
|
|
9
|
+
// Known extensions decide first: a generic media type such as `text/plain` or `text/csv` must not hide a sheet,
|
|
10
|
+
// a slide deck, a document, or an archive behind the neutral family.
|
|
11
|
+
const BY_EXTENSION = new Map([["sheet", ["xls", "xlsx", "ods", "csv"]], ["slides", ["ppt", "pptx", "odp"]], ["document", ["doc", "docx", "odt", "rtf"]], ["archive", ["zip", "tar", "gz", "tgz", "bz2", "xz", "7z", "rar"]]].flatMap(([type, extensions]) => extensions.map(extension => [extension, type])));
|
|
12
|
+
|
|
13
|
+
/** Resolve the colour family for a file or folder from its name and media type. */
|
|
14
|
+
export const fileTypeOf = file => {
|
|
15
|
+
if (file.folder) return "folder";
|
|
16
|
+
const known = BY_EXTENSION.get(file.name.split(".").pop()?.toLowerCase() ?? "");
|
|
17
|
+
if (known) return known;
|
|
18
|
+
const category = fileIcons.getFileCategory({
|
|
19
|
+
name: file.name,
|
|
20
|
+
type: "file",
|
|
21
|
+
mimeType: file.mediaType
|
|
22
|
+
});
|
|
23
|
+
return category === "pdf" || category === "image" || category === "video" || category === "audio" || category === "archive" ? category : "other";
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/** `fileIcons` adds Tailwind colour utilities that @k2b/ui does not ship; only the `ti-*` glyph is kept. */
|
|
27
|
+
const glyph = props => {
|
|
28
|
+
// `fileIcons` looks names up in plain objects, so a name such as `constructor` returns an inherited member
|
|
29
|
+
// instead of a class string; such names fall back to the generic glyph.
|
|
30
|
+
const found = props.icon ?? fileIcons.getFileIcon({
|
|
31
|
+
name: props.name,
|
|
32
|
+
type: props.folder ? "directory" : "file",
|
|
33
|
+
mimeType: props.mediaType
|
|
34
|
+
});
|
|
35
|
+
const icon = (typeof found === "string" ? found : "").split(/\s+/).filter(token => token.startsWith("ti-")).join(" ") || (props.folder ? "ti-folder" : "ti-file");
|
|
36
|
+
return props.folder && props.open ? icon.replace(/\bti-folder$/, "ti-folder-open") : icon;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A file or folder glyph in a soft chip of its type colour. Folders take the app accent hook
|
|
41
|
+
* `--k2b-app-workspace-active`; code, text, and unknown files a neutral ink. The box size is fixed per `size`.
|
|
42
|
+
*/
|
|
43
|
+
export function FileTypeIcon(props) {
|
|
44
|
+
return _$ssr(_tmpl$, `k2b-icon-tile k2b-file-type-icon ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-file-type", _$escape(fileTypeOf({
|
|
45
|
+
name: props.name,
|
|
46
|
+
mediaType: props.mediaType,
|
|
47
|
+
folder: props.folder
|
|
48
|
+
}), true), false) + _$ssrAttribute("data-size", _$escape(props.size ?? "md", true), false), `ti ${_$escape(glyph(props), true)}`);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=FileTypeIcon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["content/FileTypeIcon.tsx"],"sourcesContent":["import { fileIcons } from \"@k2b/stdlib\";\nimport type { JSX } from \"solid-js\";\n\n/** The colour family a file's icon tile uses. `other` covers code, text, and unknown files. */\nexport type FileType = \"folder\" | \"pdf\" | \"image\" | \"sheet\" | \"document\" | \"slides\" | \"video\" | \"audio\" | \"archive\" | \"other\";\n\nexport type FileTypeIconProps = {\n /** The file or folder name; its extension picks the glyph and the type colour. */\n name: string;\n mediaType?: string;\n folder?: boolean;\n /** Shows an open folder, for example the folder a list is showing. */\n open?: boolean;\n /** A Tabler icon class that replaces the glyph the name picks; the type colour still follows the name. */\n icon?: string;\n /** `sm` for tree rows, `md` for list rows, `lg` for grid previews. Defaults to `md`. */\n size?: \"sm\" | \"md\" | \"lg\";\n class?: string;\n};\n\n// Known extensions decide first: a generic media type such as `text/plain` or `text/csv` must not hide a sheet,\n// a slide deck, a document, or an archive behind the neutral family.\nconst BY_EXTENSION = new Map<string, FileType>(\n (\n [\n [\"sheet\", [\"xls\", \"xlsx\", \"ods\", \"csv\"]],\n [\"slides\", [\"ppt\", \"pptx\", \"odp\"]],\n [\"document\", [\"doc\", \"docx\", \"odt\", \"rtf\"]],\n [\"archive\", [\"zip\", \"tar\", \"gz\", \"tgz\", \"bz2\", \"xz\", \"7z\", \"rar\"]],\n ] as const\n ).flatMap(([type, extensions]) => extensions.map((extension) => [extension, type] as const)),\n);\n\n/** Resolve the colour family for a file or folder from its name and media type. */\nexport const fileTypeOf = (file: { name: string; mediaType?: string; folder?: boolean }): FileType => {\n if (file.folder) return \"folder\";\n const known = BY_EXTENSION.get(file.name.split(\".\").pop()?.toLowerCase() ?? \"\");\n if (known) return known;\n const category = fileIcons.getFileCategory({ name: file.name, type: \"file\", mimeType: file.mediaType });\n return category === \"pdf\" || category === \"image\" || category === \"video\" || category === \"audio\" || category === \"archive\"\n ? category\n : \"other\";\n};\n\n/** `fileIcons` adds Tailwind colour utilities that @k2b/ui does not ship; only the `ti-*` glyph is kept. */\nconst glyph = (props: FileTypeIconProps): string => {\n // `fileIcons` looks names up in plain objects, so a name such as `constructor` returns an inherited member\n // instead of a class string; such names fall back to the generic glyph.\n const found: unknown =\n props.icon ?? fileIcons.getFileIcon({ name: props.name, type: props.folder ? \"directory\" : \"file\", mimeType: props.mediaType });\n const icon =\n (typeof found === \"string\" ? found : \"\")\n .split(/\\s+/)\n .filter((token) => token.startsWith(\"ti-\"))\n .join(\" \") || (props.folder ? \"ti-folder\" : \"ti-file\");\n return props.folder && props.open ? icon.replace(/\\bti-folder$/, \"ti-folder-open\") : icon;\n};\n\n/**\n * A file or folder glyph in a soft chip of its type colour. Folders take the app accent hook\n * `--k2b-app-workspace-active`; code, text, and unknown files a neutral ink. The box size is fixed per `size`.\n */\nexport function FileTypeIcon(props: FileTypeIconProps): JSX.Element {\n return (\n <span\n class={`k2b-icon-tile k2b-file-type-icon ${props.class ?? \"\"}`}\n data-file-type={fileTypeOf({ name: props.name, mediaType: props.mediaType, folder: props.folder })}\n data-size={props.size ?? \"md\"}\n aria-hidden=\"true\"\n >\n <i class={`ti ${glyph(props)}`} />\n </span>\n );\n}\n"],"mappings":";;;;AAAA,SAAS,SAAS,QAAQ,aAAa;;AAGvC;;AAiBA;AACA;AACA,MAAM,YAAY,GAAG,IAAI,GAAG,CAExB,CACE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,EACxC,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,EAClC,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,EAC3C,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CACnE,CACD,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,UAAU,CAAC,GAAG,CAAE,SAAS,IAAK,CAAC,SAAS,EAAE,IAAI,CAAU,CAAC,CAC7F,CAAC;;AAED;AACA,OAAO,MAAM,UAAU,GAAI,IAA4D,IAAe;EACpG,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO,QAAQ;EAChC,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC;EAC/E,IAAI,KAAK,EAAE,OAAO,KAAK;EACvB,MAAM,QAAQ,GAAG,SAAS,CAAC,eAAe,CAAC;IAAE,IAAI,EAAE,IAAI,CAAC,IAAI;IAAE,IAAI,EAAE,MAAM;IAAE,QAAQ,EAAE,IAAI,CAAC;EAAU,CAAC,CAAC;EACvG,OAAO,QAAQ,KAAK,KAAK,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,SAAS,GACvH,QAAQ,GACR,OAAO;AACb,CAAC;;AAED;AACA,MAAM,KAAK,GAAI,KAAwB,IAAa;EAClD;EACA;EACA,MAAM,KAAc,GAClB,KAAK,CAAC,IAAI,IAAI,SAAS,CAAC,WAAW,CAAC;IAAE,IAAI,EAAE,KAAK,CAAC,IAAI;IAAE,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,WAAW,GAAG,MAAM;IAAE,QAAQ,EAAE,KAAK,CAAC;EAAU,CAAC,CAAC;EACjI,MAAM,IAAI,GACR,CAAC,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,GAAG,EAAE,EACpC,KAAK,CAAC,KAAK,CAAC,CACZ,MAAM,CAAE,KAAK,IAAK,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAC1C,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;EAC1D,OAAO,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,gBAAgB,CAAC,GAAG,IAAI;AAC3F,CAAC;;AAED;AACA;AACA;AACA;AACA,OAAO,SAAS,YAAY,CAAC,KAAwB,EAAe;EAClE,qBAEW,6CAAoC,KAAK,CAAC,KAAK,IAAI,EAAE,SAAE,4CAC9C,UAAU,CAAC;IAAE,IAAI,EAAE,KAAK,CAAC,IAAI;IAAE,SAAS,EAAE,KAAK,CAAC,SAAS;IAAE,MAAM,EAAE,KAAK,CAAC;EAAO,CAAC,CAAC,uDACvF,KAAK,CAAC,IAAI,IAAI,IAAI,iBAGnB,eAAM,KAAK,CAAC,KAAK,CAAC,SAAE;AAGpC","ignoreList":[]}
|
|
@@ -1026,7 +1026,7 @@ export default function FileView(props) {
|
|
|
1026
1026
|
},
|
|
1027
1027
|
get children() {
|
|
1028
1028
|
return _$createComponent(Placeholder, {
|
|
1029
|
-
|
|
1029
|
+
state: "loading",
|
|
1030
1030
|
get title() {
|
|
1031
1031
|
return messages().loading;
|
|
1032
1032
|
}
|
|
@@ -1038,7 +1038,7 @@ export default function FileView(props) {
|
|
|
1038
1038
|
},
|
|
1039
1039
|
get children() {
|
|
1040
1040
|
return _$createComponent(Placeholder, {
|
|
1041
|
-
|
|
1041
|
+
state: "error",
|
|
1042
1042
|
get title() {
|
|
1043
1043
|
return fileViewMessages().failedLoadFile;
|
|
1044
1044
|
},
|