@neo4j-ndl/react 4.21.2 → 4.22.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/lib/cjs/dropzone/stories/dropzone-full.story.js +5 -5
- package/lib/cjs/dropzone/stories/dropzone-full.story.js.map +1 -1
- package/lib/cjs/helpers/index.js +1 -0
- package/lib/cjs/helpers/index.js.map +1 -1
- package/lib/cjs/helpers/platform.js +59 -0
- package/lib/cjs/helpers/platform.js.map +1 -0
- package/lib/cjs/kbd/kbd-utils.js +6 -22
- package/lib/cjs/kbd/kbd-utils.js.map +1 -1
- package/lib/cjs/next/tree-view/TreeView.js +384 -66
- package/lib/cjs/next/tree-view/TreeView.js.map +1 -1
- package/lib/cjs/next/tree-view/selection.js +181 -0
- package/lib/cjs/next/tree-view/selection.js.map +1 -0
- package/lib/cjs/next/tree-view/stories/index.js +13 -1
- package/lib/cjs/next/tree-view/stories/index.js.map +1 -1
- package/lib/cjs/next/tree-view/stories/tree-view-large.story.js +57 -0
- package/lib/cjs/next/tree-view/stories/tree-view-large.story.js.map +1 -0
- package/lib/cjs/next/tree-view/stories/tree-view-lazy.story.js +1 -0
- package/lib/cjs/next/tree-view/stories/tree-view-lazy.story.js.map +1 -1
- package/lib/cjs/next/tree-view/stories/tree-view-multi.story.js +16 -40
- package/lib/cjs/next/tree-view/stories/tree-view-multi.story.js.map +1 -1
- package/lib/cjs/next/tree-view/stories/tree-view-multiple-replace.story.js +38 -0
- package/lib/cjs/next/tree-view/stories/tree-view-multiple-replace.story.js.map +1 -0
- package/lib/cjs/next/tree-view/stories/tree-view-non-selectable-folders.story.js +7 -4
- package/lib/cjs/next/tree-view/stories/tree-view-non-selectable-folders.story.js.map +1 -1
- package/lib/cjs/next/tree-view/stories/tree-view-root-selection.story.js +125 -0
- package/lib/cjs/next/tree-view/stories/tree-view-root-selection.story.js.map +1 -0
- package/lib/cjs/toast/ToastControlled.js +1 -1
- package/lib/cjs/toast/ToastControlled.js.map +1 -1
- package/lib/esm/dropzone/stories/dropzone-full.story.js +5 -5
- package/lib/esm/dropzone/stories/dropzone-full.story.js.map +1 -1
- package/lib/esm/helpers/index.js +1 -0
- package/lib/esm/helpers/index.js.map +1 -1
- package/lib/esm/helpers/platform.js +55 -0
- package/lib/esm/helpers/platform.js.map +1 -0
- package/lib/esm/kbd/kbd-utils.js +2 -18
- package/lib/esm/kbd/kbd-utils.js.map +1 -1
- package/lib/esm/next/tree-view/TreeView.js +385 -67
- package/lib/esm/next/tree-view/TreeView.js.map +1 -1
- package/lib/esm/next/tree-view/selection.js +175 -0
- package/lib/esm/next/tree-view/selection.js.map +1 -0
- package/lib/esm/next/tree-view/stories/index.js +9 -0
- package/lib/esm/next/tree-view/stories/index.js.map +1 -1
- package/lib/esm/next/tree-view/stories/tree-view-large.story.js +55 -0
- package/lib/esm/next/tree-view/stories/tree-view-large.story.js.map +1 -0
- package/lib/esm/next/tree-view/stories/tree-view-lazy.story.js +1 -0
- package/lib/esm/next/tree-view/stories/tree-view-lazy.story.js.map +1 -1
- package/lib/esm/next/tree-view/stories/tree-view-multi.story.js +16 -40
- package/lib/esm/next/tree-view/stories/tree-view-multi.story.js.map +1 -1
- package/lib/esm/next/tree-view/stories/tree-view-multiple-replace.story.js +36 -0
- package/lib/esm/next/tree-view/stories/tree-view-multiple-replace.story.js.map +1 -0
- package/lib/esm/next/tree-view/stories/tree-view-non-selectable-folders.story.js +7 -4
- package/lib/esm/next/tree-view/stories/tree-view-non-selectable-folders.story.js.map +1 -1
- package/lib/esm/next/tree-view/stories/tree-view-root-selection.story.js +123 -0
- package/lib/esm/next/tree-view/stories/tree-view-root-selection.story.js.map +1 -0
- package/lib/esm/toast/ToastControlled.js +1 -1
- package/lib/esm/toast/ToastControlled.js.map +1 -1
- package/lib/types/helpers/index.d.ts +1 -0
- package/lib/types/helpers/index.d.ts.map +1 -1
- package/lib/types/helpers/platform.d.ts +29 -0
- package/lib/types/helpers/platform.d.ts.map +1 -0
- package/lib/types/kbd/kbd-utils.d.ts +2 -5
- package/lib/types/kbd/kbd-utils.d.ts.map +1 -1
- package/lib/types/next/tree-view/TreeView.d.ts +29 -5
- package/lib/types/next/tree-view/TreeView.d.ts.map +1 -1
- package/lib/types/next/tree-view/selection.d.ts +78 -0
- package/lib/types/next/tree-view/selection.d.ts.map +1 -0
- package/lib/types/next/tree-view/stories/index.d.ts +6 -0
- package/lib/types/next/tree-view/stories/index.d.ts.map +1 -1
- package/lib/types/next/tree-view/stories/tree-view-large.story.d.ts +24 -0
- package/lib/types/next/tree-view/stories/tree-view-large.story.d.ts.map +1 -0
- package/lib/types/next/tree-view/stories/tree-view-lazy.story.d.ts.map +1 -1
- package/lib/types/next/tree-view/stories/tree-view-multi.story.d.ts +10 -0
- package/lib/types/next/tree-view/stories/tree-view-multi.story.d.ts.map +1 -1
- package/lib/types/next/tree-view/stories/tree-view-multiple-replace.story.d.ts +29 -0
- package/lib/types/next/tree-view/stories/tree-view-multiple-replace.story.d.ts.map +1 -0
- package/lib/types/next/tree-view/stories/tree-view-non-selectable-folders.story.d.ts +5 -0
- package/lib/types/next/tree-view/stories/tree-view-non-selectable-folders.story.d.ts.map +1 -1
- package/lib/types/next/tree-view/stories/tree-view-root-selection.story.d.ts +24 -0
- package/lib/types/next/tree-view/stories/tree-view-root-selection.story.d.ts.map +1 -0
- package/package.json +2 -2
- package/skills/ndl-react/SKILL.md +1 -1
- package/skills/ndl-react/components/next/tree-view.md +358 -104
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-view-lazy.story.js","sourceRoot":"","sources":["../../../../../src/next/tree-view/stories/tree-view-lazy.story.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport '@neo4j-ndl/base/lib/neo4j-ds-styles.css';\n\nimport {\n DocumentIconOutline,\n FolderIconSolid,\n PhotoIconOutline,\n} from '@neo4j-ndl/react/icons';\nimport { TreeView } from '@neo4j-ndl/react/next';\nimport { useCallback, useMemo, useRef, useState } from 'react';\n\ntype TreeNode = {\n id: string;\n label: string;\n children?: TreeNode[];\n};\n\nconst TREE_DATA: TreeNode[] = [\n {\n children: [\n {\n children: [\n { id: 'app-tsx', label: 'App.tsx' },\n { id: 'index-tsx', label: 'index.tsx' },\n { id: 'styles-css', label: 'styles.css' },\n ],\n id: 'frontend',\n label: 'Frontend',\n },\n {\n children: [\n { id: 'server-ts', label: 'server.ts' },\n { id: 'routes-ts', label: 'routes.ts' },\n ],\n id: 'backend',\n label: 'Backend',\n },\n { id: 'readme-md', label: 'README.md' },\n ],\n id: 'projects',\n label: 'Projects',\n },\n {\n children: [\n {\n children: [\n { id: 'beach-jpg', label: 'beach.jpg' },\n { id: 'sunset-jpg', label: 'sunset.jpg' },\n ],\n id: 'vacation',\n label: 'Vacation',\n },\n { id: 'profile-png', label: 'profile.png' },\n ],\n id: 'photos',\n label: 'Photos',\n },\n {\n children: [\n { id: 'resume-pdf', label: 'resume.pdf' },\n { id: 'cover-letter-pdf', label: 'cover-letter.pdf' },\n { id: 'notes-txt', label: 'notes.txt' },\n ],\n id: 'documents',\n label: 'Documents',\n },\n {\n children: [\n {\n children: [\n { id: 'chill-m3u', label: 'chill.m3u' },\n { id: 'workout-m3u', label: 'workout.m3u' },\n ],\n id: 'playlists',\n label: 'Playlists',\n },\n { id: 'favorites-m3u', label: 'favorites.m3u' },\n ],\n id: 'music',\n label: 'Music',\n },\n { id: 'todo-txt', label: 'TODO.txt' },\n];\n\nconst LOAD_DELAY_MS = 600;\n\nfunction iconForNode(node: TreeNode) {\n if (node.children) {\n return <FolderIconSolid />;\n }\n if (/\\.(jpg|jpeg|png|gif|svg)$/i.test(node.label)) {\n return <PhotoIconOutline />;\n }\n return <DocumentIconOutline />;\n}\n\ntype NodeState = {\n isExpanded: boolean;\n isLoading: boolean;\n hasLoaded: boolean;\n};\n\nconst INITIAL_NODE_STATE: NodeState = {\n hasLoaded: false,\n isExpanded: false,\n isLoading: false,\n};\n\nfunction useTreeState() {\n const [nodeStates, setNodeStates] = useState<Record<string, NodeState>>({});\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const timers = useRef<Record<string, ReturnType<typeof setTimeout>>>({});\n\n const getNodeState = useCallback(\n (id: string): NodeState => nodeStates[id] ?? INITIAL_NODE_STATE,\n [nodeStates],\n );\n\n const handleExpand = useCallback((id: string, expanded: boolean) => {\n setNodeStates((prev) => {\n const current = prev[id] ?? INITIAL_NODE_STATE;\n if (expanded && !current.hasLoaded) {\n if (timers.current[id]) {\n clearTimeout(timers.current[id]);\n }\n timers.current[id] = setTimeout(() => {\n setNodeStates((prev) => ({\n ...prev,\n [id]: { hasLoaded: true, isExpanded: true, isLoading: false },\n }));\n delete timers.current[id];\n }, LOAD_DELAY_MS);\n return {\n ...prev,\n [id]: { hasLoaded: false, isExpanded: true, isLoading: true },\n };\n }\n return { ...prev, [id]: { ...current, isExpanded: expanded } };\n });\n }, []);\n\n const handleSelect = useCallback(\n (id: string) => setSelectedId((prev) => (prev === id ? null : id)),\n [],\n );\n\n return { getNodeState, handleExpand, handleSelect, selectedId };\n}\n\ntype RenderContext = {\n getNodeState: (id: string) => NodeState;\n selectedId: string | null;\n handleExpand: (id: string, expanded: boolean) => void;\n handleSelect: (id: string) => void;\n};\n\nfunction renderNode(node: TreeNode, ctx: RenderContext) {\n const hasChildren =\n node.children !== undefined &&\n node.children !== null &&\n node.children.length > 0;\n const state = ctx.getNodeState(node.id);\n\n return (\n <TreeView.Item\n key={node.id}\n title={node.label}\n hasChildren={hasChildren}\n isExpanded={state.isExpanded}\n isLoading={state.isLoading}\n isSelected={ctx.selectedId === node.id}\n leadingVisual={iconForNode(node)}\n onExpandedChange={(expanded: boolean) =>\n ctx.handleExpand(node.id, expanded)\n }\n onSelectedChange={() => ctx.handleSelect(node.id)}\n >\n {hasChildren && state.isLoading && !state.hasLoaded && (\n <TreeView.SkeletonItem rows={2} />\n )}\n {hasChildren &&\n state.hasLoaded &&\n node.children!.map((child) => renderNode(child, ctx))}\n </TreeView.Item>\n );\n}\n\nconst Component = () => {\n const { getNodeState, selectedId, handleExpand, handleSelect } =\n useTreeState();\n\n const ctx = useMemo<RenderContext>(\n () => ({ getNodeState, handleExpand, handleSelect, selectedId }),\n [getNodeState, selectedId, handleExpand, handleSelect],\n );\n\n return (\n <TreeView ariaLabel=\"Lazy-loaded file explorer\">\n {TREE_DATA.map((node) => renderNode(node, ctx))}\n </TreeView>\n );\n};\n\nexport default Component;\n"]}
|
|
1
|
+
{"version":3,"file":"tree-view-lazy.story.js","sourceRoot":"","sources":["../../../../../src/next/tree-view/stories/tree-view-lazy.story.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport '@neo4j-ndl/base/lib/neo4j-ds-styles.css';\n\nimport {\n DocumentIconOutline,\n FolderIconSolid,\n PhotoIconOutline,\n} from '@neo4j-ndl/react/icons';\nimport { TreeView } from '@neo4j-ndl/react/next';\nimport { useCallback, useMemo, useRef, useState } from 'react';\n\ntype TreeNode = {\n id: string;\n label: string;\n children?: TreeNode[];\n};\n\nconst TREE_DATA: TreeNode[] = [\n {\n children: [\n {\n children: [\n { id: 'app-tsx', label: 'App.tsx' },\n { id: 'index-tsx', label: 'index.tsx' },\n { id: 'styles-css', label: 'styles.css' },\n ],\n id: 'frontend',\n label: 'Frontend',\n },\n {\n children: [\n { id: 'server-ts', label: 'server.ts' },\n { id: 'routes-ts', label: 'routes.ts' },\n ],\n id: 'backend',\n label: 'Backend',\n },\n { id: 'readme-md', label: 'README.md' },\n ],\n id: 'projects',\n label: 'Projects',\n },\n {\n children: [\n {\n children: [\n { id: 'beach-jpg', label: 'beach.jpg' },\n { id: 'sunset-jpg', label: 'sunset.jpg' },\n ],\n id: 'vacation',\n label: 'Vacation',\n },\n { id: 'profile-png', label: 'profile.png' },\n ],\n id: 'photos',\n label: 'Photos',\n },\n {\n children: [\n { id: 'resume-pdf', label: 'resume.pdf' },\n { id: 'cover-letter-pdf', label: 'cover-letter.pdf' },\n { id: 'notes-txt', label: 'notes.txt' },\n ],\n id: 'documents',\n label: 'Documents',\n },\n {\n children: [\n {\n children: [\n { id: 'chill-m3u', label: 'chill.m3u' },\n { id: 'workout-m3u', label: 'workout.m3u' },\n ],\n id: 'playlists',\n label: 'Playlists',\n },\n { id: 'favorites-m3u', label: 'favorites.m3u' },\n ],\n id: 'music',\n label: 'Music',\n },\n { id: 'todo-txt', label: 'TODO.txt' },\n];\n\nconst LOAD_DELAY_MS = 600;\n\nfunction iconForNode(node: TreeNode) {\n if (node.children) {\n return <FolderIconSolid />;\n }\n if (/\\.(jpg|jpeg|png|gif|svg)$/i.test(node.label)) {\n return <PhotoIconOutline />;\n }\n return <DocumentIconOutline />;\n}\n\ntype NodeState = {\n isExpanded: boolean;\n isLoading: boolean;\n hasLoaded: boolean;\n};\n\nconst INITIAL_NODE_STATE: NodeState = {\n hasLoaded: false,\n isExpanded: false,\n isLoading: false,\n};\n\nfunction useTreeState() {\n const [nodeStates, setNodeStates] = useState<Record<string, NodeState>>({});\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const timers = useRef<Record<string, ReturnType<typeof setTimeout>>>({});\n\n const getNodeState = useCallback(\n (id: string): NodeState => nodeStates[id] ?? INITIAL_NODE_STATE,\n [nodeStates],\n );\n\n const handleExpand = useCallback((id: string, expanded: boolean) => {\n setNodeStates((prev) => {\n const current = prev[id] ?? INITIAL_NODE_STATE;\n if (expanded && !current.hasLoaded) {\n if (timers.current[id]) {\n clearTimeout(timers.current[id]);\n }\n timers.current[id] = setTimeout(() => {\n setNodeStates((prev) => ({\n ...prev,\n [id]: { hasLoaded: true, isExpanded: true, isLoading: false },\n }));\n delete timers.current[id];\n }, LOAD_DELAY_MS);\n return {\n ...prev,\n [id]: { hasLoaded: false, isExpanded: true, isLoading: true },\n };\n }\n return { ...prev, [id]: { ...current, isExpanded: expanded } };\n });\n }, []);\n\n const handleSelect = useCallback(\n (id: string) => setSelectedId((prev) => (prev === id ? null : id)),\n [],\n );\n\n return { getNodeState, handleExpand, handleSelect, selectedId };\n}\n\ntype RenderContext = {\n getNodeState: (id: string) => NodeState;\n selectedId: string | null;\n handleExpand: (id: string, expanded: boolean) => void;\n handleSelect: (id: string) => void;\n};\n\nfunction renderNode(node: TreeNode, ctx: RenderContext) {\n const hasChildren =\n node.children !== undefined &&\n node.children !== null &&\n node.children.length > 0;\n const state = ctx.getNodeState(node.id);\n\n return (\n <TreeView.Item\n key={node.id}\n title={node.label}\n hasChildren={hasChildren}\n isExpanded={state.isExpanded}\n isLoading={state.isLoading}\n isSelected={ctx.selectedId === node.id}\n leadingVisual={iconForNode(node)}\n onExpandedChange={(expanded: boolean) =>\n ctx.handleExpand(node.id, expanded)\n }\n onSelectedChange={() => ctx.handleSelect(node.id)}\n >\n {hasChildren && state.isLoading && !state.hasLoaded && (\n <TreeView.SkeletonItem rows={2} />\n )}\n {/* Rendering children only while expanded keeps collapsed subtrees out\n of the DOM, so large trees only pay for the rows the user can see.\n All item state lives outside the tree (keyed by node id), so nothing\n is lost when a subtree unmounts on collapse. */}\n {hasChildren &&\n state.isExpanded &&\n state.hasLoaded &&\n node.children!.map((child) => renderNode(child, ctx))}\n </TreeView.Item>\n );\n}\n\nconst Component = () => {\n const { getNodeState, selectedId, handleExpand, handleSelect } =\n useTreeState();\n\n const ctx = useMemo<RenderContext>(\n () => ({ getNodeState, handleExpand, handleSelect, selectedId }),\n [getNodeState, selectedId, handleExpand, handleSelect],\n );\n\n return (\n <TreeView ariaLabel=\"Lazy-loaded file explorer\">\n {TREE_DATA.map((node) => renderNode(node, ctx))}\n </TreeView>\n );\n};\n\nexport default Component;\n"]}
|
|
@@ -23,49 +23,25 @@ import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
|
|
|
23
23
|
import { DocumentIconOutline, FolderIconSolid, PhotoIconOutline, } from '@neo4j-ndl/react/icons';
|
|
24
24
|
import { TreeView } from '@neo4j-ndl/react/next';
|
|
25
25
|
import { useCallback, useState } from 'react';
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (checkedCount === 0) {
|
|
37
|
-
return { isChecked: false, isIndeterminate: false };
|
|
38
|
-
}
|
|
39
|
-
if (checkedCount === enabledKeys.length) {
|
|
40
|
-
return { isChecked: true, isIndeterminate: false };
|
|
41
|
-
}
|
|
42
|
-
return { isChecked: false, isIndeterminate: true };
|
|
43
|
-
}
|
|
26
|
+
/**
|
|
27
|
+
* Every row owns its own checkbox: `onSelectedChange` reports the state the row
|
|
28
|
+
* should end up in, and the story stores exactly that. Folders are ordinary
|
|
29
|
+
* selectable rows here, unrelated to what sits inside them.
|
|
30
|
+
*
|
|
31
|
+
* Deriving a folder's state from its children instead needs the tree to own the
|
|
32
|
+
* selection, since a Shift range moves several rows at once and a cascade has
|
|
33
|
+
* to be applied to the whole set in one pass. See the root-managed selection
|
|
34
|
+
* story for that.
|
|
35
|
+
*/
|
|
44
36
|
const Component = () => {
|
|
37
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
45
38
|
const [expanded, setExpanded] = useState({});
|
|
46
|
-
const [
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
|
|
39
|
+
const [selected, setSelected] = useState({});
|
|
40
|
+
const toggleExpanded = (key) => setExpanded((prev) => (Object.assign(Object.assign({}, prev), { [key]: !prev[key] })));
|
|
41
|
+
const setRowSelected = useCallback((key, isSelected) => {
|
|
42
|
+
setSelected((prev) => (Object.assign(Object.assign({}, prev), { [key]: isSelected })));
|
|
50
43
|
}, []);
|
|
51
|
-
|
|
52
|
-
const enabledKeys = childKeys.filter((key) => !DISABLED_KEYS.has(key));
|
|
53
|
-
const isAllChecked = enabledKeys.every((key) => checked[key]);
|
|
54
|
-
setChecked((prev) => {
|
|
55
|
-
const next = Object.assign({}, prev);
|
|
56
|
-
for (const key of enabledKeys) {
|
|
57
|
-
next[key] = !isAllChecked;
|
|
58
|
-
}
|
|
59
|
-
return next;
|
|
60
|
-
});
|
|
61
|
-
}, [checked]);
|
|
62
|
-
const docState = getParentChecked(checked, [
|
|
63
|
-
...DOC_CHILDREN,
|
|
64
|
-
...WORK_CHILDREN,
|
|
65
|
-
]);
|
|
66
|
-
const workState = getParentChecked(checked, WORK_CHILDREN);
|
|
67
|
-
const imageState = getParentChecked(checked, IMAGE_CHILDREN);
|
|
68
|
-
return (_jsxs(TreeView, { ariaLabel: "File explorer", selectionMode: "multiple", children: [_jsxs(TreeView.Item, { title: "Documents", hasChildren: true, isExpanded: expanded['documents'], onExpandedChange: () => toggle('documents'), isSelected: docState.isChecked, isIndeterminate: docState.isIndeterminate, onSelectedChange: () => toggleParent([...DOC_CHILDREN, ...WORK_CHILDREN]), leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsxs(TreeView.Item, { title: "Work", hasChildren: true, isExpanded: expanded['work'], onExpandedChange: () => toggle('work'), isSelected: workState.isChecked, isIndeterminate: workState.isIndeterminate, onSelectedChange: () => toggleParent(WORK_CHILDREN), leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsx(TreeView.Item, { title: "Report.pdf", isSelected: !!checked['report'], onSelectedChange: () => toggleCheck('report'), leadingVisual: _jsx(DocumentIconOutline, {}) }), _jsx(TreeView.Item, { title: "Presentation.pptx", isDisabled: true, onSelectedChange: () => null, leadingVisual: _jsx(DocumentIconOutline, {}) })] }), _jsx(TreeView.Item, { title: "Resume.pdf", isSelected: !!checked['resume'], onSelectedChange: () => toggleCheck('resume'), leadingVisual: _jsx(DocumentIconOutline, {}) })] }), _jsxs(TreeView.Item, { title: "Images", hasChildren: true, isExpanded: expanded['images'], onExpandedChange: () => toggle('images'), isSelected: imageState.isChecked, isIndeterminate: imageState.isIndeterminate, onSelectedChange: () => toggleParent(IMAGE_CHILDREN), leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsx(TreeView.Item, { title: "Photo.jpg", isSelected: !!checked['photo'], onSelectedChange: () => toggleCheck('photo'), leadingVisual: _jsx(PhotoIconOutline, {}) }), _jsx(TreeView.Item, { title: "Screenshot.png", isSelected: !!checked['screenshot'], onSelectedChange: () => toggleCheck('screenshot'), leadingVisual: _jsx(PhotoIconOutline, {}) })] })] }));
|
|
44
|
+
return (_jsxs(TreeView, { ariaLabel: "File explorer", selectionMode: "multiple", children: [_jsxs(TreeView.Item, { title: "Documents", hasChildren: true, isExpanded: expanded['documents'], onExpandedChange: () => toggleExpanded('documents'), isSelected: (_a = selected['documents']) !== null && _a !== void 0 ? _a : false, onSelectedChange: (isSelected) => setRowSelected('documents', isSelected), leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsxs(TreeView.Item, { title: "Work", hasChildren: true, isExpanded: expanded['work'], onExpandedChange: () => toggleExpanded('work'), isSelected: (_b = selected['work']) !== null && _b !== void 0 ? _b : false, onSelectedChange: (isSelected) => setRowSelected('work', isSelected), leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsx(TreeView.Item, { title: "Report.pdf", isSelected: (_c = selected['report']) !== null && _c !== void 0 ? _c : false, onSelectedChange: (isSelected) => setRowSelected('report', isSelected), leadingVisual: _jsx(DocumentIconOutline, {}) }), _jsx(TreeView.Item, { title: "Presentation.pptx", isDisabled: true, isSelected: (_d = selected['presentation']) !== null && _d !== void 0 ? _d : false, onSelectedChange: (isSelected) => setRowSelected('presentation', isSelected), leadingVisual: _jsx(DocumentIconOutline, {}) })] }), _jsx(TreeView.Item, { title: "Resume.pdf", isSelected: (_e = selected['resume']) !== null && _e !== void 0 ? _e : false, onSelectedChange: (isSelected) => setRowSelected('resume', isSelected), leadingVisual: _jsx(DocumentIconOutline, {}) })] }), _jsxs(TreeView.Item, { title: "Images", hasChildren: true, isExpanded: expanded['images'], onExpandedChange: () => toggleExpanded('images'), isSelected: (_f = selected['images']) !== null && _f !== void 0 ? _f : false, onSelectedChange: (isSelected) => setRowSelected('images', isSelected), leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsx(TreeView.Item, { title: "Photo.jpg", isSelected: (_g = selected['photo']) !== null && _g !== void 0 ? _g : false, onSelectedChange: (isSelected) => setRowSelected('photo', isSelected), leadingVisual: _jsx(PhotoIconOutline, {}) }), _jsx(TreeView.Item, { title: "Screenshot.png", isSelected: (_h = selected['screenshot']) !== null && _h !== void 0 ? _h : false, onSelectedChange: (isSelected) => setRowSelected('screenshot', isSelected), leadingVisual: _jsx(PhotoIconOutline, {}) })] })] }));
|
|
69
45
|
};
|
|
70
46
|
export default Component;
|
|
71
47
|
//# sourceMappingURL=tree-view-multi.story.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-view-multi.story.js","sourceRoot":"","sources":["../../../../../src/next/tree-view/stories/tree-view-multi.story.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,yCAAyC,CAAC;AAEjD,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"tree-view-multi.story.js","sourceRoot":"","sources":["../../../../../src/next/tree-view/stories/tree-view-multi.story.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport '@neo4j-ndl/base/lib/neo4j-ds-styles.css';\n\nimport {\n DocumentIconOutline,\n FolderIconSolid,\n PhotoIconOutline,\n} from '@neo4j-ndl/react/icons';\nimport { TreeView } from '@neo4j-ndl/react/next';\nimport { useCallback, useState } from 'react';\n\n/**\n * Every row owns its own checkbox: `onSelectedChange` reports the state the row\n * should end up in, and the story stores exactly that. Folders are ordinary\n * selectable rows here, unrelated to what sits inside them.\n *\n * Deriving a folder's state from its children instead needs the tree to own the\n * selection, since a Shift range moves several rows at once and a cascade has\n * to be applied to the whole set in one pass. See the root-managed selection\n * story for that.\n */\nconst Component = () => {\n const [expanded, setExpanded] = useState<Record<string, boolean>>({});\n const [selected, setSelected] = useState<Record<string, boolean>>({});\n\n const toggleExpanded = (key: string) =>\n setExpanded((prev) => ({ ...prev, [key]: !prev[key] }));\n\n const setRowSelected = useCallback((key: string, isSelected: boolean) => {\n setSelected((prev) => ({ ...prev, [key]: isSelected }));\n }, []);\n\n return (\n <TreeView ariaLabel=\"File explorer\" selectionMode=\"multiple\">\n <TreeView.Item\n title=\"Documents\"\n hasChildren\n isExpanded={expanded['documents']}\n onExpandedChange={() => toggleExpanded('documents')}\n isSelected={selected['documents'] ?? false}\n onSelectedChange={(isSelected) =>\n setRowSelected('documents', isSelected)\n }\n leadingVisual={<FolderIconSolid />}\n >\n <TreeView.Item\n title=\"Work\"\n hasChildren\n isExpanded={expanded['work']}\n onExpandedChange={() => toggleExpanded('work')}\n isSelected={selected['work'] ?? false}\n onSelectedChange={(isSelected) => setRowSelected('work', isSelected)}\n leadingVisual={<FolderIconSolid />}\n >\n <TreeView.Item\n title=\"Report.pdf\"\n isSelected={selected['report'] ?? false}\n onSelectedChange={(isSelected) =>\n setRowSelected('report', isSelected)\n }\n leadingVisual={<DocumentIconOutline />}\n />\n <TreeView.Item\n title=\"Presentation.pptx\"\n isDisabled\n isSelected={selected['presentation'] ?? false}\n onSelectedChange={(isSelected) =>\n setRowSelected('presentation', isSelected)\n }\n leadingVisual={<DocumentIconOutline />}\n />\n </TreeView.Item>\n <TreeView.Item\n title=\"Resume.pdf\"\n isSelected={selected['resume'] ?? false}\n onSelectedChange={(isSelected) =>\n setRowSelected('resume', isSelected)\n }\n leadingVisual={<DocumentIconOutline />}\n />\n </TreeView.Item>\n <TreeView.Item\n title=\"Images\"\n hasChildren\n isExpanded={expanded['images']}\n onExpandedChange={() => toggleExpanded('images')}\n isSelected={selected['images'] ?? false}\n onSelectedChange={(isSelected) => setRowSelected('images', isSelected)}\n leadingVisual={<FolderIconSolid />}\n >\n <TreeView.Item\n title=\"Photo.jpg\"\n isSelected={selected['photo'] ?? false}\n onSelectedChange={(isSelected) => setRowSelected('photo', isSelected)}\n leadingVisual={<PhotoIconOutline />}\n />\n <TreeView.Item\n title=\"Screenshot.png\"\n isSelected={selected['screenshot'] ?? false}\n onSelectedChange={(isSelected) =>\n setRowSelected('screenshot', isSelected)\n }\n leadingVisual={<PhotoIconOutline />}\n />\n </TreeView.Item>\n </TreeView>\n );\n};\n\nexport default Component;\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) "Neo4j"
|
|
5
|
+
* Neo4j Sweden AB [http://neo4j.com]
|
|
6
|
+
*
|
|
7
|
+
* This file is part of Neo4j.
|
|
8
|
+
*
|
|
9
|
+
* Neo4j is free software: you can redistribute it and/or modify
|
|
10
|
+
* it under the terms of the GNU General Public License as published by
|
|
11
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
12
|
+
* (at your option) any later version.
|
|
13
|
+
*
|
|
14
|
+
* This program is distributed in the hope that it will be useful,
|
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
|
+
* GNU General Public License for more details.
|
|
18
|
+
*
|
|
19
|
+
* You should have received a copy of the GNU General Public License
|
|
20
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
+
*/
|
|
22
|
+
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
|
|
23
|
+
import { DocumentIconOutline, FolderIconSolid, PhotoIconOutline, } from '@neo4j-ndl/react/icons';
|
|
24
|
+
import { TreeView } from '@neo4j-ndl/react/next';
|
|
25
|
+
import { useState } from 'react';
|
|
26
|
+
/**
|
|
27
|
+
* Letting the tree own the selection keeps the items declarative: they carry an
|
|
28
|
+
* `id` and nothing else, and a Shift range that moves several rows at once
|
|
29
|
+
* arrives as a single `onSelectedIdsChange`.
|
|
30
|
+
*/
|
|
31
|
+
const Component = () => {
|
|
32
|
+
const [selectedIds, setSelectedIds] = useState([]);
|
|
33
|
+
return (_jsxs(TreeView, { ariaLabel: "File explorer", selectionMode: "multiple-replace", selectedIds: selectedIds, onSelectedIdsChange: setSelectedIds, children: [_jsxs(TreeView.Item, { id: "documents", title: "Documents", hasChildren: true, defaultExpanded: true, leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsxs(TreeView.Item, { id: "work", title: "Work", hasChildren: true, defaultExpanded: true, leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsx(TreeView.Item, { id: "report", title: "Report.pdf", isDisabled: true, leadingVisual: _jsx(DocumentIconOutline, {}) }), _jsx(TreeView.Item, { id: "presentation", title: "Presentation.pptx", leadingVisual: _jsx(DocumentIconOutline, {}) })] }), _jsx(TreeView.Item, { id: "resume", title: "Resume.pdf", leadingVisual: _jsx(DocumentIconOutline, {}) })] }), _jsxs(TreeView.Item, { id: "images", title: "Images", hasChildren: true, leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsx(TreeView.Item, { id: "photo", title: "Photo.jpg", leadingVisual: _jsx(PhotoIconOutline, {}) }), _jsx(TreeView.Item, { id: "screenshot", title: "Screenshot.png", leadingVisual: _jsx(PhotoIconOutline, {}) })] })] }));
|
|
34
|
+
};
|
|
35
|
+
export default Component;
|
|
36
|
+
//# sourceMappingURL=tree-view-multiple-replace.story.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-view-multiple-replace.story.js","sourceRoot":"","sources":["../../../../../src/next/tree-view/stories/tree-view-multiple-replace.story.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,yCAAyC,CAAC;AAEjD,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC;;;;GAIG;AACH,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IAE7D,OAAO,CACL,MAAC,QAAQ,IACP,SAAS,EAAC,eAAe,EACzB,aAAa,EAAC,kBAAkB,EAChC,WAAW,EAAE,WAAW,EACxB,mBAAmB,EAAE,cAAc,aAEnC,MAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,WAAW,EACd,KAAK,EAAC,WAAW,EACjB,WAAW,QACX,eAAe,QACf,aAAa,EAAE,KAAC,eAAe,KAAG,aAElC,MAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,MAAM,EACT,KAAK,EAAC,MAAM,EACZ,WAAW,QACX,eAAe,QACf,aAAa,EAAE,KAAC,eAAe,KAAG,aAElC,KAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,QAAQ,EACX,KAAK,EAAC,YAAY,EAClB,UAAU,QACV,aAAa,EAAE,KAAC,mBAAmB,KAAG,GACtC,EACF,KAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,cAAc,EACjB,KAAK,EAAC,mBAAmB,EACzB,aAAa,EAAE,KAAC,mBAAmB,KAAG,GACtC,IACY,EAChB,KAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,QAAQ,EACX,KAAK,EAAC,YAAY,EAClB,aAAa,EAAE,KAAC,mBAAmB,KAAG,GACtC,IACY,EAChB,MAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,QAAQ,EACX,KAAK,EAAC,QAAQ,EACd,WAAW,QACX,aAAa,EAAE,KAAC,eAAe,KAAG,aAElC,KAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,OAAO,EACV,KAAK,EAAC,WAAW,EACjB,aAAa,EAAE,KAAC,gBAAgB,KAAG,GACnC,EACF,KAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,YAAY,EACf,KAAK,EAAC,gBAAgB,EACtB,aAAa,EAAE,KAAC,gBAAgB,KAAG,GACnC,IACY,IACP,CACZ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport '@neo4j-ndl/base/lib/neo4j-ds-styles.css';\n\nimport {\n DocumentIconOutline,\n FolderIconSolid,\n PhotoIconOutline,\n} from '@neo4j-ndl/react/icons';\nimport { TreeView } from '@neo4j-ndl/react/next';\nimport { useState } from 'react';\n\n/**\n * Letting the tree own the selection keeps the items declarative: they carry an\n * `id` and nothing else, and a Shift range that moves several rows at once\n * arrives as a single `onSelectedIdsChange`.\n */\nconst Component = () => {\n const [selectedIds, setSelectedIds] = useState<string[]>([]);\n\n return (\n <TreeView\n ariaLabel=\"File explorer\"\n selectionMode=\"multiple-replace\"\n selectedIds={selectedIds}\n onSelectedIdsChange={setSelectedIds}\n >\n <TreeView.Item\n id=\"documents\"\n title=\"Documents\"\n hasChildren\n defaultExpanded\n leadingVisual={<FolderIconSolid />}\n >\n <TreeView.Item\n id=\"work\"\n title=\"Work\"\n hasChildren\n defaultExpanded\n leadingVisual={<FolderIconSolid />}\n >\n <TreeView.Item\n id=\"report\"\n title=\"Report.pdf\"\n isDisabled\n leadingVisual={<DocumentIconOutline />}\n />\n <TreeView.Item\n id=\"presentation\"\n title=\"Presentation.pptx\"\n leadingVisual={<DocumentIconOutline />}\n />\n </TreeView.Item>\n <TreeView.Item\n id=\"resume\"\n title=\"Resume.pdf\"\n leadingVisual={<DocumentIconOutline />}\n />\n </TreeView.Item>\n <TreeView.Item\n id=\"images\"\n title=\"Images\"\n hasChildren\n leadingVisual={<FolderIconSolid />}\n >\n <TreeView.Item\n id=\"photo\"\n title=\"Photo.jpg\"\n leadingVisual={<PhotoIconOutline />}\n />\n <TreeView.Item\n id=\"screenshot\"\n title=\"Screenshot.png\"\n leadingVisual={<PhotoIconOutline />}\n />\n </TreeView.Item>\n </TreeView>\n );\n};\n\nexport default Component;\n"]}
|
|
@@ -23,11 +23,14 @@ import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
|
|
|
23
23
|
import { DocumentIconOutline, FolderIconSolid } from '@neo4j-ndl/react/icons';
|
|
24
24
|
import { TreeView } from '@neo4j-ndl/react/next';
|
|
25
25
|
import { useState } from 'react';
|
|
26
|
+
/**
|
|
27
|
+
* Folders here are pure containers: `isSelectable={false}` makes them expand on
|
|
28
|
+
* click without ever becoming part of the selection, and screen readers
|
|
29
|
+
* announce them as non-selectable rather than as unselected rows.
|
|
30
|
+
*/
|
|
26
31
|
const Component = () => {
|
|
27
|
-
const [
|
|
28
|
-
|
|
29
|
-
const toggle = (key) => setExpanded((prev) => (Object.assign(Object.assign({}, prev), { [key]: !prev[key] })));
|
|
30
|
-
return (_jsxs(TreeView, { ariaLabel: "File explorer", children: [_jsxs(TreeView.Item, { title: "Documents", hasChildren: true, isExpanded: expanded['documents'], onExpandedChange: () => toggle('documents'), leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsxs(TreeView.Item, { title: "Work", hasChildren: true, isExpanded: expanded['work'], onExpandedChange: () => toggle('work'), leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsx(TreeView.Item, { title: "Report.pdf", isSelected: selected === 'report', onSelectedChange: () => setSelected('report'), leadingVisual: _jsx(DocumentIconOutline, {}) }), _jsx(TreeView.Item, { title: "Presentation.pptx", isSelected: selected === 'presentation', onSelectedChange: () => setSelected('presentation'), leadingVisual: _jsx(DocumentIconOutline, {}) })] }), _jsx(TreeView.Item, { title: "Resume.pdf", isSelected: selected === 'resume', onSelectedChange: () => setSelected('resume'), leadingVisual: _jsx(DocumentIconOutline, {}) })] }), _jsxs(TreeView.Item, { title: "Images", hasChildren: true, isExpanded: expanded['images'], onExpandedChange: () => toggle('images'), leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsx(TreeView.Item, { title: "Photo.jpg", isSelected: selected === 'photo', onSelectedChange: () => setSelected('photo'), leadingVisual: _jsx(DocumentIconOutline, {}) }), _jsx(TreeView.Item, { title: "Screenshot.png", isSelected: selected === 'screenshot', onSelectedChange: () => setSelected('screenshot'), leadingVisual: _jsx(DocumentIconOutline, {}) })] })] }));
|
|
32
|
+
const [selectedIds, setSelectedIds] = useState([]);
|
|
33
|
+
return (_jsxs(TreeView, { ariaLabel: "File explorer", selectedIds: selectedIds, onSelectedIdsChange: setSelectedIds, children: [_jsxs(TreeView.Item, { id: "documents", title: "Documents", hasChildren: true, isSelectable: false, leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsxs(TreeView.Item, { id: "work", title: "Work", hasChildren: true, isSelectable: false, leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsx(TreeView.Item, { id: "report", title: "Report.pdf", leadingVisual: _jsx(DocumentIconOutline, {}) }), _jsx(TreeView.Item, { id: "presentation", title: "Presentation.pptx", leadingVisual: _jsx(DocumentIconOutline, {}) })] }), _jsx(TreeView.Item, { id: "resume", title: "Resume.pdf", leadingVisual: _jsx(DocumentIconOutline, {}) })] }), _jsxs(TreeView.Item, { id: "images", title: "Images", hasChildren: true, isSelectable: false, leadingVisual: _jsx(FolderIconSolid, {}), children: [_jsx(TreeView.Item, { id: "photo", title: "Photo.jpg", leadingVisual: _jsx(DocumentIconOutline, {}) }), _jsx(TreeView.Item, { id: "screenshot", title: "Screenshot.png", leadingVisual: _jsx(DocumentIconOutline, {}) })] })] }));
|
|
31
34
|
};
|
|
32
35
|
export default Component;
|
|
33
36
|
//# sourceMappingURL=tree-view-non-selectable-folders.story.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree-view-non-selectable-folders.story.js","sourceRoot":"","sources":["../../../../../src/next/tree-view/stories/tree-view-non-selectable-folders.story.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,yCAAyC,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"tree-view-non-selectable-folders.story.js","sourceRoot":"","sources":["../../../../../src/next/tree-view/stories/tree-view-non-selectable-folders.story.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,yCAAyC,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC;;;;GAIG;AACH,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IAE7D,OAAO,CACL,MAAC,QAAQ,IACP,SAAS,EAAC,eAAe,EACzB,WAAW,EAAE,WAAW,EACxB,mBAAmB,EAAE,cAAc,aAEnC,MAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,WAAW,EACd,KAAK,EAAC,WAAW,EACjB,WAAW,QACX,YAAY,EAAE,KAAK,EACnB,aAAa,EAAE,KAAC,eAAe,KAAG,aAElC,MAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,MAAM,EACT,KAAK,EAAC,MAAM,EACZ,WAAW,QACX,YAAY,EAAE,KAAK,EACnB,aAAa,EAAE,KAAC,eAAe,KAAG,aAElC,KAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,QAAQ,EACX,KAAK,EAAC,YAAY,EAClB,aAAa,EAAE,KAAC,mBAAmB,KAAG,GACtC,EACF,KAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,cAAc,EACjB,KAAK,EAAC,mBAAmB,EACzB,aAAa,EAAE,KAAC,mBAAmB,KAAG,GACtC,IACY,EAChB,KAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,QAAQ,EACX,KAAK,EAAC,YAAY,EAClB,aAAa,EAAE,KAAC,mBAAmB,KAAG,GACtC,IACY,EAChB,MAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,QAAQ,EACX,KAAK,EAAC,QAAQ,EACd,WAAW,QACX,YAAY,EAAE,KAAK,EACnB,aAAa,EAAE,KAAC,eAAe,KAAG,aAElC,KAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,OAAO,EACV,KAAK,EAAC,WAAW,EACjB,aAAa,EAAE,KAAC,mBAAmB,KAAG,GACtC,EACF,KAAC,QAAQ,CAAC,IAAI,IACZ,EAAE,EAAC,YAAY,EACf,KAAK,EAAC,gBAAgB,EACtB,aAAa,EAAE,KAAC,mBAAmB,KAAG,GACtC,IACY,IACP,CACZ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport '@neo4j-ndl/base/lib/neo4j-ds-styles.css';\n\nimport { DocumentIconOutline, FolderIconSolid } from '@neo4j-ndl/react/icons';\nimport { TreeView } from '@neo4j-ndl/react/next';\nimport { useState } from 'react';\n\n/**\n * Folders here are pure containers: `isSelectable={false}` makes them expand on\n * click without ever becoming part of the selection, and screen readers\n * announce them as non-selectable rather than as unselected rows.\n */\nconst Component = () => {\n const [selectedIds, setSelectedIds] = useState<string[]>([]);\n\n return (\n <TreeView\n ariaLabel=\"File explorer\"\n selectedIds={selectedIds}\n onSelectedIdsChange={setSelectedIds}\n >\n <TreeView.Item\n id=\"documents\"\n title=\"Documents\"\n hasChildren\n isSelectable={false}\n leadingVisual={<FolderIconSolid />}\n >\n <TreeView.Item\n id=\"work\"\n title=\"Work\"\n hasChildren\n isSelectable={false}\n leadingVisual={<FolderIconSolid />}\n >\n <TreeView.Item\n id=\"report\"\n title=\"Report.pdf\"\n leadingVisual={<DocumentIconOutline />}\n />\n <TreeView.Item\n id=\"presentation\"\n title=\"Presentation.pptx\"\n leadingVisual={<DocumentIconOutline />}\n />\n </TreeView.Item>\n <TreeView.Item\n id=\"resume\"\n title=\"Resume.pdf\"\n leadingVisual={<DocumentIconOutline />}\n />\n </TreeView.Item>\n <TreeView.Item\n id=\"images\"\n title=\"Images\"\n hasChildren\n isSelectable={false}\n leadingVisual={<FolderIconSolid />}\n >\n <TreeView.Item\n id=\"photo\"\n title=\"Photo.jpg\"\n leadingVisual={<DocumentIconOutline />}\n />\n <TreeView.Item\n id=\"screenshot\"\n title=\"Screenshot.png\"\n leadingVisual={<DocumentIconOutline />}\n />\n </TreeView.Item>\n </TreeView>\n );\n};\n\nexport default Component;\n"]}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) "Neo4j"
|
|
5
|
+
* Neo4j Sweden AB [http://neo4j.com]
|
|
6
|
+
*
|
|
7
|
+
* This file is part of Neo4j.
|
|
8
|
+
*
|
|
9
|
+
* Neo4j is free software: you can redistribute it and/or modify
|
|
10
|
+
* it under the terms of the GNU General Public License as published by
|
|
11
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
12
|
+
* (at your option) any later version.
|
|
13
|
+
*
|
|
14
|
+
* This program is distributed in the hope that it will be useful,
|
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
|
+
* GNU General Public License for more details.
|
|
18
|
+
*
|
|
19
|
+
* You should have received a copy of the GNU General Public License
|
|
20
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
+
*/
|
|
22
|
+
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
|
|
23
|
+
import { DocumentIconOutline, FolderIconSolid } from '@neo4j-ndl/react/icons';
|
|
24
|
+
import { TreeView } from '@neo4j-ndl/react/next';
|
|
25
|
+
import { useCallback, useState } from 'react';
|
|
26
|
+
const files = [
|
|
27
|
+
{
|
|
28
|
+
children: [
|
|
29
|
+
{
|
|
30
|
+
children: [
|
|
31
|
+
{ id: 'report', title: 'Report.pdf' },
|
|
32
|
+
{ id: 'presentation', title: 'Presentation.pptx' },
|
|
33
|
+
],
|
|
34
|
+
id: 'work',
|
|
35
|
+
title: 'Work',
|
|
36
|
+
},
|
|
37
|
+
{ id: 'resume', title: 'Resume.pdf' },
|
|
38
|
+
],
|
|
39
|
+
id: 'documents',
|
|
40
|
+
title: 'Documents',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
children: [
|
|
44
|
+
{ id: 'photo', title: 'Photo.jpg' },
|
|
45
|
+
{ id: 'screenshot', title: 'Screenshot.png' },
|
|
46
|
+
],
|
|
47
|
+
id: 'images',
|
|
48
|
+
title: 'Images',
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
const walk = (nodes, visit) => {
|
|
52
|
+
nodes.forEach((node) => {
|
|
53
|
+
var _a;
|
|
54
|
+
visit(node);
|
|
55
|
+
walk((_a = node.children) !== null && _a !== void 0 ? _a : [], visit);
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
const getDescendantIds = (node) => {
|
|
59
|
+
var _a;
|
|
60
|
+
return ((_a = node.children) !== null && _a !== void 0 ? _a : []).flatMap((child) => [
|
|
61
|
+
child.id,
|
|
62
|
+
...getDescendantIds(child),
|
|
63
|
+
]);
|
|
64
|
+
};
|
|
65
|
+
const getLeafIds = (node) => node.children === undefined ? [node.id] : node.children.flatMap(getLeafIds);
|
|
66
|
+
/** Folders follow their contents: selected only when every leaf below them is. */
|
|
67
|
+
const syncFolders = (nodes, selected) => {
|
|
68
|
+
nodes.forEach((node) => {
|
|
69
|
+
if (node.children === undefined) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
syncFolders(node.children, selected);
|
|
73
|
+
if (getLeafIds(node).every((id) => selected.has(id))) {
|
|
74
|
+
selected.add(node.id);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
selected.delete(node.id);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
const Component = () => {
|
|
82
|
+
const [selectedIds, setSelectedIds] = useState(['resume']);
|
|
83
|
+
const selected = new Set(selectedIds);
|
|
84
|
+
/**
|
|
85
|
+
* The tree reports the whole selection at once, so cascading folders onto
|
|
86
|
+
* their contents takes a single pass even when a Shift range flipped many
|
|
87
|
+
* rows.
|
|
88
|
+
*/
|
|
89
|
+
const handleSelectedIdsChange = useCallback((nextIds) => {
|
|
90
|
+
setSelectedIds((previousIds) => {
|
|
91
|
+
const next = new Set(nextIds);
|
|
92
|
+
const previous = new Set(previousIds);
|
|
93
|
+
walk(files, (node) => {
|
|
94
|
+
const isSelected = next.has(node.id);
|
|
95
|
+
if (node.children === undefined ||
|
|
96
|
+
isSelected === previous.has(node.id)) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
getDescendantIds(node).forEach((id) => {
|
|
100
|
+
if (isSelected) {
|
|
101
|
+
next.add(id);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
next.delete(id);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
syncFolders(files, next);
|
|
109
|
+
return [...next];
|
|
110
|
+
});
|
|
111
|
+
}, []);
|
|
112
|
+
const renderNode = (node) => {
|
|
113
|
+
var _a;
|
|
114
|
+
const leafIds = getLeafIds(node);
|
|
115
|
+
const selectedLeafCount = leafIds.filter((id) => selected.has(id)).length;
|
|
116
|
+
return (_jsx(TreeView.Item, { id: node.id, title: node.title, defaultExpanded: true, isIndeterminate: node.children !== undefined &&
|
|
117
|
+
selectedLeafCount > 0 &&
|
|
118
|
+
selectedLeafCount < leafIds.length, leadingVisual: node.children === undefined ? (_jsx(DocumentIconOutline, {})) : (_jsx(FolderIconSolid, {})), children: (_a = node.children) === null || _a === void 0 ? void 0 : _a.map(renderNode) }, node.id));
|
|
119
|
+
};
|
|
120
|
+
return (_jsx(TreeView, { ariaLabel: "File explorer", selectionMode: "multiple", selectedIds: selectedIds, onSelectedIdsChange: handleSelectedIdsChange, children: files.map(renderNode) }));
|
|
121
|
+
};
|
|
122
|
+
export default Component;
|
|
123
|
+
//# sourceMappingURL=tree-view-root-selection.story.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-view-root-selection.story.js","sourceRoot":"","sources":["../../../../../src/next/tree-view/stories/tree-view-root-selection.story.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport '@neo4j-ndl/base/lib/neo4j-ds-styles.css';\n\nimport { DocumentIconOutline, FolderIconSolid } from '@neo4j-ndl/react/icons';\nimport { TreeView } from '@neo4j-ndl/react/next';\nimport { useCallback, useState } from 'react';\n\ntype FileNode = {\n children?: FileNode[];\n id: string;\n title: string;\n};\n\nconst files: FileNode[] = [\n {\n children: [\n {\n children: [\n { id: 'report', title: 'Report.pdf' },\n { id: 'presentation', title: 'Presentation.pptx' },\n ],\n id: 'work',\n title: 'Work',\n },\n { id: 'resume', title: 'Resume.pdf' },\n ],\n id: 'documents',\n title: 'Documents',\n },\n {\n children: [\n { id: 'photo', title: 'Photo.jpg' },\n { id: 'screenshot', title: 'Screenshot.png' },\n ],\n id: 'images',\n title: 'Images',\n },\n];\n\nconst walk = (nodes: FileNode[], visit: (node: FileNode) => void) => {\n nodes.forEach((node) => {\n visit(node);\n walk(node.children ?? [], visit);\n });\n};\n\nconst getDescendantIds = (node: FileNode): string[] =>\n (node.children ?? []).flatMap((child) => [\n child.id,\n ...getDescendantIds(child),\n ]);\n\nconst getLeafIds = (node: FileNode): string[] =>\n node.children === undefined ? [node.id] : node.children.flatMap(getLeafIds);\n\n/** Folders follow their contents: selected only when every leaf below them is. */\nconst syncFolders = (nodes: FileNode[], selected: Set<string>) => {\n nodes.forEach((node) => {\n if (node.children === undefined) {\n return;\n }\n syncFolders(node.children, selected);\n if (getLeafIds(node).every((id) => selected.has(id))) {\n selected.add(node.id);\n } else {\n selected.delete(node.id);\n }\n });\n};\n\nconst Component = () => {\n const [selectedIds, setSelectedIds] = useState<string[]>(['resume']);\n const selected = new Set(selectedIds);\n\n /**\n * The tree reports the whole selection at once, so cascading folders onto\n * their contents takes a single pass even when a Shift range flipped many\n * rows.\n */\n const handleSelectedIdsChange = useCallback((nextIds: string[]) => {\n setSelectedIds((previousIds) => {\n const next = new Set(nextIds);\n const previous = new Set(previousIds);\n walk(files, (node) => {\n const isSelected = next.has(node.id);\n if (\n node.children === undefined ||\n isSelected === previous.has(node.id)\n ) {\n return;\n }\n getDescendantIds(node).forEach((id) => {\n if (isSelected) {\n next.add(id);\n } else {\n next.delete(id);\n }\n });\n });\n syncFolders(files, next);\n return [...next];\n });\n }, []);\n\n const renderNode = (node: FileNode) => {\n const leafIds = getLeafIds(node);\n const selectedLeafCount = leafIds.filter((id) => selected.has(id)).length;\n return (\n <TreeView.Item\n key={node.id}\n id={node.id}\n title={node.title}\n defaultExpanded\n isIndeterminate={\n node.children !== undefined &&\n selectedLeafCount > 0 &&\n selectedLeafCount < leafIds.length\n }\n leadingVisual={\n node.children === undefined ? (\n <DocumentIconOutline />\n ) : (\n <FolderIconSolid />\n )\n }\n >\n {node.children?.map(renderNode)}\n </TreeView.Item>\n );\n };\n\n return (\n <TreeView\n ariaLabel=\"File explorer\"\n selectionMode=\"multiple\"\n selectedIds={selectedIds}\n onSelectedIdsChange={handleSelectedIdsChange}\n >\n {files.map(renderNode)}\n </TreeView>\n );\n};\n\nexport default Component;\n"]}
|
|
@@ -60,7 +60,7 @@ const toastWithVariant = (input) => {
|
|
|
60
60
|
case 'danger':
|
|
61
61
|
return toast.danger(input.text, Object.assign(Object.assign({}, commonRootProps), { sonnerToastProps: commonSonnerProps }));
|
|
62
62
|
case 'progress-bar':
|
|
63
|
-
return toast.progressBar(input.text, Object.assign(Object.assign({}, commonRootProps), {
|
|
63
|
+
return toast.progressBar(input.text, Object.assign(Object.assign({}, commonRootProps), { initialProgressBarValue: input.progressBarValue, sonnerToastProps: commonSonnerProps }));
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
66
|
export const ToasterControlled = (_a) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToastControlled.js","sourceRoot":"","sources":["../../../src/toast/ToastControlled.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG5C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAoC,MAAM,SAAS,CAAC;AAsB3E,MAAM,gBAAgB,GAAG,CAAC,KAAsB,EAAE,EAAE;IAClD,MAAM,eAAe,GAAG;QACtB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,WAAW,EAAE,KAAK,CAAC,OAAO,KAAK,SAAS;QACxC,YAAY,EAAE,IAAI;QAClB,QAAQ,CAAC,EAAW;;YAClB,MAAA,KAAK,CAAC,QAAQ,sDAAG,EAAE,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,CAAC,EAAW;;YACjB,MAAA,KAAK,CAAC,OAAO,sDAAG,EAAE,CAAC,CAAC;QACtB,CAAC;QACD,eAAe,EAAE,KAAK;QACtB,mBAAmB,EAAE,KAAK;KAC3B,CAAC;IAEF,MAAM,iBAAiB,GAAkB;QACvC,WAAW,EAAE,KAAK;QAClB,EAAE,EAAE,KAAK,CAAC,EAAE;KACb,CAAC;IAEF,QAAQ,KAAK,CAAC,OAAO,EAAE,CAAC;QACtB,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,kCAC1B,eAAe,KAClB,gBAAgB,EAAE,iBAAiB,IACnC,CAAC;QACL,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,kCAC1B,eAAe,KAClB,gBAAgB,EAAE,iBAAiB,IACnC,CAAC;QACL,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,kCACzB,eAAe,KAClB,gBAAgB,EAAE,iBAAiB,IACnC,CAAC;QACL,KAAK,cAAc;YACjB,OAAO,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,kCAC9B,eAAe,KAClB,
|
|
1
|
+
{"version":3,"file":"ToastControlled.js","sourceRoot":"","sources":["../../../src/toast/ToastControlled.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG5C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAoC,MAAM,SAAS,CAAC;AAsB3E,MAAM,gBAAgB,GAAG,CAAC,KAAsB,EAAE,EAAE;IAClD,MAAM,eAAe,GAAG;QACtB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,WAAW,EAAE,KAAK,CAAC,OAAO,KAAK,SAAS;QACxC,YAAY,EAAE,IAAI;QAClB,QAAQ,CAAC,EAAW;;YAClB,MAAA,KAAK,CAAC,QAAQ,sDAAG,EAAE,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,CAAC,EAAW;;YACjB,MAAA,KAAK,CAAC,OAAO,sDAAG,EAAE,CAAC,CAAC;QACtB,CAAC;QACD,eAAe,EAAE,KAAK;QACtB,mBAAmB,EAAE,KAAK;KAC3B,CAAC;IAEF,MAAM,iBAAiB,GAAkB;QACvC,WAAW,EAAE,KAAK;QAClB,EAAE,EAAE,KAAK,CAAC,EAAE;KACb,CAAC;IAEF,QAAQ,KAAK,CAAC,OAAO,EAAE,CAAC;QACtB,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,kCAC1B,eAAe,KAClB,gBAAgB,EAAE,iBAAiB,IACnC,CAAC;QACL,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,kCAC1B,eAAe,KAClB,gBAAgB,EAAE,iBAAiB,IACnC,CAAC;QACL,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,kCACzB,eAAe,KAClB,gBAAgB,EAAE,iBAAiB,IACnC,CAAC;QACL,KAAK,cAAc;YACjB,OAAO,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,kCAC9B,eAAe,KAClB,uBAAuB,EAAE,KAAK,CAAC,gBAAgB,EAC/C,gBAAgB,EAAE,iBAAiB,IACnC,CAAC;IACP,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,EAGX,EAAE,EAAE;QAHO,EAChC,MAAM,OAEe,EADlB,SAAS,cAFoB,UAGjC,CADa;IAEZ,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAoB,EAAE,CAAC,CAAC;IAEtE,SAAS,CAAC,GAAG,EAAE;QACb,kCAAkC;QAClC,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,CACtC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CACxD,CAAC;QACF,aAAa,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;YACrC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,kDAAkD;QAClD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QAED,cAAc,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAE1B,OAAO,KAAC,OAAO,kBAAC,aAAa,EAAE,CAAC,IAAM,SAAS,EAAI,CAAC;AACtD,CAAC,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\nimport { useEffect, useState } from 'react';\nimport { type ExternalToast } from 'sonner';\n\nimport { toast, Toaster, type ToastId, type ToastVariants } from './Toast';\n\ntype ControlledToast = {\n id: ToastId;\n text: string;\n onClose?: (id: ToastId) => void;\n actionLabel?: string;\n onAction?: (id: ToastId) => void;\n} & (\n | {\n variant: Exclude<ToastVariants, 'progress-bar' | 'loading-spinner'>;\n }\n | {\n id: ToastId;\n variant: Extract<ToastVariants, 'progress-bar'>;\n progressBarValue: number;\n }\n);\ntype ToastControlledProps = {\n toasts: ControlledToast[];\n} & Pick<React.ComponentProps<typeof Toaster>, 'visibleToasts'>;\n\nconst toastWithVariant = (input: ControlledToast) => {\n const commonRootProps = {\n actionLabel: input.actionLabel,\n isCloseable: input.onClose !== undefined,\n isControlled: true,\n onAction(id: ToastId) {\n input.onAction?.(id);\n },\n onClose(id: ToastId) {\n input.onClose?.(id);\n },\n shouldAutoClose: false,\n shouldCloseOnAction: false,\n };\n\n const commonSonnerProps: ExternalToast = {\n dismissible: false,\n id: input.id,\n };\n\n switch (input.variant) {\n case 'neutral':\n return toast.neutral(input.text, {\n ...commonRootProps,\n sonnerToastProps: commonSonnerProps,\n });\n case 'success':\n return toast.success(input.text, {\n ...commonRootProps,\n sonnerToastProps: commonSonnerProps,\n });\n case 'danger':\n return toast.danger(input.text, {\n ...commonRootProps,\n sonnerToastProps: commonSonnerProps,\n });\n case 'progress-bar':\n return toast.progressBar(input.text, {\n ...commonRootProps,\n initialProgressBarValue: input.progressBarValue,\n sonnerToastProps: commonSonnerProps,\n });\n }\n};\n\nexport const ToasterControlled = ({\n toasts,\n ...restProps\n}: ToastControlledProps) => {\n const [toastsState, setToastsState] = useState<ControlledToast[]>([]);\n\n useEffect(() => {\n // if a toast is removed, close it\n const removedToasts = toastsState.filter(\n (toast) => !toasts.some((item) => item.id === toast.id),\n );\n removedToasts.forEach((removedToast) => {\n toast.close(removedToast.id);\n });\n\n // Otherwise, update the toast or create a new one\n for (const toast of toasts) {\n toastWithVariant(toast);\n }\n\n setToastsState(toasts);\n }, [toasts, toastsState]);\n\n return <Toaster visibleToasts={1} {...restProps} />;\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/helpers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/helpers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Copyright (c) "Neo4j"
|
|
4
|
+
* Neo4j Sweden AB [http://neo4j.com]
|
|
5
|
+
*
|
|
6
|
+
* This file is part of Neo4j.
|
|
7
|
+
*
|
|
8
|
+
* Neo4j is free software: you can redistribute it and/or modify
|
|
9
|
+
* it under the terms of the GNU General Public License as published by
|
|
10
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
* (at your option) any later version.
|
|
12
|
+
*
|
|
13
|
+
* This program is distributed in the hope that it will be useful,
|
|
14
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
* GNU General Public License for more details.
|
|
17
|
+
*
|
|
18
|
+
* You should have received a copy of the GNU General Public License
|
|
19
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
*/
|
|
21
|
+
export type OperatingSystem = 'mac' | 'windows' | 'linux';
|
|
22
|
+
/** Detects the operating system the keyboard is attached to. */
|
|
23
|
+
export declare function detectOS(): OperatingSystem;
|
|
24
|
+
/**
|
|
25
|
+
* Apple platforms take `Cmd` where the rest take `Ctrl`, since `Ctrl` + click
|
|
26
|
+
* is the macOS context menu gesture.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isApplePlatform(): boolean;
|
|
29
|
+
//# sourceMappingURL=platform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../../src/helpers/platform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,SAAS,GAAG,OAAO,CAAC;AAsB1D,gEAAgE;AAChE,wBAAgB,QAAQ,IAAI,eAAe,CAS1C;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC"}
|
|
@@ -19,12 +19,9 @@
|
|
|
19
19
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
20
|
*/
|
|
21
21
|
import type { ReactNode } from 'react';
|
|
22
|
-
|
|
22
|
+
import { detectOS, type OperatingSystem } from '../helpers/platform';
|
|
23
|
+
export { detectOS, type OperatingSystem };
|
|
23
24
|
export type KbdKey = 'meta' | 'shift' | 'ctrl' | 'enter' | 'delete' | 'escape' | 'tab' | 'capslock' | 'up' | 'right' | 'down' | 'left' | 'pageup' | 'pagedown' | 'home' | 'end' | 'space' | 'fn' | 'alt';
|
|
24
|
-
/**
|
|
25
|
-
* Detects the operating system based on the user agent
|
|
26
|
-
*/
|
|
27
|
-
export declare function detectOS(): OperatingSystem;
|
|
28
25
|
/**
|
|
29
26
|
* Returns OS-aware keyboard key symbols
|
|
30
27
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kbd-utils.d.ts","sourceRoot":"","sources":["../../../src/kbd/kbd-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,
|
|
1
|
+
{"version":3,"file":"kbd-utils.d.ts","sourceRoot":"","sources":["../../../src/kbd/kbd-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAErE,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,CAAC;AAE1C,MAAM,MAAM,MAAM,GACd,MAAM,GACN,OAAO,GACP,MAAM,GACN,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,KAAK,GACL,UAAU,GACV,IAAI,GACJ,OAAO,GACP,MAAM,GACN,MAAM,GACN,QAAQ,GACR,UAAU,GACV,MAAM,GACN,KAAK,GACL,OAAO,GACP,IAAI,GACJ,KAAK,CAAC;AAEV;;GAEG;AACH,wBAAgB,aAAa,CAC3B,EAAE,GAAE,eAA4B,GAC/B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwBxB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,GAAE,eAA4B,GAC/B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBxB;AAkBD,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GAAG,SAAS,EACjD,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAC3C,EAAE,GAAE,eAA4B,GAC/B,MAAM,CAcR"}
|