├── .docs ├── demo.gif └── modified_theme.png ├── .eslintrc.json ├── .gitignore ├── .npmignore ├── .prettierrc ├── .storybook ├── main.js └── preview.js ├── LICENSE ├── README.md ├── babel.config.js ├── buildWindows.bat ├── docs ├── 177.4167c097561c92e01549.manager.bundle.js ├── 177.4167c097561c92e01549.manager.bundle.js.LICENSE.txt ├── 229.17d4ab2f2fe53489353e.manager.bundle.js ├── 229.4efcb577.iframe.bundle.js ├── 273.6ed48bcd.iframe.bundle.js ├── 273.6ed48bcd.iframe.bundle.js.LICENSE.txt ├── 295.086f3c94c9e023c3caff.manager.bundle.js ├── 51.4834abe5.iframe.bundle.js ├── 51.4834abe5.iframe.bundle.js.LICENSE.txt ├── 51.7070d385b30a646ee70e.manager.bundle.js ├── 51.7070d385b30a646ee70e.manager.bundle.js.LICENSE.txt ├── 551.40dddcc29c80ee6a1cee.manager.bundle.js ├── 551.a57b0b1f.iframe.bundle.js ├── 701.0be8a683.iframe.bundle.js ├── 705.2b2233a9.iframe.bundle.js ├── 705.2b2233a9.iframe.bundle.js.LICENSE.txt ├── 745.81c2b425.iframe.bundle.js ├── 807.5f1ebcc4.iframe.bundle.js ├── 807.5f1ebcc4.iframe.bundle.js.LICENSE.txt ├── 807.b6c07b84a21e65368b97.manager.bundle.js ├── 807.b6c07b84a21e65368b97.manager.bundle.js.LICENSE.txt ├── 897.42824d67.iframe.bundle.js ├── 897.42824d67.iframe.bundle.js.LICENSE.txt ├── 897.9ce4e971c3718f12eeb4.manager.bundle.js ├── 897.9ce4e971c3718f12eeb4.manager.bundle.js.LICENSE.txt ├── 935.39164b0f.iframe.bundle.js ├── 935.eff965ec22feacd9e876.manager.bundle.js ├── favicon.ico ├── iframe.html ├── index.html ├── main.e0c86993c546a5eb3b5b.manager.bundle.js ├── main.f11ad2ee.iframe.bundle.js ├── project.json ├── runtime~main.36299d73.iframe.bundle.js └── runtime~main.5c006a4c9c32bc86d0dc.manager.bundle.js ├── package.json ├── rollup.config.js ├── src ├── Tree.ts ├── Tree │ ├── Context.tsx │ ├── Elements.tsx │ ├── Nodes.tsx │ └── TreeRoot.tsx ├── __tests__ │ ├── Tree.spec.tsx │ ├── __snapshots__ │ │ └── Tree.spec.tsx.snap │ └── mocks │ │ ├── full_list_data.tsx │ │ └── full_list_long_names_data.tsx ├── assets │ └── images │ │ ├── Icons.ts │ │ ├── chevron-right.svg │ │ ├── circle-notch.svg │ │ └── paperclip.svg ├── hooks │ └── useReactTreeApi.tsx ├── index.tsx ├── stories │ ├── Tree.stories.tsx │ └── fixtures │ │ ├── Nodes.ts │ │ └── Theme.ts ├── styles │ └── theme.ts └── types │ ├── ReactSvg.d.ts │ └── global.d.ts ├── tsconfig.build.json ├── tsconfig.json └── yarn.lock /.docs/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naisutech/react-tree/7a4f725f66a29df1ea6d2aea0c19878904e9823b/.docs/demo.gif -------------------------------------------------------------------------------- /.docs/modified_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naisutech/react-tree/7a4f725f66a29df1ea6d2aea0c19878904e9823b/.docs/modified_theme.png -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "plugins": ["@typescript-eslint", "prettier"], 4 | "extends": [ 5 | "eslint:recommended", 6 | "plugin:@typescript-eslint/recommended", 7 | "plugin:react/recommended", 8 | "prettier" 9 | ], 10 | "settings": { 11 | "react": { 12 | "version": "detect" 13 | } 14 | }, 15 | "parser": "@typescript-eslint/parser", 16 | "rules": { 17 | "@typescript-eslint/no-empty-function": "off", 18 | "react/jsx-uses-react": "error", 19 | "react/jsx-uses-vars": "error" 20 | }, 21 | "parserOptions": { 22 | "ecmaFeatures": { 23 | "jsx": true 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | dist 3 | js 4 | node_modules 5 | /types 6 | .size-snapshot.json 7 | *.tgz 8 | **/*.tgz 9 | /lib -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .docs 2 | .storybook 3 | docs 4 | js 5 | node_modules 6 | src 7 | .eslintrc.json 8 | .gitignore 9 | .npmignore 10 | .prettierrc 11 | .size-snapshot.json 12 | babel.config.js 13 | rollup.config.js 14 | tsconfig.build.json 15 | tsconfig.json 16 | yarn.lock 17 | buildWindows.bat -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "trailingComma": "none", 4 | "singleQuote": true, 5 | "printWidth": 80, 6 | "arrowParens": "avoid", 7 | "bracketSameLine": false, 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /.storybook/main.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const pathToInlineSvg = path.resolve(__dirname, '../src/assets/images') 3 | 4 | module.exports = { 5 | stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], 6 | addons: [ 7 | '@storybook/addon-links', 8 | '@storybook/addon-essentials', 9 | '@storybook/addon-interactions' 10 | ], 11 | framework: '@storybook/react', 12 | core: { 13 | builder: 'webpack5' 14 | }, 15 | webpackFinal: async (config, { configType }) => { 16 | // SVG config for storybook 17 | const fileLoaderRule = config.module.rules.find(rule => 18 | rule.test.test('.svg') 19 | ) 20 | fileLoaderRule.exclude = pathToInlineSvg 21 | 22 | config.module.rules.push({ 23 | test: /\.svg$/, 24 | include: pathToInlineSvg, 25 | use: [ 26 | { 27 | loader: '@svgr/webpack', 28 | options: { 29 | icon: true 30 | } 31 | } 32 | ] 33 | }) 34 | 35 | // frame motion ES module workaround for storybook 36 | config.module.rules.push({ 37 | test: /\.mjs$/, 38 | include: /node_modules/, 39 | type: 'javascript/auto' 40 | }) 41 | return config 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /.storybook/preview.js: -------------------------------------------------------------------------------- 1 | export const parameters = { 2 | actions: { argTypesRegex: "^on[A-Z].*" }, 3 | controls: { 4 | matchers: { 5 | color: /(background|color)$/i, 6 | date: /Date$/, 7 | }, 8 | }, 9 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Naisu Technology Co. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-tree 2 | 3 | a hierarchical tree component for React in Typescript 4 | 5 | [Demo+Docs here](https://naisutech.github.io/react-tree/) 6 | 7 | ![demo](./.docs/demo.gif) 8 | 9 | ## Features 10 | 11 | - Written in Typescript will full typings exported from package 12 | - Theming support for almost all parts of the components appearance, (**NEW** including partial theming) (see **Theming** below) 13 | - Use as an uncontrolled component with `defaultSelectedNodes` and `defaultOpenNodes` or a completely controlled component with `selectedNodes` and `openNodes` props with `onEvent` listeners 14 | - Fully stylable container for fixed width, or flex-box based layouts, or scrollable container when lists are too long for the parent container 15 | - Optimized UX to clearly indicate open/closed folders, selected items and feedback on user input 16 | - Toggle support for long-object labels with `truncateLongText` prop 17 | - Title attributes on hover for truncated labels that are too long for container 18 | - Toggle support for empty folders with `displayEmpty` prop 19 | - Customizable component message strings with `messages` prop (no data, empty folders, loading) 20 | - Display a loading indicator and nothing when in loading state with `loading` prop 21 | - Opt-in animated micro-interactions for opening/closing folders 22 | - Multi-select API! hold your OS's `meta` key or `ctrl` key to be able to select/deselect multiple-nodes 23 | - **NEW in v3** imperative API via export `useReactTreeApi` hook. Pass the ref to the componenta (see **Imperative API** below 24 | - **NEW in v3** new context-based state management for better maintainability and handling of business logic 25 | - **NEW in v3** moved `react-dom` and `styled-components` to `peerDependencies` 26 | - **NEW in v3** Custom render functions for nodes and icons (full node context passed to render function with open/selected status) 27 | 28 | 29 | ## Add to a project 30 | 31 | `yarn add @naisutech/react-tree` or `npm install @naisutech/react-tree` 32 | 33 | ## Usage 34 | 35 | There is only one required prop: `nodes` (see **Data format**) 36 | 37 | ```jsx 38 | import { ReactTree } from '@naisutech/react-tree' 39 | 40 | // component code 41 | 42 | const data = ... // fetch data 43 | 44 | 45 | ``` 46 | 47 | ## Data format 48 | 49 | - data should be a flat list of node `objects` with required properties: 50 | - `label`, 51 | - `id`, 52 | - `parentId` 53 | - optional properties: 54 | - `items` 55 | - `id` is typed to be `number` or `string` 56 | - root nodes should have `parentId` property set to `null` 57 | - files/leaf items should be a flat list of node objects on `items` property inside a node. 58 | - files do not require an `items` property (this should be obvious) 59 | - example: 60 | 61 | ```json 62 | [ 63 | { 64 | "id": 12345678, 65 | "parentId": null, 66 | "label": "My parent node", 67 | "items": [ 68 | { 69 | "id": 87654321, 70 | "label": "My file", 71 | "parentId": 12345678 72 | } 73 | ] 74 | }, 75 | { 76 | "id": 56789012, 77 | "parentId": 12345678, 78 | "label": "My child node" 79 | } 80 | ] 81 | ``` 82 | 83 | ## Component API 84 | 85 | There are a number of optional properties which 86 | can be used to customise the UX of your _React Tree_ component. You can explore the full interactive docs [here](https://naisutech.github.io/react-tree/) or you can refer to the sample code below: 87 | 88 | ```tsx 89 | void 108 | onToggleOpenNodes?: (nodes: TreeNodeId[]) => void 109 | ref: React.MutableRef 110 | /> 111 | ``` 112 | 113 | ### Props list 114 | 115 | | **Prop name** | **Prop type** | **Default** | **Required** | **Description** | 116 | |-----------------------------|-----------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------| 117 | | `nodes` | `TreeNodeList` | `[]` | Y | The data set for react tree to render | 118 | | `defaultOpenNodes` | `TreeNodeId[]` | `undefined` | N | The default set of open nodes. Specify when you intend to use the component in uncontrolled mode | 119 | | `defaultSelectedNodes` | `TreeNodeId[]` | `undefined` | N | The default set of selected nodes. Specify when you intend to use the component in uncontrolled mode | 120 | | `openNodes` | `TreeNodeId[]` | `undefined` | N | The currently open nodes. Specify when you intend to use the component in controlled mode. | 121 | | `selectedNodes` | `TreeNodeId[]` | `undefined` | N | The currently selected nodes. Specify when you intend to use the component in controlled mode. | 122 | | `theme` | `string` | `light` | N | The curently selected theme (built-in themes are `light`, and `dark`) | 123 | | `themes` | `ThemeSettings` (`Record`) | `{}` | N | The user-specified set of themes | 124 | | `loading` | `boolean` | `false` | N | Display a loader instead of the rendered tree | 125 | | `messages` | `{ noData?: React.ReactNode; loading?: React.ReactNode; emptyItems?: React.ReactNode }` | `{loading: 'Loading...', noData: 'No data to render 😔', emptyItems: '[Empty]' }` | N | The default component message strings. | 126 | | `enableItemAnimations` | `boolean` | `false` | N | Whether or not to animate folders on enter/exit | 127 | | `enableIndicatorAnimations` | `boolean` | `false` | N | Whether or not to animate folder open/close icons | 128 | | `showEmptyItems` | `boolean` | `false` | N | Whether or not to display an indicator for empty folders | 129 | | `noIcons` | `boolean` | `false` | N | Disable the icon display | 130 | | `truncateLongText` | `boolean` | `false` | N | Prepares all DOM nodes to be able to truncate long text nodes. Note this setting will have _no effect_ if container is not styled to have a fixed width. | 131 | | `multiSelect` | `boolean` | `false` | N | Component is single select by default. | 132 | | `containerStyles` | `CSSProperties` | `{}` | N | Style the _React Tree_ container | 133 | | `RenderNode` | `TreeRenderFn` | `undefined` | N | A custom renderer for `Node` elements. See **Custom rendering** | 134 | | `RenderIcon` | `TreeRenderFn` | `undefined` | N | A custom renderer for `Icon` elements. See **Custom rendering** | 135 | | `onToggleSelectedNodes` | `(nodes: TreeNodeId[]) => void` | () => void | N | A callback called whenever items are selected/deselected | 136 | | `onToggleOpenNodes` | `(nodes: TreeNodeId[]) => void` | () => void | N | A callback called whenever items are opened/closed | 137 | 138 | ## Typescript 139 | 140 | _React Tree_ is written in typescript and is fully typescript compatible. All type definitions are exported directly from the library. See `src/types` in the repo for extensive definitions 141 | 142 | ## Imperative API 143 | 144 | _React Tree_ exposes a hook `useReactTreeApi` which you can use to imperatively control the tree component. The hook returns a `React.MutableRef` type object. All you have to do is pass the returned object to the `ref` props on the _React Tree_ component. The `.current` property on the ref object will be populated with the API functions you need to fully control the component. 145 | 146 | ### Usage 147 | 148 | ```tsx 149 | import ReactTree, { useReactTreeApi } from "@naisutech/react-tree" 150 | const App = () => { 151 | const treeApi = useReactTreeApi() 152 | 153 | return
154 | 155 | 159 |
160 | } 161 | ``` 162 | 163 | ### Docs 164 | 165 | Full details of the _React Tree_ API: 166 | 167 | ```ts 168 | interface ReactTreeApi { 169 | getOpenNodes: () => (number | string)[] // get a list of all open nodes 170 | getSelectedNodes: () => (number | string)[] // get a list of all selected nodes 171 | toggleNodeSelectedState: (node: string | number) => void // toggle a node selected/unselected. This is an inclusive operation (all other selected nodes are retained) 172 | toggleNodeOpenState: (node: string | number) => void // toggle a node open. This is an inclusive operation (all other open nodes are retained) 173 | toggleAllNodesOpenState: (state: 'open' | 'closed') => void // open or close all nodes 174 | toggleAllNodesSelectedState: (state: 'selected' | 'unselected') => void // select or deselect all nodes 175 | toggleOpenNodes: (nodes: (number | string)[]) => void // toggle a set of nodes open. This is an additive operation (it's a union of already open and newly open nodes) 176 | toggleClosedNodes: (nodes: (number | string)[]) => void // toggle a set of nodes closed. This is an subtractive operation (it's a difference of already open and newly closed nodes) 177 | toggleOpenClosedNodes: (nodes: (number | string)[]) => void // toggle a set of nodes open. This is an exclusive operation (all other open nodes are closed) 178 | selectNodes: (nodes: (number | string)[]) => void // toggle a set of nodes selected. This is an additive operation (it's a union of already selected and newly selected nodes) 179 | deselectNodes: (nodes: (number | string)[]) => void // toggle a set of nodes deselected. This is an subtractive operation (it's a difference of already selected and newly deselected nodes) 180 | toggleSelectedNodes: (nodes: (number | string)[]) => void // toggle a set of nodes selected. This is an exclusive operation (all other selected nodes are deselected) 181 | } 182 | ``` 183 | 184 | ## Theming 185 | 186 | _ReactTree_ supports custom theming. All values are CSS compatible properties. Provide the custom theme object to the `themes` prop (with a key matching your theme name) and provide your theme name to the `theme` prop. 187 | 188 | ### Theme API: 189 | 190 | Note all props are optional. Any props not provided will use `initial` settings (e.g. `background-color: initial;`) 191 | 192 | ```ts 193 | interface ReactTreeTheme { 194 | text?: { 195 | fontSize?: SizeUnit | CSSUnit 196 | fontFamily?: string 197 | color?: string 198 | selectedColor?: string | null 199 | hoverColor?: string | null 200 | } 201 | nodes?: { 202 | height?: CSSUnit 203 | folder?: { 204 | bgColor?: string 205 | selectedBgColor?: string 206 | hoverBgColor?: string | null 207 | } 208 | leaf?: { 209 | bgColor?: string 210 | selectedBgColor?: string 211 | hoverBgColor?: string | null 212 | } 213 | separator?: { 214 | border?: string 215 | borderColor?: string 216 | } 217 | icons?: { 218 | size?: CSSUnit 219 | folderColor?: string 220 | leafColor?: string 221 | } 222 | } 223 | } 224 | ``` 225 | 226 | ### Usage: 227 | 228 | ```ts 229 | const myThemes: ThemeSettings = { 230 | { 231 | "exampleCustomTheme": { 232 | "text": { 233 | "fontSize": "xl", 234 | "fontFamily": "cursive", 235 | "color": "#fafafa", 236 | "selectedColor": "#fafafa", 237 | "hoverColor": "#fafafa" 238 | }, 239 | "nodes": { 240 | "height": "3.5rem", 241 | "folder": { 242 | "bgColor": "gold", 243 | "selectedBgColor": "goldenrod", 244 | "hoverBgColor": "yellow" 245 | }, 246 | "leaf": { 247 | "bgColor": "magenta", 248 | "selectedBgColor": "blueviolet", 249 | "hoverBgColor": "violet" 250 | }, 251 | "separator": { 252 | "border": "3px solid", 253 | "borderColor": "transparent" 254 | }, 255 | "icons": { 256 | "size": "1rem", 257 | "folderColor": "crimson", 258 | "leafColor": "white" 259 | } 260 | } 261 | } 262 | } 263 | } 264 | ``` 265 | 266 | ```jsx 267 | 268 | ``` 269 | 270 | > Result 271 | 272 | ![result](./.docs/modified_theme.png) 273 | 274 | ## Custom render functions 275 | 276 | _React Tree_ includes two props `RenderNode` and `RenderIcon` which can be used to fully customize the appearance and behaviour of the component 277 | 278 | ### API 279 | 280 | Icons and nodes both use the same API, `TreeRenderFn`: 281 | 282 | ```tsx 283 | type TreeRenderFn = ({ 284 | node, 285 | type, 286 | selected = false, 287 | open = false, 288 | context 289 | }: { 290 | node: TreeNode 291 | type: 'leaf' | 'node' | 'loader' 292 | selected: boolean 293 | open?: boolean 294 | Icon?: React.ReactNode 295 | context: TReactTreeContext 296 | }) => React.ReactNode 297 | ``` 298 | 299 | - `node: TreeNode` - the node data 300 | - `type: 'leaf' | 'node' | 'loader'` - the type of this node 301 | - `selected: boolean` - indicates whether node is selected or not 302 | - `open: boolean` - use only for node, indicates whether node is open or not 303 | - `icon: React.ReactNode` - the SVG component of the original _React Tree_ icon if you want to use it 304 | - `context: TReactTreeContext` - the entire _React Tree_ context including the state, and API methods 305 | 306 | 307 | ### Nodes 308 | 309 | _ReactTree_ will call (if provided) the `RenderNode` icon with the API for TreeRenderFn. This should be enough information to render any customization you need. 310 | 311 | **N.B.** if you use the prop `truncateLongText` you'll notice that unless you properly style your custom node elements, it will take no effect. As explained elsewhere, you'll need to make sure that a) the container is styled to have a fixed width and b) that the custom node is styled `overflow-x: hidden;` and `text-overflow: ellipsis` to be rendered correctly. 312 | 313 | ### Icons 314 | 315 | _ReactTree_ comes with a pretty solid set of default icons for showing node elements and leaf elements. However, if you want to hide the icons, pass the `noIcons` prop. 316 | 317 | If you want to customize the icons, you can! Some conditions: 318 | 319 | - the icon is rendered inside a container which whose size is determined by theme property `icons.size`. It will render any child SVG or `img` element as `100%` height and width within that container 320 | 321 | ## TODO in v4 and beyond 322 | 323 | - add drag and drop support 324 | 325 | ## Contributing 326 | 327 | - open issues and PRs and we'll work together! 328 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [['@babel/preset-env', { targets: { node: 'current' } }], '@babel/preset-typescript', '@babel/preset-react'] 3 | } 4 | -------------------------------------------------------------------------------- /buildWindows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM This has to be in a separate batch file rather than a sequence of ... && ... commands, because the 3 | REM "set" command only takes effect AFTER the line containing it has completed. Chaining it with && 4 | REM means it will NOT take effect for the commands following it in the same line. 5 | set NODE_ENV=production 6 | IF EXIST .\\js ( rmdir /S /Q .\\js ) 7 | REM "tsc" and "yarn" are batch files, so unless we use "call" to execute them, execution won't come back here. 8 | call tsc -p tsconfig.build.json 9 | call yarn copy-files-windows 10 | REM I don't know if "rollup" is a batch file, but it doesn't matter either way. 11 | rollup -c -------------------------------------------------------------------------------- /docs/177.4167c097561c92e01549.manager.bundle.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /*! 8 | * Fuse.js v3.6.1 - Lightweight fuzzy-search (http://fusejs.io) 9 | * 10 | * Copyright (c) 2012-2017 Kirollos Risk (http://kiro.me) 11 | * All Rights Reserved. Apache Software License 2.0 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | */ 15 | 16 | /*! 17 | * https://github.com/es-shims/es5-shim 18 | * @license es5-shim Copyright 2009-2020 by contributors, MIT License 19 | * see https://github.com/es-shims/es5-shim/blob/master/LICENSE 20 | */ 21 | 22 | /*! 23 | * isobject 24 | * 25 | * Copyright (c) 2014-2017, Jon Schlinkert. 26 | * Released under the MIT License. 27 | */ 28 | 29 | /*! ***************************************************************************** 30 | Copyright (c) Microsoft Corporation. 31 | 32 | Permission to use, copy, modify, and/or distribute this software for any 33 | purpose with or without fee is hereby granted. 34 | 35 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 36 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 37 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 38 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 39 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 40 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 41 | PERFORMANCE OF THIS SOFTWARE. 42 | ***************************************************************************** */ 43 | 44 | /*! store2 - v2.13.1 - 2021-12-20 45 | * Copyright (c) 2021 Nathan Bubna; Licensed (MIT OR GPL-3.0) */ 46 | 47 | /** 48 | * @license React 49 | * react-dom.production.min.js 50 | * 51 | * Copyright (c) Facebook, Inc. and its affiliates. 52 | * 53 | * This source code is licensed under the MIT license found in the 54 | * LICENSE file in the root directory of this source tree. 55 | */ 56 | 57 | /** 58 | * @license React 59 | * react.production.min.js 60 | * 61 | * Copyright (c) Facebook, Inc. and its affiliates. 62 | * 63 | * This source code is licensed under the MIT license found in the 64 | * LICENSE file in the root directory of this source tree. 65 | */ 66 | 67 | /** 68 | * @license React 69 | * scheduler.production.min.js 70 | * 71 | * Copyright (c) Facebook, Inc. and its affiliates. 72 | * 73 | * This source code is licensed under the MIT license found in the 74 | * LICENSE file in the root directory of this source tree. 75 | */ 76 | 77 | /** 78 | * React Router DOM v6.0.2 79 | * 80 | * Copyright (c) Remix Software Inc. 81 | * 82 | * This source code is licensed under the MIT license found in the 83 | * LICENSE.md file in the root directory of this source tree. 84 | * 85 | * @license MIT 86 | */ 87 | 88 | /** 89 | * React Router v6.0.2 90 | * 91 | * Copyright (c) Remix Software Inc. 92 | * 93 | * This source code is licensed under the MIT license found in the 94 | * LICENSE.md file in the root directory of this source tree. 95 | * 96 | * @license MIT 97 | */ 98 | -------------------------------------------------------------------------------- /docs/273.6ed48bcd.iframe.bundle.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! ***************************************************************************** 2 | Copyright (c) Microsoft Corporation. 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any 5 | purpose with or without fee is hereby granted. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 8 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 9 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 10 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 11 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 12 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 13 | PERFORMANCE OF THIS SOFTWARE. 14 | ***************************************************************************** */ 15 | -------------------------------------------------------------------------------- /docs/295.086f3c94c9e023c3caff.manager.bundle.js: -------------------------------------------------------------------------------- 1 | (self.webpackChunk_naisutech_react_tree=self.webpackChunk_naisutech_react_tree||[]).push([[295],{19295:module=>{module.exports=function(e,n){return n=n||{},new Promise((function(t,r){var s=new XMLHttpRequest,o=[],u=[],i={},a=function(){return{ok:2==(s.status/100|0),statusText:s.statusText,status:s.status,url:s.responseURL,text:function(){return Promise.resolve(s.responseText)},json:function(){return Promise.resolve(s.responseText).then(JSON.parse)},blob:function(){return Promise.resolve(new Blob([s.response]))},clone:a,headers:{keys:function(){return o},entries:function(){return u},get:function(e){return i[e.toLowerCase()]},has:function(e){return e.toLowerCase()in i}}}};for(var l in s.open(n.method||"get",e,!0),s.onload=function(){s.getAllResponseHeaders().replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm,(function(e,n,t){o.push(n=n.toLowerCase()),u.push([n,t]),i[n]=i[n]?i[n]+","+t:t})),t(a())},s.onerror=r,s.withCredentials="include"==n.credentials,n.headers)s.setRequestHeader(l,n.headers[l]);s.send(n.body||null)}))}}}]); -------------------------------------------------------------------------------- /docs/51.4834abe5.iframe.bundle.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * Prism: Lightweight, robust, elegant syntax highlighting 3 | * 4 | * @license MIT 5 | * @author Lea Verou 6 | * @namespace 7 | * @public 8 | */ 9 | -------------------------------------------------------------------------------- /docs/51.7070d385b30a646ee70e.manager.bundle.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * Prism: Lightweight, robust, elegant syntax highlighting 3 | * 4 | * @license MIT 5 | * @author Lea Verou 6 | * @namespace 7 | * @public 8 | */ 9 | -------------------------------------------------------------------------------- /docs/551.40dddcc29c80ee6a1cee.manager.bundle.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunk_naisutech_react_tree=self.webpackChunk_naisutech_react_tree||[]).push([[551],{82551:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{default:()=>GlobalScrollAreaStyles,getScrollAreaStyles:()=>getScrollAreaStyles});__webpack_require__(47042),__webpack_require__(43371);var _templateObject,react__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(67294),_storybook_theming__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(65316);var hsResizeObserverDummyAnimation=(0,_storybook_theming__WEBPACK_IMPORTED_MODULE_3__.F4)(_templateObject||(_templateObject=function _taggedTemplateLiteral(strings,raw){return raw||(raw=strings.slice(0)),Object.freeze(Object.defineProperties(strings,{raw:{value:Object.freeze(raw)}}))}(["0%{z-index:0}to{z-index:-1}"]))),getScrollAreaStyles=function getScrollAreaStyles(theme){return{"html.os-html, html.os-html>.os-host":{display:"block",overflow:"hidden",boxSizing:"border-box",height:"100%!important",width:"100%!important",minWidth:"100%!important",minHeight:"100%!important",margin:"0!important",position:"absolute!important"},"html.os-html>.os-host>.os-padding":{position:"absolute"},"body.os-dragging, body.os-dragging *":{cursor:"default"},".os-host, .os-host-textarea":{position:"relative",overflow:"visible!important",flexDirection:"column",flexWrap:"nowrap",justifyContent:"flex-start",alignContent:"flex-start",alignItems:"flex-start"},".os-host-flexbox":{overflow:"hidden!important",display:"flex"},".os-host-flexbox>.os-size-auto-observer":{height:"inherit!important"},".os-host-flexbox>.os-content-glue":{flexGrow:1,flexShrink:0},".os-host-flexbox>.os-size-auto-observer, .os-host-flexbox>.os-content-glue":{minHeight:0,minWidth:0,flexGrow:0,flexShrink:1,flexBasis:"auto"},"#os-dummy-scrollbar-size":{position:"fixed",opacity:0,visibility:"hidden",overflow:"scroll",height:500,width:500},"#os-dummy-scrollbar-size>div":{width:"200%",height:"200%",margin:10},"#os-dummy-scrollbar-size, .os-viewport":{},".os-viewport-native-scrollbars-invisible#os-dummy-scrollbar-size, .os-viewport-native-scrollbars-invisible.os-viewport":{scrollbarWidth:"none!important"},".os-viewport-native-scrollbars-invisible#os-dummy-scrollbar-size::-webkit-scrollbar, .os-viewport-native-scrollbars-invisible.os-viewport::-webkit-scrollbar, .os-viewport-native-scrollbars-invisible#os-dummy-scrollbar-size::-webkit-scrollbar-corner, .os-viewport-native-scrollbars-invisible.os-viewport::-webkit-scrollbar-corner":{display:"none!important",width:"0!important",height:"0!important",visibility:"hidden!important",background:"0 0!important"},".os-content-glue":{boxSizing:"inherit",maxHeight:"100%",maxWidth:"100%",width:"100%",pointerEvents:"none"},".os-padding":{boxSizing:"inherit",direction:"inherit",position:"absolute",overflow:"visible",padding:0,margin:0,left:0,top:0,bottom:0,right:0,width:"auto!important",height:"auto!important",zIndex:1},".os-host-overflow>.os-padding":{overflow:"hidden"},".os-viewport":{direction:"inherit!important",boxSizing:"inherit!important",resize:"none!important",outline:"0!important",position:"absolute",overflow:"hidden",top:0,left:0,bottom:0,right:0,padding:0,margin:0},".os-content-arrange":{position:"absolute",zIndex:-1,minHeight:1,minWidth:1,pointerEvents:"none"},".os-content":{direction:"inherit",boxSizing:"border-box!important",position:"relative",display:"block",height:"100%",width:"100%",visibility:"visible"},".os-content:before, .os-content:after":{content:"''",display:"table",width:0,height:0,lineHeight:0,fontSize:0},".os-content>.os-textarea":{boxSizing:"border-box!important",direction:"inherit!important",background:"0 0!important",outline:"0 transparent!important",overflow:"hidden!important",position:"absolute!important",display:"block!important",top:"0!important",left:"0!important",margin:"0!important",borderRadius:"0!important",float:"none!important",filter:"none!important",border:"0!important",resize:"none!important",transform:"none!important",maxWidth:"none!important",maxHeight:"none!important",boxShadow:"none!important",perspective:"none!important",opacity:"1!important",zIndex:"1!important",clip:"auto!important",verticalAlign:"baseline!important",padding:0},".os-host-rtl>.os-padding>.os-viewport>.os-content>.os-textarea":{right:"0!important"},".os-content>.os-textarea-cover":{zIndex:-1,pointerEvents:"none"},".os-content>.os-textarea[wrap=off]":{whiteSpace:"pre!important",margin:"0!important"},".os-text-inherit":{fontFamily:"inherit",fontSize:"inherit",fontWeight:"inherit",fontStyle:"inherit",fontVariant:"inherit",textTransform:"inherit",textDecoration:"inherit",textIndent:"inherit",textAlign:"inherit",textShadow:"inherit",textOverflow:"inherit",letterSpacing:"inherit",wordSpacing:"inherit",lineHeight:"inherit",unicodeBidi:"inherit",direction:"inherit",color:"inherit",cursor:"text"},".os-resize-observer, .os-resize-observer-host":{boxSizing:"inherit",display:"block",opacity:0,position:"absolute",top:0,left:0,height:"100%",width:"100%",overflow:"hidden",pointerEvents:"none",zIndex:-1},".os-resize-observer-host":{padding:"inherit",border:"inherit",borderColor:"transparent",borderStyle:"solid",boxSizing:"border-box"},".os-resize-observer-host:after":{content:"''"},".os-resize-observer-host>.os-resize-observer, .os-resize-observer-host:after":{height:"200%",width:"200%",padding:"inherit",border:"inherit",margin:0,display:"block",boxSizing:"content-box"},".os-resize-observer.observed, object.os-resize-observer":{boxSizing:"border-box!important"},".os-size-auto-observer":{boxSizing:"inherit!important",height:"100%",width:"inherit",maxWidth:1,position:"relative",float:"left",maxHeight:1,overflow:"hidden",zIndex:-1,padding:0,margin:0,pointerEvents:"none",flexGrow:"inherit",flexShrink:0,flexBasis:0},".os-size-auto-observer>.os-resize-observer":{width:"1000%",height:"1000%",minHeight:1,minWidth:1},".os-resize-observer-item":{position:"absolute",top:0,right:0,bottom:0,left:0,overflow:"hidden",zIndex:-1,opacity:0,direction:"ltr!important",flex:"none!important"},".os-resize-observer-item-final":{position:"absolute",left:0,top:0,transition:"none!important",flex:"none!important"},".os-resize-observer":{animationDuration:".001s",animationName:"".concat(hsResizeObserverDummyAnimation)},".os-host-transition>.os-scrollbar, .os-host-transition>.os-scrollbar-corner":{transition:"opacity .3s,visibility .3s,top .3s,right .3s,bottom .3s,left .3s"},"html.os-html>.os-host>.os-scrollbar":{position:"absolute",zIndex:999999},".os-scrollbar, .os-scrollbar-corner":{position:"absolute",opacity:1,zIndex:1},".os-scrollbar-corner":{bottom:0,right:0,height:10,width:10,backgroundColor:"transparent"},".os-scrollbar":{pointerEvents:"none",padding:2,boxSizing:"border-box",background:0},".os-scrollbar-track":{pointerEvents:"auto",position:"relative",height:"100%",width:"100%",padding:"0!important",border:"0!important"},".os-scrollbar-handle":{pointerEvents:"auto",position:"absolute",width:"100%",height:"100%"},".os-scrollbar-handle-off, .os-scrollbar-track-off":{pointerEvents:"none"},".os-scrollbar.os-scrollbar-unusable, .os-scrollbar.os-scrollbar-unusable *":{pointerEvents:"none!important"},".os-scrollbar.os-scrollbar-unusable .os-scrollbar-handle":{opacity:"0!important"},".os-scrollbar-horizontal":{bottom:0,left:0,right:10,height:10},".os-scrollbar-vertical":{top:0,right:0,bottom:10,width:10},".os-host-rtl>.os-scrollbar-horizontal":{right:0},".os-host-rtl>.os-scrollbar-vertical":{right:"auto",left:0},".os-host-rtl>.os-scrollbar-corner":{right:"auto",left:0},".os-scrollbar-auto-hidden, .os-padding+.os-scrollbar-corner, .os-host-resize-disabled.os-host-scrollbar-horizontal-hidden>.os-scrollbar-corner, .os-host-scrollbar-horizontal-hidden>.os-scrollbar-horizontal, .os-host-resize-disabled.os-host-scrollbar-vertical-hidden>.os-scrollbar-corner, .os-host-scrollbar-vertical-hidden>.os-scrollbar-vertical, .os-scrollbar-horizontal.os-scrollbar-auto-hidden+.os-scrollbar-vertical+.os-scrollbar-corner, .os-scrollbar-horizontal+.os-scrollbar-vertical.os-scrollbar-auto-hidden+.os-scrollbar-corner, .os-scrollbar-horizontal.os-scrollbar-auto-hidden+.os-scrollbar-vertical.os-scrollbar-auto-hidden+.os-scrollbar-corner":{opacity:0,visibility:"hidden",pointerEvents:"none"},".os-scrollbar-corner-resize-both":{cursor:"nwse-resize"},".os-host-rtl>.os-scrollbar-corner-resize-both":{cursor:"nesw-resize"},".os-scrollbar-corner-resize-horizontal":{cursor:"ew-resize"},".os-scrollbar-corner-resize-vertical":{cursor:"ns-resize"},".os-dragging .os-scrollbar-corner.os-scrollbar-corner-resize":{cursor:"default"},".os-host-resize-disabled.os-host-scrollbar-horizontal-hidden>.os-scrollbar-vertical":{top:0,bottom:0},".os-host-resize-disabled.os-host-scrollbar-vertical-hidden>.os-scrollbar-horizontal, .os-host-rtl.os-host-resize-disabled.os-host-scrollbar-vertical-hidden>.os-scrollbar-horizontal":{right:0,left:0},".os-scrollbar:hover, .os-scrollbar-corner.os-scrollbar-corner-resize":{opacity:"1!important",visibility:"visible!important"},".os-scrollbar-corner.os-scrollbar-corner-resize":{backgroundImage:"linear-gradient(135deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 50%, rgba(0,0,0,0.4) 50%, rgba(0,0,0,0.4) 100%)",backgroundRepeat:"no-repeat",backgroundPosition:"100% 100%",pointerEvents:"auto!important"},".os-host-rtl>.os-scrollbar-corner.os-scrollbar-corner-resize":{transform:"scale(-1,1)"},".os-host-overflow":{overflow:"hidden!important"},".os-theme-dark.os-host-rtl>.os-scrollbar-horizontal":{left:10,right:0},".os-scrollbar.os-scrollbar-unusable":{background:0},".os-scrollbar>.os-scrollbar-track":{background:0},".os-scrollbar-horizontal>.os-scrollbar-track>.os-scrollbar-handle":{minWidth:30},".os-scrollbar-vertical>.os-scrollbar-track>.os-scrollbar-handle":{minHeight:30},".os-theme-dark.os-host-transition>.os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle":{transition:"background-color .3s"},".os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle, .os-scrollbar>.os-scrollbar-track":{borderRadius:10},".os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle":{background:theme.color.mediumdark,opacity:.5},".os-scrollbar:hover>.os-scrollbar-track>.os-scrollbar-handle":{opacity:.6},".os-scrollbar-horizontal .os-scrollbar-handle:before, .os-scrollbar-vertical .os-scrollbar-handle:before":{content:"''",position:"absolute",left:0,right:0,top:0,bottom:0,display:"block"},".os-theme-dark.os-host-scrollbar-horizontal-hidden>.os-scrollbar-horizontal .os-scrollbar-handle:before, .os-theme-dark.os-host-scrollbar-vertical-hidden>.os-scrollbar-vertical .os-scrollbar-handle:before":{display:"none"},".os-scrollbar-horizontal .os-scrollbar-handle:before":{top:-6,bottom:-2},".os-scrollbar-vertical .os-scrollbar-handle:before":{left:-6,right:-2},".os-host-rtl.os-scrollbar-vertical .os-scrollbar-handle:before":{right:-6,left:-2}}},GlobalScrollAreaStyles=function GlobalScrollAreaStyles(){return react__WEBPACK_IMPORTED_MODULE_2__.createElement(_storybook_theming__WEBPACK_IMPORTED_MODULE_3__.xB,{styles:getScrollAreaStyles})}}}]); -------------------------------------------------------------------------------- /docs/551.a57b0b1f.iframe.bundle.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunk_naisutech_react_tree=self.webpackChunk_naisutech_react_tree||[]).push([[551],{"./node_modules/@storybook/components/dist/esm/GlobalScrollAreaStyles-8793ce4a.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{default:()=>GlobalScrollAreaStyles,getScrollAreaStyles:()=>getScrollAreaStyles});__webpack_require__("./node_modules/core-js/modules/es.array.slice.js"),__webpack_require__("./node_modules/core-js/modules/es.object.freeze.js");var _templateObject,react__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__("./node_modules/react/index.js"),_storybook_theming__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__("./node_modules/@storybook/theming/dist/esm/index.js");var hsResizeObserverDummyAnimation=(0,_storybook_theming__WEBPACK_IMPORTED_MODULE_3__.F4)(_templateObject||(_templateObject=function _taggedTemplateLiteral(strings,raw){return raw||(raw=strings.slice(0)),Object.freeze(Object.defineProperties(strings,{raw:{value:Object.freeze(raw)}}))}(["0%{z-index:0}to{z-index:-1}"]))),getScrollAreaStyles=function getScrollAreaStyles(theme){return{"html.os-html, html.os-html>.os-host":{display:"block",overflow:"hidden",boxSizing:"border-box",height:"100%!important",width:"100%!important",minWidth:"100%!important",minHeight:"100%!important",margin:"0!important",position:"absolute!important"},"html.os-html>.os-host>.os-padding":{position:"absolute"},"body.os-dragging, body.os-dragging *":{cursor:"default"},".os-host, .os-host-textarea":{position:"relative",overflow:"visible!important",flexDirection:"column",flexWrap:"nowrap",justifyContent:"flex-start",alignContent:"flex-start",alignItems:"flex-start"},".os-host-flexbox":{overflow:"hidden!important",display:"flex"},".os-host-flexbox>.os-size-auto-observer":{height:"inherit!important"},".os-host-flexbox>.os-content-glue":{flexGrow:1,flexShrink:0},".os-host-flexbox>.os-size-auto-observer, .os-host-flexbox>.os-content-glue":{minHeight:0,minWidth:0,flexGrow:0,flexShrink:1,flexBasis:"auto"},"#os-dummy-scrollbar-size":{position:"fixed",opacity:0,visibility:"hidden",overflow:"scroll",height:500,width:500},"#os-dummy-scrollbar-size>div":{width:"200%",height:"200%",margin:10},"#os-dummy-scrollbar-size, .os-viewport":{},".os-viewport-native-scrollbars-invisible#os-dummy-scrollbar-size, .os-viewport-native-scrollbars-invisible.os-viewport":{scrollbarWidth:"none!important"},".os-viewport-native-scrollbars-invisible#os-dummy-scrollbar-size::-webkit-scrollbar, .os-viewport-native-scrollbars-invisible.os-viewport::-webkit-scrollbar, .os-viewport-native-scrollbars-invisible#os-dummy-scrollbar-size::-webkit-scrollbar-corner, .os-viewport-native-scrollbars-invisible.os-viewport::-webkit-scrollbar-corner":{display:"none!important",width:"0!important",height:"0!important",visibility:"hidden!important",background:"0 0!important"},".os-content-glue":{boxSizing:"inherit",maxHeight:"100%",maxWidth:"100%",width:"100%",pointerEvents:"none"},".os-padding":{boxSizing:"inherit",direction:"inherit",position:"absolute",overflow:"visible",padding:0,margin:0,left:0,top:0,bottom:0,right:0,width:"auto!important",height:"auto!important",zIndex:1},".os-host-overflow>.os-padding":{overflow:"hidden"},".os-viewport":{direction:"inherit!important",boxSizing:"inherit!important",resize:"none!important",outline:"0!important",position:"absolute",overflow:"hidden",top:0,left:0,bottom:0,right:0,padding:0,margin:0},".os-content-arrange":{position:"absolute",zIndex:-1,minHeight:1,minWidth:1,pointerEvents:"none"},".os-content":{direction:"inherit",boxSizing:"border-box!important",position:"relative",display:"block",height:"100%",width:"100%",visibility:"visible"},".os-content:before, .os-content:after":{content:"''",display:"table",width:0,height:0,lineHeight:0,fontSize:0},".os-content>.os-textarea":{boxSizing:"border-box!important",direction:"inherit!important",background:"0 0!important",outline:"0 transparent!important",overflow:"hidden!important",position:"absolute!important",display:"block!important",top:"0!important",left:"0!important",margin:"0!important",borderRadius:"0!important",float:"none!important",filter:"none!important",border:"0!important",resize:"none!important",transform:"none!important",maxWidth:"none!important",maxHeight:"none!important",boxShadow:"none!important",perspective:"none!important",opacity:"1!important",zIndex:"1!important",clip:"auto!important",verticalAlign:"baseline!important",padding:0},".os-host-rtl>.os-padding>.os-viewport>.os-content>.os-textarea":{right:"0!important"},".os-content>.os-textarea-cover":{zIndex:-1,pointerEvents:"none"},".os-content>.os-textarea[wrap=off]":{whiteSpace:"pre!important",margin:"0!important"},".os-text-inherit":{fontFamily:"inherit",fontSize:"inherit",fontWeight:"inherit",fontStyle:"inherit",fontVariant:"inherit",textTransform:"inherit",textDecoration:"inherit",textIndent:"inherit",textAlign:"inherit",textShadow:"inherit",textOverflow:"inherit",letterSpacing:"inherit",wordSpacing:"inherit",lineHeight:"inherit",unicodeBidi:"inherit",direction:"inherit",color:"inherit",cursor:"text"},".os-resize-observer, .os-resize-observer-host":{boxSizing:"inherit",display:"block",opacity:0,position:"absolute",top:0,left:0,height:"100%",width:"100%",overflow:"hidden",pointerEvents:"none",zIndex:-1},".os-resize-observer-host":{padding:"inherit",border:"inherit",borderColor:"transparent",borderStyle:"solid",boxSizing:"border-box"},".os-resize-observer-host:after":{content:"''"},".os-resize-observer-host>.os-resize-observer, .os-resize-observer-host:after":{height:"200%",width:"200%",padding:"inherit",border:"inherit",margin:0,display:"block",boxSizing:"content-box"},".os-resize-observer.observed, object.os-resize-observer":{boxSizing:"border-box!important"},".os-size-auto-observer":{boxSizing:"inherit!important",height:"100%",width:"inherit",maxWidth:1,position:"relative",float:"left",maxHeight:1,overflow:"hidden",zIndex:-1,padding:0,margin:0,pointerEvents:"none",flexGrow:"inherit",flexShrink:0,flexBasis:0},".os-size-auto-observer>.os-resize-observer":{width:"1000%",height:"1000%",minHeight:1,minWidth:1},".os-resize-observer-item":{position:"absolute",top:0,right:0,bottom:0,left:0,overflow:"hidden",zIndex:-1,opacity:0,direction:"ltr!important",flex:"none!important"},".os-resize-observer-item-final":{position:"absolute",left:0,top:0,transition:"none!important",flex:"none!important"},".os-resize-observer":{animationDuration:".001s",animationName:"".concat(hsResizeObserverDummyAnimation)},".os-host-transition>.os-scrollbar, .os-host-transition>.os-scrollbar-corner":{transition:"opacity .3s,visibility .3s,top .3s,right .3s,bottom .3s,left .3s"},"html.os-html>.os-host>.os-scrollbar":{position:"absolute",zIndex:999999},".os-scrollbar, .os-scrollbar-corner":{position:"absolute",opacity:1,zIndex:1},".os-scrollbar-corner":{bottom:0,right:0,height:10,width:10,backgroundColor:"transparent"},".os-scrollbar":{pointerEvents:"none",padding:2,boxSizing:"border-box",background:0},".os-scrollbar-track":{pointerEvents:"auto",position:"relative",height:"100%",width:"100%",padding:"0!important",border:"0!important"},".os-scrollbar-handle":{pointerEvents:"auto",position:"absolute",width:"100%",height:"100%"},".os-scrollbar-handle-off, .os-scrollbar-track-off":{pointerEvents:"none"},".os-scrollbar.os-scrollbar-unusable, .os-scrollbar.os-scrollbar-unusable *":{pointerEvents:"none!important"},".os-scrollbar.os-scrollbar-unusable .os-scrollbar-handle":{opacity:"0!important"},".os-scrollbar-horizontal":{bottom:0,left:0,right:10,height:10},".os-scrollbar-vertical":{top:0,right:0,bottom:10,width:10},".os-host-rtl>.os-scrollbar-horizontal":{right:0},".os-host-rtl>.os-scrollbar-vertical":{right:"auto",left:0},".os-host-rtl>.os-scrollbar-corner":{right:"auto",left:0},".os-scrollbar-auto-hidden, .os-padding+.os-scrollbar-corner, .os-host-resize-disabled.os-host-scrollbar-horizontal-hidden>.os-scrollbar-corner, .os-host-scrollbar-horizontal-hidden>.os-scrollbar-horizontal, .os-host-resize-disabled.os-host-scrollbar-vertical-hidden>.os-scrollbar-corner, .os-host-scrollbar-vertical-hidden>.os-scrollbar-vertical, .os-scrollbar-horizontal.os-scrollbar-auto-hidden+.os-scrollbar-vertical+.os-scrollbar-corner, .os-scrollbar-horizontal+.os-scrollbar-vertical.os-scrollbar-auto-hidden+.os-scrollbar-corner, .os-scrollbar-horizontal.os-scrollbar-auto-hidden+.os-scrollbar-vertical.os-scrollbar-auto-hidden+.os-scrollbar-corner":{opacity:0,visibility:"hidden",pointerEvents:"none"},".os-scrollbar-corner-resize-both":{cursor:"nwse-resize"},".os-host-rtl>.os-scrollbar-corner-resize-both":{cursor:"nesw-resize"},".os-scrollbar-corner-resize-horizontal":{cursor:"ew-resize"},".os-scrollbar-corner-resize-vertical":{cursor:"ns-resize"},".os-dragging .os-scrollbar-corner.os-scrollbar-corner-resize":{cursor:"default"},".os-host-resize-disabled.os-host-scrollbar-horizontal-hidden>.os-scrollbar-vertical":{top:0,bottom:0},".os-host-resize-disabled.os-host-scrollbar-vertical-hidden>.os-scrollbar-horizontal, .os-host-rtl.os-host-resize-disabled.os-host-scrollbar-vertical-hidden>.os-scrollbar-horizontal":{right:0,left:0},".os-scrollbar:hover, .os-scrollbar-corner.os-scrollbar-corner-resize":{opacity:"1!important",visibility:"visible!important"},".os-scrollbar-corner.os-scrollbar-corner-resize":{backgroundImage:"linear-gradient(135deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 50%, rgba(0,0,0,0.4) 50%, rgba(0,0,0,0.4) 100%)",backgroundRepeat:"no-repeat",backgroundPosition:"100% 100%",pointerEvents:"auto!important"},".os-host-rtl>.os-scrollbar-corner.os-scrollbar-corner-resize":{transform:"scale(-1,1)"},".os-host-overflow":{overflow:"hidden!important"},".os-theme-dark.os-host-rtl>.os-scrollbar-horizontal":{left:10,right:0},".os-scrollbar.os-scrollbar-unusable":{background:0},".os-scrollbar>.os-scrollbar-track":{background:0},".os-scrollbar-horizontal>.os-scrollbar-track>.os-scrollbar-handle":{minWidth:30},".os-scrollbar-vertical>.os-scrollbar-track>.os-scrollbar-handle":{minHeight:30},".os-theme-dark.os-host-transition>.os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle":{transition:"background-color .3s"},".os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle, .os-scrollbar>.os-scrollbar-track":{borderRadius:10},".os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle":{background:theme.color.mediumdark,opacity:.5},".os-scrollbar:hover>.os-scrollbar-track>.os-scrollbar-handle":{opacity:.6},".os-scrollbar-horizontal .os-scrollbar-handle:before, .os-scrollbar-vertical .os-scrollbar-handle:before":{content:"''",position:"absolute",left:0,right:0,top:0,bottom:0,display:"block"},".os-theme-dark.os-host-scrollbar-horizontal-hidden>.os-scrollbar-horizontal .os-scrollbar-handle:before, .os-theme-dark.os-host-scrollbar-vertical-hidden>.os-scrollbar-vertical .os-scrollbar-handle:before":{display:"none"},".os-scrollbar-horizontal .os-scrollbar-handle:before":{top:-6,bottom:-2},".os-scrollbar-vertical .os-scrollbar-handle:before":{left:-6,right:-2},".os-host-rtl.os-scrollbar-vertical .os-scrollbar-handle:before":{right:-6,left:-2}}},GlobalScrollAreaStyles=function GlobalScrollAreaStyles(){return react__WEBPACK_IMPORTED_MODULE_2__.createElement(_storybook_theming__WEBPACK_IMPORTED_MODULE_3__.xB,{styles:getScrollAreaStyles})}}}]); -------------------------------------------------------------------------------- /docs/701.0be8a683.iframe.bundle.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunk_naisutech_react_tree=self.webpackChunk_naisutech_react_tree||[]).push([[701],{"./node_modules/@storybook/preview-web/dist/esm/renderDocs.js":(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{renderDocs:()=>renderDocs,unmountDocs:()=>unmountDocs});__webpack_require__("./node_modules/regenerator-runtime/runtime.js"),__webpack_require__("./node_modules/core-js/modules/es.object.to-string.js"),__webpack_require__("./node_modules/core-js/modules/es.promise.js");var react=__webpack_require__("./node_modules/react/index.js"),react_dom=__webpack_require__("./node_modules/react-dom/index.js"),wrapper={fontSize:"14px",letterSpacing:"0.2px",margin:"10px 0"},main={margin:"auto",padding:30,borderRadius:10,background:"rgba(0,0,0,0.03)"},heading={textAlign:"center"},NoDocs=function NoDocs(){return react.createElement("div",{style:wrapper,className:"sb-nodocs sb-wrapper"},react.createElement("div",{style:main},react.createElement("h1",{style:heading},"No Docs"),react.createElement("p",null,"Sorry, but there are no docs for the selected story. To add them, set the story's ",react.createElement("code",null,"docs")," parameter. If you think this is an error:"),react.createElement("ul",null,react.createElement("li",null,"Please check the story definition."),react.createElement("li",null,"Please check the Storybook config."),react.createElement("li",null,"Try reloading the page.")),react.createElement("p",null,"If the problem persists, check the browser console, or the terminal you've run Storybook from.")))};function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg),value=info.value}catch(error){return void reject(error)}info.done?resolve(value):Promise.resolve(value).then(_next,_throw)}function _asyncToGenerator(fn){return function(){var self=this,args=arguments;return new Promise((function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(void 0)}))}}function renderDocs(story,docsContext,element,callback){return function renderDocsAsync(_x,_x2,_x3){return _renderDocsAsync.apply(this,arguments)}(story,docsContext,element).then(callback)}function _renderDocsAsync(){return(_renderDocsAsync=_asyncToGenerator(regeneratorRuntime.mark((function _callee(story,docsContext,element){var _docs$getContainer,_docs$getPage,docs,DocsContainer,Page,docsElement;return regeneratorRuntime.wrap((function _callee$(_context){for(;;)switch(_context.prev=_context.next){case 0:if(!(null!=(docs=story.parameters.docs)&&docs.getPage||null!=docs&&docs.page)||(null!=docs&&docs.getContainer||null!=docs&&docs.container)){_context.next=3;break}throw new Error("No `docs.container` set, did you run `addon-docs/preset`?");case 3:if(_context.t1=docs.container,_context.t1){_context.next=8;break}return _context.next=7,null===(_docs$getContainer=docs.getContainer)||void 0===_docs$getContainer?void 0:_docs$getContainer.call(docs);case 7:_context.t1=_context.sent;case 8:if(_context.t0=_context.t1,_context.t0){_context.next=11;break}_context.t0=function(_ref){var children=_ref.children;return react.createElement(react.Fragment,null,children)};case 11:if(DocsContainer=_context.t0,_context.t3=docs.page,_context.t3){_context.next=17;break}return _context.next=16,null===(_docs$getPage=docs.getPage)||void 0===_docs$getPage?void 0:_docs$getPage.call(docs);case 16:_context.t3=_context.sent;case 17:if(_context.t2=_context.t3,_context.t2){_context.next=20;break}_context.t2=NoDocs;case 20:return Page=_context.t2,docsElement=react.createElement(DocsContainer,{key:story.componentId,context:docsContext},react.createElement(Page,null)),_context.next=24,new Promise((function(resolve){react_dom.render(docsElement,element,resolve)}));case 24:case"end":return _context.stop()}}),_callee)})))).apply(this,arguments)}function unmountDocs(element){react_dom.unmountComponentAtNode(element)}NoDocs.displayName="NoDocs"}}]); -------------------------------------------------------------------------------- /docs/705.2b2233a9.iframe.bundle.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /*! 8 | * The buffer module from node.js, for the browser. 9 | * 10 | * @author Feross Aboukhadijeh 11 | * @license MIT 12 | */ 13 | 14 | /*! 15 | * https://github.com/es-shims/es5-shim 16 | * @license es5-shim Copyright 2009-2020 by contributors, MIT License 17 | * see https://github.com/es-shims/es5-shim/blob/master/LICENSE 18 | */ 19 | 20 | /*! 21 | * is-plain-object 22 | * 23 | * Copyright (c) 2014-2017, Jon Schlinkert. 24 | * Released under the MIT License. 25 | */ 26 | 27 | /*! 28 | * isobject 29 | * 30 | * Copyright (c) 2014-2017, Jon Schlinkert. 31 | * Released under the MIT License. 32 | */ 33 | 34 | /** 35 | * @license React 36 | * react-dom.production.min.js 37 | * 38 | * Copyright (c) Facebook, Inc. and its affiliates. 39 | * 40 | * This source code is licensed under the MIT license found in the 41 | * LICENSE file in the root directory of this source tree. 42 | */ 43 | 44 | /** 45 | * @license React 46 | * react-jsx-runtime.production.min.js 47 | * 48 | * Copyright (c) Facebook, Inc. and its affiliates. 49 | * 50 | * This source code is licensed under the MIT license found in the 51 | * LICENSE file in the root directory of this source tree. 52 | */ 53 | 54 | /** 55 | * @license React 56 | * react.production.min.js 57 | * 58 | * Copyright (c) Facebook, Inc. and its affiliates. 59 | * 60 | * This source code is licensed under the MIT license found in the 61 | * LICENSE file in the root directory of this source tree. 62 | */ 63 | 64 | /** 65 | * @license React 66 | * scheduler.production.min.js 67 | * 68 | * Copyright (c) Facebook, Inc. and its affiliates. 69 | * 70 | * This source code is licensed under the MIT license found in the 71 | * LICENSE file in the root directory of this source tree. 72 | */ 73 | 74 | /** @license React v16.13.1 75 | * react-is.production.min.js 76 | * 77 | * Copyright (c) Facebook, Inc. and its affiliates. 78 | * 79 | * This source code is licensed under the MIT license found in the 80 | * LICENSE file in the root directory of this source tree. 81 | */ 82 | 83 | /** @license React v17.0.2 84 | * react-is.production.min.js 85 | * 86 | * Copyright (c) Facebook, Inc. and its affiliates. 87 | * 88 | * This source code is licensed under the MIT license found in the 89 | * LICENSE file in the root directory of this source tree. 90 | */ 91 | 92 | //! stable.js 0.1.8, https://github.com/Two-Screen/stable 93 | 94 | //! © 2018 Angry Bytes and contributors. MIT licensed. 95 | -------------------------------------------------------------------------------- /docs/745.81c2b425.iframe.bundle.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunk_naisutech_react_tree=self.webpackChunk_naisutech_react_tree||[]).push([[745],{"./node_modules/react-dom/client.js":(__unused_webpack_module,exports,__webpack_require__)=>{var m=__webpack_require__("./node_modules/react-dom/index.js");exports.createRoot=m.createRoot,exports.hydrateRoot=m.hydrateRoot}}]); -------------------------------------------------------------------------------- /docs/807.5f1ebcc4.iframe.bundle.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Google Inc. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file at https://angular.io/license 7 | */ 8 | 9 | /** 10 | * @license 11 | * Copyright Google Inc. All Rights Reserved. 12 | * 13 | * Use of this source code is governed by an MIT-style license that can be 14 | * found in the LICENSE file at https://angular.io/license 15 | */ 16 | 17 | /** 18 | * @license 19 | * Copyright Google Inc. All Rights Reserved. 20 | * 21 | * Use of this source code is governed by an MIT-style license that can be 22 | * found in the LICENSE file at https://angular.io/license 23 | */ 24 | 25 | /** 26 | * @license 27 | * Copyright Google Inc. All Rights Reserved. 28 | * 29 | * Use of this source code is governed by an MIT-style license that can be 30 | * found in the LICENSE file at https://angular.io/license 31 | */ 32 | -------------------------------------------------------------------------------- /docs/807.b6c07b84a21e65368b97.manager.bundle.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Google Inc. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file at https://angular.io/license 7 | */ 8 | 9 | /** 10 | * @license 11 | * Copyright Google Inc. All Rights Reserved. 12 | * 13 | * Use of this source code is governed by an MIT-style license that can be 14 | * found in the LICENSE file at https://angular.io/license 15 | */ 16 | 17 | /** 18 | * @license 19 | * Copyright Google Inc. All Rights Reserved. 20 | * 21 | * Use of this source code is governed by an MIT-style license that can be 22 | * found in the LICENSE file at https://angular.io/license 23 | */ 24 | 25 | /** 26 | * @license 27 | * Copyright Google Inc. All Rights Reserved. 28 | * 29 | * Use of this source code is governed by an MIT-style license that can be 30 | * found in the LICENSE file at https://angular.io/license 31 | */ 32 | -------------------------------------------------------------------------------- /docs/897.42824d67.iframe.bundle.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | * OverlayScrollbars 3 | * https://github.com/KingSora/OverlayScrollbars 4 | * 5 | * Version: 1.13.0 6 | * 7 | * Copyright KingSora | Rene Haas. 8 | * https://github.com/KingSora 9 | * 10 | * Released under the MIT license. 11 | * Date: 02.08.2020 12 | */ 13 | -------------------------------------------------------------------------------- /docs/897.9ce4e971c3718f12eeb4.manager.bundle.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | * OverlayScrollbars 3 | * https://github.com/KingSora/OverlayScrollbars 4 | * 5 | * Version: 1.13.0 6 | * 7 | * Copyright KingSora | Rene Haas. 8 | * https://github.com/KingSora 9 | * 10 | * Released under the MIT license. 11 | * Date: 02.08.2020 12 | */ 13 | -------------------------------------------------------------------------------- /docs/935.eff965ec22feacd9e876.manager.bundle.js: -------------------------------------------------------------------------------- 1 | "use strict";(self.webpackChunk_naisutech_react_tree=self.webpackChunk_naisutech_react_tree||[]).push([[935],{15935:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{ColorControl:()=>ColorControl,default:()=>ColorControl});__webpack_require__(19601),__webpack_require__(47941),__webpack_require__(69600),__webpack_require__(57327),__webpack_require__(41539),__webpack_require__(9653),__webpack_require__(74916),__webpack_require__(39714),__webpack_require__(15306),__webpack_require__(66992),__webpack_require__(51532),__webpack_require__(78783),__webpack_require__(33948),__webpack_require__(4723),__webpack_require__(21249),__webpack_require__(23123),__webpack_require__(54747),__webpack_require__(47042),__webpack_require__(92222),__webpack_require__(26833),__webpack_require__(23157),__webpack_require__(68309),__webpack_require__(82526),__webpack_require__(41817),__webpack_require__(32165),__webpack_require__(91038);var _ColorPicker,_fallbackColor,_index_681e4b07_js__WEBPACK_IMPORTED_MODULE_30__=__webpack_require__(94601),react__WEBPACK_IMPORTED_MODULE_26__=__webpack_require__(67294),_storybook_theming__WEBPACK_IMPORTED_MODULE_31__=__webpack_require__(65316);__webpack_require__(52326),__webpack_require__(35032),__webpack_require__(80129);function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}function _typeof(obj){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(obj){return typeof obj}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj},_typeof(obj)}function _slicedToArray(arr,i){return function _arrayWithHoles(arr){if(Array.isArray(arr))return arr}(arr)||function _iterableToArrayLimit(arr,i){var _i=null==arr?null:"undefined"!=typeof Symbol&&arr[Symbol.iterator]||arr["@@iterator"];if(null==_i)return;var _s,_e,_arr=[],_n=!0,_d=!1;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done)&&(_arr.push(_s.value),!i||_arr.length!==i);_n=!0);}catch(err){_d=!0,_e=err}finally{try{_n||null==_i.return||_i.return()}finally{if(_d)throw _e}}return _arr}(arr,i)||function _unsupportedIterableToArray(o,minLen){if(!o)return;if("string"==typeof o)return _arrayLikeToArray(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);"Object"===n&&o.constructor&&(n=o.constructor.name);if("Map"===n||"Set"===n)return Array.from(o);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _arrayLikeToArray(o,minLen)}(arr,i)||function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _arrayLikeToArray(arr,len){(null==len||len>arr.length)&&(len=arr.length);for(var i=0,arr2=new Array(len);i=0||(o[t]=e[t]);return o}function i(e){var t=(0,react__WEBPACK_IMPORTED_MODULE_26__.useRef)(e),n=(0,react__WEBPACK_IMPORTED_MODULE_26__.useRef)((function(e){t.current&&t.current(e)}));return t.current=e,n.current}var s=function s(e,r,t){return void 0===r&&(r=0),void 0===t&&(t=1),e>t?t:e0:_e.buttons>0)&&m.current?g(d(m.current,_e,b.current)):t(!1)},r=function r(){return t(!1)};function t(t){var n=_.current,o=v(m.current),a=t?o.addEventListener:o.removeEventListener;a(n?"touchmove":"mousemove",e),a(n?"touchend":"mouseup",r)}return[function(e){var r=e.nativeEvent,n=m.current;if(n&&(h(r),!function(e,r){return r&&!f(e)}(r,_.current)&&n)){if(f(r)){_.current=!0;var o=r.changedTouches||[];o.length&&(b.current=o[0].identifier)}n.focus(),g(d(n,r,b.current)),t(!0)}},function(e){var r=e.which||e.keyCode;r<37||r>40||(e.preventDefault(),p({left:39===r?.05:37===r?-.05:0,top:40===r?.05:38===r?-.05:0}))},t]}),[p,g]),C=x[0],E=x[1],H=x[2];return(0,react__WEBPACK_IMPORTED_MODULE_26__.useEffect)((function(){return H}),[H]),react__WEBPACK_IMPORTED_MODULE_26__.createElement("div",u({},s,{onTouchStart:C,onMouseDown:C,className:"react-colorful__interactive",ref:m,onKeyDown:E,tabIndex:0,role:"slider"}))})),g=function g(e){return e.filter(Boolean).join(" ")},p=function p(r){var t=r.color,n=r.left,o=r.top,a=void 0===o?.5:o,l=g(["react-colorful__pointer",r.className]);return react__WEBPACK_IMPORTED_MODULE_26__.createElement("div",{className:l,style:{top:100*a+"%",left:100*n+"%"}},react__WEBPACK_IMPORTED_MODULE_26__.createElement("div",{className:"react-colorful__pointer-fill",style:{backgroundColor:t}}))},b=function b(e,r,t){return void 0===r&&(r=0),void 0===t&&(t=Math.pow(10,r)),Math.round(t*e)/t},_={grad:.9,turn:360,rad:360/(2*Math.PI)},x=function x(e){return"#"===e[0]&&(e=e.substr(1)),e.length<6?{r:parseInt(e[0]+e[0],16),g:parseInt(e[1]+e[1],16),b:parseInt(e[2]+e[2],16),a:1}:{r:parseInt(e.substr(0,2),16),g:parseInt(e.substr(2,2),16),b:parseInt(e.substr(4,2),16),a:1}},C=function C(e,r){return void 0===r&&(r="deg"),Number(e)*(_[r]||1)},M=function M(e){var r=e.s,t=e.l;return{h:e.h,s:(r*=(t<50?t:100-t)/100)>0?2*r/(t+r)*100:0,v:t+r,a:e.a}},N=function N(e){var r=e.s,t=e.v,n=e.a,o=(200-r)*t/100;return{h:b(e.h),s:b(o>0&&o<200?r*t/100/(o<=100?o:200-o)*100:0),l:b(o/2),a:b(n,2)}},w=function w(e){var r=N(e);return"hsl("+r.h+", "+r.s+"%, "+r.l+"%)"},y=function y(e){var r=N(e);return"hsla("+r.h+", "+r.s+"%, "+r.l+"%, "+r.a+")"},q=function q(e){var r=e.h,t=e.s,n=e.v,o=e.a;r=r/360*6,t/=100,n/=100;var a=Math.floor(r),l=n*(1-t),u=n*(1-(r-a)*t),c=n*(1-(1-r+a)*t),i=a%6;return{r:b(255*[n,u,l,l,c,n][i]),g:b(255*[c,n,n,u,l,l][i]),b:b(255*[l,l,c,n,n,u][i]),a:b(o,2)}},z=function z(e){var r=e.toString(16);return r.length<2?"0"+r:r},B=function B(e){var r=e.r,t=e.g,n=e.b,o=e.a,a=Math.max(r,t,n),l=a-Math.min(r,t,n),u=l?a===r?(t-n)/l:a===t?2+(n-r)/l:4+(r-t)/l:0;return{h:b(60*(u<0?u+6:u)),s:b(a?l/a*100:0),v:b(a/255*100),a:o}},K=react__WEBPACK_IMPORTED_MODULE_26__.memo((function(r){var t=r.hue,n=r.onChange,o=g(["react-colorful__hue",r.className]);return react__WEBPACK_IMPORTED_MODULE_26__.createElement("div",{className:o},react__WEBPACK_IMPORTED_MODULE_26__.createElement(m,{onMove:function onMove(e){n({h:360*e.left})},onKey:function onKey(e){n({h:s(t+360*e.left,0,360)})},"aria-label":"Hue","aria-valuetext":b(t)},react__WEBPACK_IMPORTED_MODULE_26__.createElement(p,{className:"react-colorful__hue-pointer",left:t/360,color:w({h:t,s:100,v:100,a:1})})))})),L=react__WEBPACK_IMPORTED_MODULE_26__.memo((function(r){var t=r.hsva,n=r.onChange,o={backgroundColor:w({h:t.h,s:100,v:100,a:1})};return react__WEBPACK_IMPORTED_MODULE_26__.createElement("div",{className:"react-colorful__saturation",style:o},react__WEBPACK_IMPORTED_MODULE_26__.createElement(m,{onMove:function onMove(e){n({s:100*e.left,v:100-100*e.top})},onKey:function onKey(e){n({s:s(t.s+100*e.left,0,100),v:s(t.v-100*e.top,0,100)})},"aria-label":"Color","aria-valuetext":"Saturation "+b(t.s)+"%, Brightness "+b(t.v)+"%"},react__WEBPACK_IMPORTED_MODULE_26__.createElement(p,{className:"react-colorful__saturation-pointer",top:1-t.v/100,left:t.s/100,color:w(t)})))})),A=function A(e,r){if(e===r)return!0;for(var t in e)if(e[t]!==r[t])return!1;return!0},S=function S(e,r){return e.replace(/\s/g,"")===r.replace(/\s/g,"")};function T(e,t,l){var u=i(l),c=(0,react__WEBPACK_IMPORTED_MODULE_26__.useState)((function(){return e.toHsva(t)})),s=c[0],f=c[1],v=(0,react__WEBPACK_IMPORTED_MODULE_26__.useRef)({color:t,hsva:s});(0,react__WEBPACK_IMPORTED_MODULE_26__.useEffect)((function(){if(!e.equal(t,v.current.color)){var r=e.toHsva(t);v.current={hsva:r,color:t},f(r)}}),[t,e]),(0,react__WEBPACK_IMPORTED_MODULE_26__.useEffect)((function(){var r;A(s,v.current.hsva)||e.equal(r=e.fromHsva(s),v.current.color)||(v.current={hsva:s,color:r},u(r))}),[s,e,u]);var d=(0,react__WEBPACK_IMPORTED_MODULE_26__.useCallback)((function(e){f((function(r){return Object.assign({},r,e)}))}),[]);return[s,d]}for(var P="undefined"!=typeof window?react__WEBPACK_IMPORTED_MODULE_26__.useLayoutEffect:react__WEBPACK_IMPORTED_MODULE_26__.useEffect,R=new Map,V=function V(e){P((function(){var r=e.current?e.current.ownerDocument:document;if(void 0!==r&&!R.has(r)){var t=r.createElement("style");t.innerHTML='.react-colorful{position:relative;display:flex;flex-direction:column;width:200px;height:200px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.react-colorful__saturation{position:relative;flex-grow:1;border-color:transparent;border-bottom:12px solid #000;border-radius:8px 8px 0 0;background-image:linear-gradient(0deg,#000,transparent),linear-gradient(90deg,#fff,hsla(0,0%,100%,0))}.react-colorful__alpha-gradient,.react-colorful__pointer-fill{content:"";position:absolute;left:0;top:0;right:0;bottom:0;pointer-events:none;border-radius:inherit}.react-colorful__alpha-gradient,.react-colorful__saturation{box-shadow:inset 0 0 0 1px rgba(0,0,0,.05)}.react-colorful__alpha,.react-colorful__hue{position:relative;height:24px}.react-colorful__hue{background:linear-gradient(90deg,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red)}.react-colorful__last-control{border-radius:0 0 8px 8px}.react-colorful__interactive{position:absolute;left:0;top:0;right:0;bottom:0;border-radius:inherit;outline:none;touch-action:none}.react-colorful__pointer{position:absolute;z-index:1;box-sizing:border-box;width:28px;height:28px;transform:translate(-50%,-50%);background-color:#fff;border:2px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.2)}.react-colorful__interactive:focus .react-colorful__pointer{transform:translate(-50%,-50%) scale(1.1)}.react-colorful__alpha,.react-colorful__alpha-pointer{background-color:#fff;background-image:url(\'data:image/svg+xml;charset=utf-8,\')}.react-colorful__saturation-pointer{z-index:3}.react-colorful__hue-pointer{z-index:2}',R.set(r,t);var n=function X(){return __webpack_require__.nc}();n&&t.setAttribute("nonce",n),r.head.appendChild(t)}}),[])},$=function $(t){var n=t.className,o=t.colorModel,a=t.color,l=void 0===a?o.defaultColor:a,i=t.onChange,s=c(t,["className","colorModel","color","onChange"]),f=(0,react__WEBPACK_IMPORTED_MODULE_26__.useRef)(null);V(f);var v=T(o,l,i),d=v[0],h=v[1],m=g(["react-colorful",n]);return react__WEBPACK_IMPORTED_MODULE_26__.createElement("div",u({},s,{ref:f,className:m}),react__WEBPACK_IMPORTED_MODULE_26__.createElement(L,{hsva:d,onChange:h}),react__WEBPACK_IMPORTED_MODULE_26__.createElement(K,{hue:d.h,onChange:h,className:"react-colorful__last-control"}))},G={defaultColor:"000",toHsva:function toHsva(e){return B(x(e))},fromHsva:function fromHsva(e){return t=(r=q(e)).g,n=r.b,"#"+z(r.r)+z(t)+z(n);var r,t,n},equal:function equal(e,r){return e.toLowerCase()===r.toLowerCase()||A(x(e),x(r))}},Q=function Q(r){var t=r.className,n=r.hsva,o=r.onChange,a={backgroundImage:"linear-gradient(90deg, "+y(Object.assign({},n,{a:0}))+", "+y(Object.assign({},n,{a:1}))+")"},l=g(["react-colorful__alpha",t]);return react__WEBPACK_IMPORTED_MODULE_26__.createElement("div",{className:l},react__WEBPACK_IMPORTED_MODULE_26__.createElement("div",{className:"react-colorful__alpha-gradient",style:a}),react__WEBPACK_IMPORTED_MODULE_26__.createElement(m,{onMove:function onMove(e){o({a:e.left})},onKey:function onKey(e){o({a:s(n.a+e.left)})},"aria-label":"Alpha","aria-valuetext":b(100*n.a)+"%"},react__WEBPACK_IMPORTED_MODULE_26__.createElement(p,{className:"react-colorful__alpha-pointer",left:n.a,color:y(n)})))},U=function U(t){var n=t.className,o=t.colorModel,a=t.color,l=void 0===a?o.defaultColor:a,i=t.onChange,s=c(t,["className","colorModel","color","onChange"]),f=(0,react__WEBPACK_IMPORTED_MODULE_26__.useRef)(null);V(f);var v=T(o,l,i),d=v[0],h=v[1],m=g(["react-colorful",n]);return react__WEBPACK_IMPORTED_MODULE_26__.createElement("div",u({},s,{ref:f,className:m}),react__WEBPACK_IMPORTED_MODULE_26__.createElement(L,{hsva:d,onChange:h}),react__WEBPACK_IMPORTED_MODULE_26__.createElement(K,{hue:d.h,onChange:h}),react__WEBPACK_IMPORTED_MODULE_26__.createElement(Q,{hsva:d,onChange:h,className:"react-colorful__last-control"}))},ee={defaultColor:"hsla(0, 0%, 0%, 1)",toHsva:function E(e){var r=/hsla?\(?\s*(-?\d*\.?\d+)(deg|rad|grad|turn)?[,\s]+(-?\d*\.?\d+)%?[,\s]+(-?\d*\.?\d+)%?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i.exec(e);return r?M({h:C(r[1],r[2]),s:Number(r[3]),l:Number(r[4]),a:void 0===r[5]?1:Number(r[5])/(r[6]?100:1)}):{h:0,s:0,v:0,a:1}},fromHsva:y,equal:S},ge={defaultColor:"rgba(0, 0, 0, 1)",toHsva:function I(e){var r=/rgba?\(?\s*(-?\d*\.?\d+)(%)?[,\s]+(-?\d*\.?\d+)(%)?[,\s]+(-?\d*\.?\d+)(%)?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i.exec(e);return r?B({r:Number(r[1])/(r[2]?100/255:1),g:Number(r[3])/(r[4]?100/255:1),b:Number(r[5])/(r[6]?100/255:1),a:void 0===r[7]?1:Number(r[7])/(r[8]?100:1)}):{h:0,s:0,v:0,a:1}},fromHsva:function fromHsva(e){var r=q(e);return"rgba("+r.r+", "+r.g+", "+r.b+", "+r.a+")"},equal:S},cssKeywords={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},reverseKeywords={},_i=0,_Object$keys=Object.keys(cssKeywords);_i<_Object$keys.length;_i++){var key=_Object$keys[_i];reverseKeywords[cssKeywords[key]]=key}for(var convert$1={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}},conversions$2=convert$1,_i2=0,_Object$keys2=Object.keys(convert$1);_i2<_Object$keys2.length;_i2++){var model=_Object$keys2[_i2];if(!("channels"in convert$1[model]))throw new Error("missing channels property: "+model);if(!("labels"in convert$1[model]))throw new Error("missing channel labels property: "+model);if(convert$1[model].labels.length!==convert$1[model].channels)throw new Error("channel and label counts mismatch: "+model);var _convert$1$model=convert$1[model],channels=_convert$1$model.channels,labels=_convert$1$model.labels;delete convert$1[model].channels,delete convert$1[model].labels,Object.defineProperty(convert$1[model],"channels",{value:channels}),Object.defineProperty(convert$1[model],"labels",{value:labels})}function comparativeDistance(x,y){return Math.pow(x[0]-y[0],2)+Math.pow(x[1]-y[1],2)+Math.pow(x[2]-y[2],2)}convert$1.rgb.hsl=function(rgb){var h,r=rgb[0]/255,g=rgb[1]/255,b=rgb[2]/255,min=Math.min(r,g,b),max=Math.max(r,g,b),delta=max-min;max===min?h=0:r===max?h=(g-b)/delta:g===max?h=2+(b-r)/delta:b===max&&(h=4+(r-g)/delta),(h=Math.min(60*h,360))<0&&(h+=360);var l=(min+max)/2;return[h,100*(max===min?0:l<=.5?delta/(max+min):delta/(2-max-min)),100*l]},convert$1.rgb.hsv=function(rgb){var rdif,gdif,bdif,h,s,r=rgb[0]/255,g=rgb[1]/255,b=rgb[2]/255,v=Math.max(r,g,b),diff=v-Math.min(r,g,b),diffc=function diffc(c){return(v-c)/6/diff+.5};return 0===diff?(h=0,s=0):(s=diff/v,rdif=diffc(r),gdif=diffc(g),bdif=diffc(b),r===v?h=bdif-gdif:g===v?h=1/3+rdif-bdif:b===v&&(h=2/3+gdif-rdif),h<0?h+=1:h>1&&(h-=1)),[360*h,100*s,100*v]},convert$1.rgb.hwb=function(rgb){var r=rgb[0],g=rgb[1],b=rgb[2];return[convert$1.rgb.hsl(rgb)[0],100*(1/255*Math.min(r,Math.min(g,b))),100*(b=1-1/255*Math.max(r,Math.max(g,b)))]},convert$1.rgb.cmyk=function(rgb){var r=rgb[0]/255,g=rgb[1]/255,b=rgb[2]/255,k=Math.min(1-r,1-g,1-b);return[100*((1-r-k)/(1-k)||0),100*((1-g-k)/(1-k)||0),100*((1-b-k)/(1-k)||0),100*k]},convert$1.rgb.keyword=function(rgb){var reversed=reverseKeywords[rgb];if(reversed)return reversed;for(var currentClosestKeyword,currentClosestDistance=1/0,_i3=0,_Object$keys3=Object.keys(cssKeywords);_i3<_Object$keys3.length;_i3++){var keyword=_Object$keys3[_i3],distance=comparativeDistance(rgb,cssKeywords[keyword]);distance.04045?Math.pow((r+.055)/1.055,2.4):r/12.92)+.3576*(g=g>.04045?Math.pow((g+.055)/1.055,2.4):g/12.92)+.1805*(b=b>.04045?Math.pow((b+.055)/1.055,2.4):b/12.92)),100*(.2126*r+.7152*g+.0722*b),100*(.0193*r+.1192*g+.9505*b)]},convert$1.rgb.lab=function(rgb){var xyz=convert$1.rgb.xyz(rgb),x=xyz[0],y=xyz[1],z=xyz[2];return y/=100,z/=108.883,x=(x/=95.047)>.008856?Math.pow(x,1/3):7.787*x+16/116,[116*(y=y>.008856?Math.pow(y,1/3):7.787*y+16/116)-16,500*(x-y),200*(y-(z=z>.008856?Math.pow(z,1/3):7.787*z+16/116))]},convert$1.hsl.rgb=function(hsl){var t2,t3,val,h=hsl[0]/360,s=hsl[1]/100,l=hsl[2]/100;if(0===s)return[val=255*l,val,val];for(var t1=2*l-(t2=l<.5?l*(1+s):l+s-l*s),rgb=[0,0,0],_i4=0;_i4<3;_i4++)(t3=h+1/3*-(_i4-1))<0&&t3++,t3>1&&t3--,val=6*t3<1?t1+6*(t2-t1)*t3:2*t3<1?t2:3*t3<2?t1+(t2-t1)*(2/3-t3)*6:t1,rgb[_i4]=255*val;return rgb},convert$1.hsl.hsv=function(hsl){var h=hsl[0],s=hsl[1]/100,l=hsl[2]/100,smin=s,lmin=Math.max(l,.01);return s*=(l*=2)<=1?l:2-l,smin*=lmin<=1?lmin:2-lmin,[h,100*(0===l?2*smin/(lmin+smin):2*s/(l+s)),100*((l+s)/2)]},convert$1.hsv.rgb=function(hsv){var h=hsv[0]/60,s=hsv[1]/100,v=hsv[2]/100,hi=Math.floor(h)%6,f=h-Math.floor(h),p=255*v*(1-s),q=255*v*(1-s*f),t=255*v*(1-s*(1-f));switch(v*=255,hi){case 0:return[v,t,p];case 1:return[q,v,p];case 2:return[p,v,t];case 3:return[p,q,v];case 4:return[t,p,v];case 5:return[v,p,q]}},convert$1.hsv.hsl=function(hsv){var sl,l,h=hsv[0],s=hsv[1]/100,v=hsv[2]/100,vmin=Math.max(v,.01);l=(2-s)*v;var lmin=(2-s)*vmin;return sl=s*vmin,[h,100*(sl=(sl/=lmin<=1?lmin:2-lmin)||0),100*(l/=2)]},convert$1.hwb.rgb=function(hwb){var f,h=hwb[0]/360,wh=hwb[1]/100,bl=hwb[2]/100,ratio=wh+bl;ratio>1&&(wh/=ratio,bl/=ratio);var i=Math.floor(6*h),v=1-bl;f=6*h-i,0!=(1&i)&&(f=1-f);var r,g,b,n=wh+f*(v-wh);switch(i){default:case 6:case 0:r=v,g=n,b=wh;break;case 1:r=n,g=v,b=wh;break;case 2:r=wh,g=v,b=n;break;case 3:r=wh,g=n,b=v;break;case 4:r=n,g=wh,b=v;break;case 5:r=v,g=wh,b=n}return[255*r,255*g,255*b]},convert$1.cmyk.rgb=function(cmyk){var c=cmyk[0]/100,m=cmyk[1]/100,y=cmyk[2]/100,k=cmyk[3]/100;return[255*(1-Math.min(1,c*(1-k)+k)),255*(1-Math.min(1,m*(1-k)+k)),255*(1-Math.min(1,y*(1-k)+k))]},convert$1.xyz.rgb=function(xyz){var r,g,b,x=xyz[0]/100,y=xyz[1]/100,z=xyz[2]/100;return g=-.9689*x+1.8758*y+.0415*z,b=.0557*x+-.204*y+1.057*z,r=(r=3.2406*x+-1.5372*y+-.4986*z)>.0031308?1.055*Math.pow(r,1/2.4)-.055:12.92*r,g=g>.0031308?1.055*Math.pow(g,1/2.4)-.055:12.92*g,b=b>.0031308?1.055*Math.pow(b,1/2.4)-.055:12.92*b,[255*(r=Math.min(Math.max(0,r),1)),255*(g=Math.min(Math.max(0,g),1)),255*(b=Math.min(Math.max(0,b),1))]},convert$1.xyz.lab=function(xyz){var x=xyz[0],y=xyz[1],z=xyz[2];return y/=100,z/=108.883,x=(x/=95.047)>.008856?Math.pow(x,1/3):7.787*x+16/116,[116*(y=y>.008856?Math.pow(y,1/3):7.787*y+16/116)-16,500*(x-y),200*(y-(z=z>.008856?Math.pow(z,1/3):7.787*z+16/116))]},convert$1.lab.xyz=function(lab){var x,y,z,l=lab[0];x=lab[1]/500+(y=(l+16)/116),z=y-lab[2]/200;var y2=Math.pow(y,3),x2=Math.pow(x,3),z2=Math.pow(z,3);return y=y2>.008856?y2:(y-16/116)/7.787,x=x2>.008856?x2:(x-16/116)/7.787,z=z2>.008856?z2:(z-16/116)/7.787,[x*=95.047,y*=100,z*=108.883]},convert$1.lab.lch=function(lab){var h,l=lab[0],a=lab[1],b=lab[2];return(h=360*Math.atan2(b,a)/2/Math.PI)<0&&(h+=360),[l,Math.sqrt(a*a+b*b),h]},convert$1.lch.lab=function(lch){var l=lch[0],c=lch[1],hr=lch[2]/360*2*Math.PI;return[l,c*Math.cos(hr),c*Math.sin(hr)]},convert$1.rgb.ansi16=function(args){var saturation=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,_args=_slicedToArray(args,3),r=_args[0],g=_args[1],b=_args[2],value=null===saturation?convert$1.rgb.hsv(args)[2]:saturation;if(0===(value=Math.round(value/50)))return 30;var ansi=30+(Math.round(b/255)<<2|Math.round(g/255)<<1|Math.round(r/255));return 2===value&&(ansi+=60),ansi},convert$1.hsv.ansi16=function(args){return convert$1.rgb.ansi16(convert$1.hsv.rgb(args),args[2])},convert$1.rgb.ansi256=function(args){var r=args[0],g=args[1],b=args[2];return r===g&&g===b?r<8?16:r>248?231:Math.round((r-8)/247*24)+232:16+36*Math.round(r/255*5)+6*Math.round(g/255*5)+Math.round(b/255*5)},convert$1.ansi16.rgb=function(args){var color=args%10;if(0===color||7===color)return args>50&&(color+=3.5),[color=color/10.5*255,color,color];var mult=.5*(1+~~(args>50));return[(1&color)*mult*255,(color>>1&1)*mult*255,(color>>2&1)*mult*255]},convert$1.ansi256.rgb=function(args){if(args>=232){var _c=10*(args-232)+8;return[_c,_c,_c]}var rem;return args-=16,[Math.floor(args/36)/5*255,Math.floor((rem=args%36)/6)/5*255,rem%6/5*255]},convert$1.rgb.hex=function(args){var string=(((255&Math.round(args[0]))<<16)+((255&Math.round(args[1]))<<8)+(255&Math.round(args[2]))).toString(16).toUpperCase();return"000000".substring(string.length)+string},convert$1.hex.rgb=function(args){var match=args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!match)return[0,0,0];var colorString=match[0];3===match[0].length&&(colorString=colorString.split("").map((function(char){return char+char})).join(""));var integer=parseInt(colorString,16);return[integer>>16&255,integer>>8&255,255&integer]},convert$1.rgb.hcg=function(rgb){var hue,r=rgb[0]/255,g=rgb[1]/255,b=rgb[2]/255,max=Math.max(Math.max(r,g),b),min=Math.min(Math.min(r,g),b),chroma=max-min;return hue=chroma<=0?0:max===r?(g-b)/chroma%6:max===g?2+(b-r)/chroma:4+(r-g)/chroma,hue/=6,[360*(hue%=1),100*chroma,100*(chroma<1?min/(1-chroma):0)]},convert$1.hsl.hcg=function(hsl){var s=hsl[1]/100,l=hsl[2]/100,c=l<.5?2*s*l:2*s*(1-l),f=0;return c<1&&(f=(l-.5*c)/(1-c)),[hsl[0],100*c,100*f]},convert$1.hsv.hcg=function(hsv){var s=hsv[1]/100,v=hsv[2]/100,c=s*v,f=0;return c<1&&(f=(v-c)/(1-c)),[hsv[0],100*c,100*f]},convert$1.hcg.rgb=function(hcg){var h=hcg[0]/360,c=hcg[1]/100,g=hcg[2]/100;if(0===c)return[255*g,255*g,255*g];var mg,pure=[0,0,0],hi=h%1*6,v=hi%1,w=1-v;switch(Math.floor(hi)){case 0:pure[0]=1,pure[1]=v,pure[2]=0;break;case 1:pure[0]=w,pure[1]=1,pure[2]=0;break;case 2:pure[0]=0,pure[1]=1,pure[2]=v;break;case 3:pure[0]=0,pure[1]=w,pure[2]=1;break;case 4:pure[0]=v,pure[1]=0,pure[2]=1;break;default:pure[0]=1,pure[1]=0,pure[2]=w}return mg=(1-c)*g,[255*(c*pure[0]+mg),255*(c*pure[1]+mg),255*(c*pure[2]+mg)]},convert$1.hcg.hsv=function(hcg){var c=hcg[1]/100,v=c+hcg[2]/100*(1-c),f=0;return v>0&&(f=c/v),[hcg[0],100*f,100*v]},convert$1.hcg.hsl=function(hcg){var c=hcg[1]/100,l=hcg[2]/100*(1-c)+.5*c,s=0;return l>0&&l<.5?s=c/(2*l):l>=.5&&l<1&&(s=c/(2*(1-l))),[hcg[0],100*s,100*l]},convert$1.hcg.hwb=function(hcg){var c=hcg[1]/100,v=c+hcg[2]/100*(1-c);return[hcg[0],100*(v-c),100*(1-v)]},convert$1.hwb.hcg=function(hwb){var w=hwb[1]/100,v=1-hwb[2]/100,c=v-w,g=0;return c<1&&(g=(v-c)/(1-c)),[hwb[0],100*c,100*g]},convert$1.apple.rgb=function(apple){return[apple[0]/65535*255,apple[1]/65535*255,apple[2]/65535*255]},convert$1.rgb.apple=function(rgb){return[rgb[0]/255*65535,rgb[1]/255*65535,rgb[2]/255*65535]},convert$1.gray.rgb=function(args){return[args[0]/100*255,args[0]/100*255,args[0]/100*255]},convert$1.gray.hsl=function(args){return[0,0,args[0]]},convert$1.gray.hsv=convert$1.gray.hsl,convert$1.gray.hwb=function(gray){return[0,100,gray[0]]},convert$1.gray.cmyk=function(gray){return[0,0,0,gray[0]]},convert$1.gray.lab=function(gray){return[gray[0],0,0]},convert$1.gray.hex=function(gray){var val=255&Math.round(gray[0]/100*255),string=((val<<16)+(val<<8)+val).toString(16).toUpperCase();return"000000".substring(string.length)+string},convert$1.rgb.gray=function(rgb){return[(rgb[0]+rgb[1]+rgb[2])/3/255*100]};var conversions$1=conversions$2;function deriveBFS(fromModel){var graph=function buildGraph(){for(var graph={},models=Object.keys(conversions$1),len=models.length,_i5=0;_i51&&(args=arg0);var result=fn(args);if("object"===_typeof(result))for(var len=result.length,_i8=0;_i81&&(args=arg0),fn(args))};return"conversion"in fn&&(wrappedFn.conversion=fn.conversion),wrappedFn}(fn)}))}));var colorConvert=convert,root=_index_681e4b07_js__WEBPACK_IMPORTED_MODULE_30__.u,now_1=function now$1(){return root.Date.now()},reWhitespace=/\s/;var trimmedEndIndex=function trimmedEndIndex$1(string){for(var index=string.length;index--&&reWhitespace.test(string.charAt(index)););return index},reTrimStart=/^\s+/;var baseTrim=function baseTrim$1(string){return string?string.slice(0,trimmedEndIndex(string)+1).replace(reTrimStart,""):string},isObject$2=_index_681e4b07_js__WEBPACK_IMPORTED_MODULE_30__.x,isSymbol=_index_681e4b07_js__WEBPACK_IMPORTED_MODULE_30__.y,reIsBadHex=/^[-+]0x[0-9a-f]+$/i,reIsBinary=/^0b[01]+$/i,reIsOctal=/^0o[0-7]+$/i,freeParseInt=parseInt;var toNumber_1=function toNumber$1(value){if("number"==typeof value)return value;if(isSymbol(value))return NaN;if(isObject$2(value)){var other="function"==typeof value.valueOf?value.valueOf():value;value=isObject$2(other)?other+"":other}if("string"!=typeof value)return 0===value?value:+value;value=baseTrim(value);var isBinary=reIsBinary.test(value);return isBinary||reIsOctal.test(value)?freeParseInt(value.slice(2),isBinary?2:8):reIsBadHex.test(value)?NaN:+value},isObject$1=_index_681e4b07_js__WEBPACK_IMPORTED_MODULE_30__.x,now=now_1,toNumber=toNumber_1,nativeMax=Math.max,nativeMin=Math.min;var debounce=function debounce$1(func,wait,options){var lastArgs,lastThis,maxWait,result,timerId,lastCallTime,lastInvokeTime=0,leading=!1,maxing=!1,trailing=!0;if("function"!=typeof func)throw new TypeError("Expected a function");function invokeFunc(time){var args=lastArgs,thisArg=lastThis;return lastArgs=lastThis=void 0,lastInvokeTime=time,result=func.apply(thisArg,args)}function leadingEdge(time){return lastInvokeTime=time,timerId=setTimeout(timerExpired,wait),leading?invokeFunc(time):result}function shouldInvoke(time){var timeSinceLastCall=time-lastCallTime;return void 0===lastCallTime||timeSinceLastCall>=wait||timeSinceLastCall<0||maxing&&time-lastInvokeTime>=maxWait}function timerExpired(){var time=now();if(shouldInvoke(time))return trailingEdge(time);timerId=setTimeout(timerExpired,function remainingWait(time){var timeWaiting=wait-(time-lastCallTime);return maxing?nativeMin(timeWaiting,maxWait-(time-lastInvokeTime)):timeWaiting}(time))}function trailingEdge(time){return timerId=void 0,trailing&&lastArgs?invokeFunc(time):(lastArgs=lastThis=void 0,result)}function debounced(){var time=now(),isInvoking=shouldInvoke(time);if(lastArgs=arguments,lastThis=this,lastCallTime=time,isInvoking){if(void 0===timerId)return leadingEdge(lastCallTime);if(maxing)return clearTimeout(timerId),timerId=setTimeout(timerExpired,wait),invokeFunc(lastCallTime)}return void 0===timerId&&(timerId=setTimeout(timerExpired,wait)),result}return wait=toNumber(wait)||0,isObject$1(options)&&(leading=!!options.leading,maxWait=(maxing="maxWait"in options)?nativeMax(toNumber(options.maxWait)||0,wait):maxWait,trailing="trailing"in options?!!options.trailing:trailing),debounced.cancel=function cancel(){void 0!==timerId&&clearTimeout(timerId),lastInvokeTime=0,lastArgs=lastCallTime=lastThis=timerId=void 0},debounced.flush=function flush(){return void 0===timerId?result:trailingEdge(now())},debounced},isObject=_index_681e4b07_js__WEBPACK_IMPORTED_MODULE_30__.x;var ColorSpace,throttle_1=function throttle(func,wait,options){var leading=!0,trailing=!0;if("function"!=typeof func)throw new TypeError("Expected a function");return isObject(options)&&(leading="leading"in options?!!options.leading:leading,trailing="trailing"in options?!!options.trailing:trailing),debounce(func,wait,{leading,maxWait:wait,trailing})},Wrapper=_storybook_theming__WEBPACK_IMPORTED_MODULE_31__.zo.div({position:"relative",maxWidth:250}),PickerTooltip=(0,_storybook_theming__WEBPACK_IMPORTED_MODULE_31__.zo)(_index_681e4b07_js__WEBPACK_IMPORTED_MODULE_30__.W)({position:"absolute",zIndex:1,top:4,left:4}),TooltipContent=_storybook_theming__WEBPACK_IMPORTED_MODULE_31__.zo.div({width:200,margin:5,".react-colorful__saturation":{borderRadius:"4px 4px 0 0"},".react-colorful__hue":{boxShadow:"inset 0 0 0 1px rgb(0 0 0 / 5%)"},".react-colorful__last-control":{borderRadius:"0 0 4px 4px"}}),Note=(0,_storybook_theming__WEBPACK_IMPORTED_MODULE_31__.zo)(_index_681e4b07_js__WEBPACK_IMPORTED_MODULE_30__.T)((function(_ref){return{fontFamily:_ref.theme.typography.fonts.base}})),Swatches=_storybook_theming__WEBPACK_IMPORTED_MODULE_31__.zo.div({display:"grid",gridTemplateColumns:"repeat(9, 16px)",gap:6,padding:3,marginTop:5,width:200}),SwatchColor=_storybook_theming__WEBPACK_IMPORTED_MODULE_31__.zo.div((function(_ref2){var theme=_ref2.theme;return{width:16,height:16,boxShadow:_ref2.active?"".concat(theme.appBorderColor," 0 0 0 1px inset, ").concat(theme.color.mediumdark,"50 0 0 0 4px"):"".concat(theme.appBorderColor," 0 0 0 1px inset"),borderRadius:theme.appBorderRadius}})),Swatch=function Swatch(_a){var value=_a.value,active=_a.active,onClick=_a.onClick,style=_a.style,props=(0,_index_681e4b07_js__WEBPACK_IMPORTED_MODULE_30__.d)(_a,["value","active","onClick","style"]),backgroundImage="linear-gradient(".concat(value,", ").concat(value,"), ").concat('url(\'data:image/svg+xml;charset=utf-8,\')',", linear-gradient(#fff, #fff)");return react__WEBPACK_IMPORTED_MODULE_26__.createElement(SwatchColor,Object.assign({},props,{active,onClick},{style:Object.assign(Object.assign({},style),{backgroundImage})}))},Input=(0,_storybook_theming__WEBPACK_IMPORTED_MODULE_31__.zo)(_index_681e4b07_js__WEBPACK_IMPORTED_MODULE_30__.F.Input)((function(_ref3){return{width:"100%",paddingLeft:30,paddingRight:30,boxSizing:"border-box",fontFamily:_ref3.theme.typography.fonts.base}})),ToggleIcon=(0,_storybook_theming__WEBPACK_IMPORTED_MODULE_31__.zo)(_index_681e4b07_js__WEBPACK_IMPORTED_MODULE_30__.I)((function(_ref4){return{position:"absolute",zIndex:1,top:6,right:7,width:20,height:20,padding:4,boxSizing:"border-box",cursor:"pointer",color:_ref4.theme.input.color}}));!function(ColorSpace){ColorSpace.RGB="rgb",ColorSpace.HSL="hsl",ColorSpace.HEX="hex"}(ColorSpace||(ColorSpace={}));var COLOR_SPACES=Object.values(ColorSpace),COLOR_REGEXP=/\(([0-9]+),\s*([0-9]+)%?,\s*([0-9]+)%?,?\s*([0-9.]+)?\)/,RGB_REGEXP=/^\s*rgba?\(([0-9]+),\s*([0-9]+),\s*([0-9]+),?\s*([0-9.]+)?\)\s*$/i,HSL_REGEXP=/^\s*hsla?\(([0-9]+),\s*([0-9]+)%,\s*([0-9]+)%,?\s*([0-9.]+)?\)\s*$/i,HEX_REGEXP=/^\s*#?([0-9a-f]{3}|[0-9a-f]{6})\s*$/i,SHORTHEX_REGEXP=/^\s*#?([0-9a-f]{3})\s*$/i,ColorPicker=(_defineProperty(_ColorPicker={},ColorSpace.HEX,(function J(r){return react__WEBPACK_IMPORTED_MODULE_26__.createElement($,u({},r,{colorModel:G}))})),_defineProperty(_ColorPicker,ColorSpace.RGB,(function pe(r){return react__WEBPACK_IMPORTED_MODULE_26__.createElement(U,u({},r,{colorModel:ge}))})),_defineProperty(_ColorPicker,ColorSpace.HSL,(function re(r){return react__WEBPACK_IMPORTED_MODULE_26__.createElement(U,u({},r,{colorModel:ee}))})),_ColorPicker),fallbackColor=(_defineProperty(_fallbackColor={},ColorSpace.HEX,"transparent"),_defineProperty(_fallbackColor,ColorSpace.RGB,"rgba(0, 0, 0, 0)"),_defineProperty(_fallbackColor,ColorSpace.HSL,"hsla(0, 0%, 0%, 0)"),_fallbackColor),stringToArgs=function stringToArgs(value){var match=null==value?void 0:value.match(COLOR_REGEXP);if(!match)return[0,0,0,1];var _match=_slicedToArray(match,5),x=_match[1],y=_match[2],z=_match[3],_match$=_match[4];return[x,y,z,void 0===_match$?1:_match$].map(Number)},parseValue=function parseValue(value){var _ref11;if(value){var valid=!0;if(RGB_REGEXP.test(value)){var _ref7,_stringToArgs2=_slicedToArray(stringToArgs(value),4),r=_stringToArgs2[0],_g=_stringToArgs2[1],_b=_stringToArgs2[2],a=_stringToArgs2[3],_ref6=_slicedToArray(colorConvert.rgb.hsl([r,_g,_b])||[0,0,0],3),_h=_ref6[0],_s2=_ref6[1],l=_ref6[2];return _defineProperty(_ref7={valid,value,keyword:colorConvert.rgb.keyword([r,_g,_b]),colorSpace:ColorSpace.RGB},ColorSpace.RGB,value),_defineProperty(_ref7,ColorSpace.HSL,"hsla(".concat(_h,", ").concat(_s2,"%, ").concat(l,"%, ").concat(a,")")),_defineProperty(_ref7,ColorSpace.HEX,"#".concat(colorConvert.rgb.hex([r,_g,_b]).toLowerCase())),_ref7}if(HSL_REGEXP.test(value)){var _ref10,_stringToArgs4=_slicedToArray(stringToArgs(value),4),_h2=_stringToArgs4[0],_s3=_stringToArgs4[1],_l=_stringToArgs4[2],_a2=_stringToArgs4[3],_ref9=_slicedToArray(colorConvert.hsl.rgb([_h2,_s3,_l])||[0,0,0],3),_r=_ref9[0],_g2=_ref9[1],_b2=_ref9[2];return _defineProperty(_ref10={valid,value,keyword:colorConvert.hsl.keyword([_h2,_s3,_l]),colorSpace:ColorSpace.HSL},ColorSpace.RGB,"rgba(".concat(_r,", ").concat(_g2,", ").concat(_b2,", ").concat(_a2,")")),_defineProperty(_ref10,ColorSpace.HSL,value),_defineProperty(_ref10,ColorSpace.HEX,"#".concat(colorConvert.hsl.hex([_h2,_s3,_l]).toLowerCase())),_ref10}var plain=value.replace("#",""),rgb=colorConvert.keyword.rgb(plain)||colorConvert.hex.rgb(plain),hsl=colorConvert.rgb.hsl(rgb),mapped=value;if(/[^#a-f0-9]/i.test(value)?mapped=plain:HEX_REGEXP.test(value)&&(mapped="#".concat(plain)),mapped.startsWith("#"))valid=HEX_REGEXP.test(mapped);else try{colorConvert.keyword.hex(mapped)}catch(e){valid=!1}return _defineProperty(_ref11={valid,value:mapped,keyword:colorConvert.rgb.keyword(rgb),colorSpace:ColorSpace.HEX},ColorSpace.RGB,"rgba(".concat(rgb[0],", ").concat(rgb[1],", ").concat(rgb[2],", 1)")),_defineProperty(_ref11,ColorSpace.HSL,"hsla(".concat(hsl[0],", ").concat(hsl[1],"%, ").concat(hsl[2],"%, 1)")),_defineProperty(_ref11,ColorSpace.HEX,mapped),_ref11}},useColorInput=function useColorInput(initialValue,onChange){var _useState2=_slicedToArray((0,react__WEBPACK_IMPORTED_MODULE_26__.useState)(initialValue||""),2),value=_useState2[0],setValue=_useState2[1],_useState4=_slicedToArray((0,react__WEBPACK_IMPORTED_MODULE_26__.useState)((function(){return parseValue(value)})),2),color=_useState4[0],setColor=_useState4[1],_useState6=_slicedToArray((0,react__WEBPACK_IMPORTED_MODULE_26__.useState)((null==color?void 0:color.colorSpace)||ColorSpace.HEX),2),colorSpace=_useState6[0],setColorSpace=_useState6[1];(0,react__WEBPACK_IMPORTED_MODULE_26__.useEffect)((function(){void 0===initialValue&&(setValue(""),setColor(void 0),setColorSpace(ColorSpace.HEX))}),[initialValue]);var realValue=(0,react__WEBPACK_IMPORTED_MODULE_26__.useMemo)((function(){return function getRealValue(value,color,colorSpace){if(!value||!(null==color?void 0:color.valid))return fallbackColor[colorSpace];if(colorSpace!==ColorSpace.HEX)return(null==color?void 0:color[colorSpace])||fallbackColor[colorSpace];if(!color.hex.startsWith("#"))try{return"#".concat(colorConvert.keyword.hex(color.hex))}catch(e){return fallbackColor.hex}var short=color.hex.match(SHORTHEX_REGEXP);if(!short)return HEX_REGEXP.test(color.hex)?color.hex:fallbackColor.hex;var _short$1$split2=_slicedToArray(short[1].split(""),3),r=_short$1$split2[0],g=_short$1$split2[1],b=_short$1$split2[2];return"#".concat(r).concat(r).concat(g).concat(g).concat(b).concat(b)}(value,color,colorSpace).toLowerCase()}),[value,color,colorSpace]),updateValue=(0,react__WEBPACK_IMPORTED_MODULE_26__.useCallback)((function(update){var parsed=parseValue(update);setValue((null==parsed?void 0:parsed.value)||update||""),parsed&&(setColor(parsed),setColorSpace(parsed.colorSpace),onChange(parsed.value))}),[onChange]),cycleColorSpace=(0,react__WEBPACK_IMPORTED_MODULE_26__.useCallback)((function(){var next=COLOR_SPACES.indexOf(colorSpace)+1;next>=COLOR_SPACES.length&&(next=0),setColorSpace(COLOR_SPACES[next]);var update=(null==color?void 0:color[COLOR_SPACES[next]])||"";setValue(update),onChange(update)}),[color,colorSpace,onChange]);return{value,realValue,updateValue,color,colorSpace,cycleColorSpace}},id=function id(value){return value.replace(/\s*/,"").toLowerCase()},ColorControl=function ColorControl(_ref12){var name=_ref12.name,initialValue=_ref12.value,onChange=_ref12.onChange,onFocus=_ref12.onFocus,onBlur=_ref12.onBlur,presetColors=_ref12.presetColors,startOpen=_ref12.startOpen,_useColorInput=useColorInput(initialValue,throttle_1(onChange,200)),value=_useColorInput.value,realValue=_useColorInput.realValue,updateValue=_useColorInput.updateValue,color=_useColorInput.color,colorSpace=_useColorInput.colorSpace,cycleColorSpace=_useColorInput.cycleColorSpace,_usePresets=function usePresets(presetColors,currentColor,colorSpace){var _useState8=_slicedToArray((0,react__WEBPACK_IMPORTED_MODULE_26__.useState)((null==currentColor?void 0:currentColor.valid)?[currentColor]:[]),2),selectedColors=_useState8[0],setSelectedColors=_useState8[1];(0,react__WEBPACK_IMPORTED_MODULE_26__.useEffect)((function(){void 0===currentColor&&setSelectedColors([])}),[currentColor]);var presets=(0,react__WEBPACK_IMPORTED_MODULE_26__.useMemo)((function(){return(presetColors||[]).map((function(preset){return"string"==typeof preset?parseValue(preset):preset.title?Object.assign(Object.assign({},parseValue(preset.color)),{keyword:preset.title}):parseValue(preset.color)})).concat(selectedColors).filter(Boolean).slice(-27)}),[presetColors,selectedColors]),addPreset=(0,react__WEBPACK_IMPORTED_MODULE_26__.useCallback)((function(color){(null==color?void 0:color.valid)&&(presets.some((function(preset){return id(preset[colorSpace])===id(color[colorSpace])}))||setSelectedColors((function(arr){return arr.concat(color)})))}),[colorSpace,presets]);return{presets,addPreset}}(presetColors,color,colorSpace),presets=_usePresets.presets,addPreset=_usePresets.addPreset,Picker=ColorPicker[colorSpace];return react__WEBPACK_IMPORTED_MODULE_26__.createElement(Wrapper,null,react__WEBPACK_IMPORTED_MODULE_26__.createElement(PickerTooltip,{trigger:"click",startOpen,closeOnClick:!0,onVisibilityChange:function onVisibilityChange(){return addPreset(color)},tooltip:react__WEBPACK_IMPORTED_MODULE_26__.createElement(TooltipContent,null,react__WEBPACK_IMPORTED_MODULE_26__.createElement(Picker,Object.assign({color:"transparent"===realValue?"#000000":realValue},{onChange:updateValue,onFocus,onBlur})),presets.length>0&&react__WEBPACK_IMPORTED_MODULE_26__.createElement(Swatches,null,presets.map((function(preset,index){return react__WEBPACK_IMPORTED_MODULE_26__.createElement(_index_681e4b07_js__WEBPACK_IMPORTED_MODULE_30__.W,{key:"".concat(preset.value,"-").concat(index),hasChrome:!1,tooltip:react__WEBPACK_IMPORTED_MODULE_26__.createElement(Note,{note:preset.keyword||preset.value})},react__WEBPACK_IMPORTED_MODULE_26__.createElement(Swatch,{value:preset[colorSpace],active:color&&id(preset[colorSpace])===id(color[colorSpace]),onClick:function onClick(){return updateValue(preset.value)}}))}))))},react__WEBPACK_IMPORTED_MODULE_26__.createElement(Swatch,{value:realValue,style:{margin:4}})),react__WEBPACK_IMPORTED_MODULE_26__.createElement(Input,{id:(0,_index_681e4b07_js__WEBPACK_IMPORTED_MODULE_30__.z)(name),value,onChange:function onChange(e){return updateValue(e.target.value)},onFocus:function onFocus(e){return e.target.select()},placeholder:"Choose color..."}),value?react__WEBPACK_IMPORTED_MODULE_26__.createElement(ToggleIcon,{icon:"markup",onClick:cycleColorSpace}):null)}}}]); -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naisutech/react-tree/7a4f725f66a29df1ea6d2aea0c19878904e9823b/docs/favicon.ico -------------------------------------------------------------------------------- /docs/iframe.html: -------------------------------------------------------------------------------- 1 | Webpack App

No Preview

Sorry, but you either have no stories or none are selected somehow.

  • Please check the Storybook config.
  • Try reloading the page.

If the problem persists, check the browser console, or the terminal you've run Storybook from.

-------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | Webpack App
-------------------------------------------------------------------------------- /docs/main.e0c86993c546a5eb3b5b.manager.bundle.js: -------------------------------------------------------------------------------- 1 | (self.webpackChunk_naisutech_react_tree=self.webpackChunk_naisutech_react_tree||[]).push([[179],{24654:()=>{}},__webpack_require__=>{var __webpack_exec__=moduleId=>__webpack_require__(__webpack_require__.s=moduleId);__webpack_require__.O(0,[177],(()=>(__webpack_exec__(30091),__webpack_exec__(33735),__webpack_exec__(78295),__webpack_exec__(15887),__webpack_exec__(59288),__webpack_exec__(10566),__webpack_exec__(50213),__webpack_exec__(75259),__webpack_exec__(57464),__webpack_exec__(10165),__webpack_exec__(13457),__webpack_exec__(35637))));__webpack_require__.O()}]); -------------------------------------------------------------------------------- /docs/project.json: -------------------------------------------------------------------------------- 1 | {"generatedAt":1666505022485,"builder":{"name":"webpack5"},"hasCustomBabel":false,"hasCustomWebpack":true,"hasStaticDirs":false,"hasStorybookEslint":true,"refCount":0,"packageManager":{"type":"yarn","version":"1.22.19"},"storybookVersion":"6.5.12","language":"typescript","storybookPackages":{"@storybook/addon-actions":{"version":"6.5.12"},"@storybook/builder-webpack5":{"version":"6.5.12"},"@storybook/manager-webpack5":{"version":"6.5.12"},"@storybook/react":{"version":"6.5.12"},"@storybook/testing-library":{"version":"0.0.13"},"eslint-plugin-storybook":{"version":"0.6.4"}},"framework":{"name":"react"},"addons":{"@storybook/addon-links":{"version":"6.5.12"},"@storybook/addon-essentials":{"version":"6.5.12"},"@storybook/addon-interactions":{"version":"6.5.12"}}} 2 | -------------------------------------------------------------------------------- /docs/runtime~main.36299d73.iframe.bundle.js: -------------------------------------------------------------------------------- 1 | (()=>{"use strict";var deferred,leafPrototypes,getProto,inProgress,__webpack_modules__={},__webpack_module_cache__={};function __webpack_require__(moduleId){var cachedModule=__webpack_module_cache__[moduleId];if(void 0!==cachedModule)return cachedModule.exports;var module=__webpack_module_cache__[moduleId]={id:moduleId,loaded:!1,exports:{}};return __webpack_modules__[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}__webpack_require__.m=__webpack_modules__,deferred=[],__webpack_require__.O=(result,chunkIds,fn,priority)=>{if(!chunkIds){var notFulfilled=1/0;for(i=0;i=priority)&&Object.keys(__webpack_require__.O).every((key=>__webpack_require__.O[key](chunkIds[j])))?chunkIds.splice(j--,1):(fulfilled=!1,priority0&&deferred[i-1][2]>priority;i--)deferred[i]=deferred[i-1];deferred[i]=[chunkIds,fn,priority]},__webpack_require__.n=module=>{var getter=module&&module.__esModule?()=>module.default:()=>module;return __webpack_require__.d(getter,{a:getter}),getter},getProto=Object.getPrototypeOf?obj=>Object.getPrototypeOf(obj):obj=>obj.__proto__,__webpack_require__.t=function(value,mode){if(1&mode&&(value=this(value)),8&mode)return value;if("object"==typeof value&&value){if(4&mode&&value.__esModule)return value;if(16&mode&&"function"==typeof value.then)return value}var ns=Object.create(null);__webpack_require__.r(ns);var def={};leafPrototypes=leafPrototypes||[null,getProto({}),getProto([]),getProto(getProto)];for(var current=2&mode&&value;"object"==typeof current&&!~leafPrototypes.indexOf(current);current=getProto(current))Object.getOwnPropertyNames(current).forEach((key=>def[key]=()=>value[key]));return def.default=()=>value,__webpack_require__.d(ns,def),ns},__webpack_require__.d=(exports,definition)=>{for(var key in definition)__webpack_require__.o(definition,key)&&!__webpack_require__.o(exports,key)&&Object.defineProperty(exports,key,{enumerable:!0,get:definition[key]})},__webpack_require__.f={},__webpack_require__.e=chunkId=>Promise.all(Object.keys(__webpack_require__.f).reduce(((promises,key)=>(__webpack_require__.f[key](chunkId,promises),promises)),[])),__webpack_require__.u=chunkId=>chunkId+"."+{51:"4834abe5",229:"4efcb577",273:"6ed48bcd",551:"a57b0b1f",701:"0be8a683",745:"81c2b425",807:"5f1ebcc4",897:"42824d67",935:"39164b0f"}[chunkId]+".iframe.bundle.js",__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=module=>((module=Object.create(module)).children||(module.children=[]),Object.defineProperty(module,"exports",{enumerable:!0,set:()=>{throw new Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+module.id)}}),module),__webpack_require__.o=(obj,prop)=>Object.prototype.hasOwnProperty.call(obj,prop),inProgress={},__webpack_require__.l=(url,done,key,chunkId)=>{if(inProgress[url])inProgress[url].push(done);else{var script,needAttach;if(void 0!==key)for(var scripts=document.getElementsByTagName("script"),i=0;i{script.onerror=script.onload=null,clearTimeout(timeout);var doneFns=inProgress[url];if(delete inProgress[url],script.parentNode&&script.parentNode.removeChild(script),doneFns&&doneFns.forEach((fn=>fn(event))),prev)return prev(event)},timeout=setTimeout(onScriptComplete.bind(null,void 0,{type:"timeout",target:script}),12e4);script.onerror=onScriptComplete.bind(null,script.onerror),script.onload=onScriptComplete.bind(null,script.onload),needAttach&&document.head.appendChild(script)}},__webpack_require__.r=exports=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.nmd=module=>(module.paths=[],module.children||(module.children=[]),module),__webpack_require__.p="",(()=>{var installedChunks={303:0};__webpack_require__.f.j=(chunkId,promises)=>{var installedChunkData=__webpack_require__.o(installedChunks,chunkId)?installedChunks[chunkId]:void 0;if(0!==installedChunkData)if(installedChunkData)promises.push(installedChunkData[2]);else if(303!=chunkId){var promise=new Promise(((resolve,reject)=>installedChunkData=installedChunks[chunkId]=[resolve,reject]));promises.push(installedChunkData[2]=promise);var url=__webpack_require__.p+__webpack_require__.u(chunkId),error=new Error;__webpack_require__.l(url,(event=>{if(__webpack_require__.o(installedChunks,chunkId)&&(0!==(installedChunkData=installedChunks[chunkId])&&(installedChunks[chunkId]=void 0),installedChunkData)){var errorType=event&&("load"===event.type?"missing":event.type),realSrc=event&&event.target&&event.target.src;error.message="Loading chunk "+chunkId+" failed.\n("+errorType+": "+realSrc+")",error.name="ChunkLoadError",error.type=errorType,error.request=realSrc,installedChunkData[1](error)}}),"chunk-"+chunkId,chunkId)}else installedChunks[chunkId]=0},__webpack_require__.O.j=chunkId=>0===installedChunks[chunkId];var webpackJsonpCallback=(parentChunkLoadingFunction,data)=>{var moduleId,chunkId,[chunkIds,moreModules,runtime]=data,i=0;if(chunkIds.some((id=>0!==installedChunks[id]))){for(moduleId in moreModules)__webpack_require__.o(moreModules,moduleId)&&(__webpack_require__.m[moduleId]=moreModules[moduleId]);if(runtime)var result=runtime(__webpack_require__)}for(parentChunkLoadingFunction&&parentChunkLoadingFunction(data);i{"use strict";var deferred,leafPrototypes,getProto,inProgress,__webpack_modules__={},__webpack_module_cache__={};function __webpack_require__(moduleId){var cachedModule=__webpack_module_cache__[moduleId];if(void 0!==cachedModule)return cachedModule.exports;var module=__webpack_module_cache__[moduleId]={id:moduleId,loaded:!1,exports:{}};return __webpack_modules__[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}__webpack_require__.m=__webpack_modules__,deferred=[],__webpack_require__.O=(result,chunkIds,fn,priority)=>{if(!chunkIds){var notFulfilled=1/0;for(i=0;i=priority)&&Object.keys(__webpack_require__.O).every((key=>__webpack_require__.O[key](chunkIds[j])))?chunkIds.splice(j--,1):(fulfilled=!1,priority0&&deferred[i-1][2]>priority;i--)deferred[i]=deferred[i-1];deferred[i]=[chunkIds,fn,priority]},__webpack_require__.n=module=>{var getter=module&&module.__esModule?()=>module.default:()=>module;return __webpack_require__.d(getter,{a:getter}),getter},getProto=Object.getPrototypeOf?obj=>Object.getPrototypeOf(obj):obj=>obj.__proto__,__webpack_require__.t=function(value,mode){if(1&mode&&(value=this(value)),8&mode)return value;if("object"==typeof value&&value){if(4&mode&&value.__esModule)return value;if(16&mode&&"function"==typeof value.then)return value}var ns=Object.create(null);__webpack_require__.r(ns);var def={};leafPrototypes=leafPrototypes||[null,getProto({}),getProto([]),getProto(getProto)];for(var current=2&mode&&value;"object"==typeof current&&!~leafPrototypes.indexOf(current);current=getProto(current))Object.getOwnPropertyNames(current).forEach((key=>def[key]=()=>value[key]));return def.default=()=>value,__webpack_require__.d(ns,def),ns},__webpack_require__.d=(exports,definition)=>{for(var key in definition)__webpack_require__.o(definition,key)&&!__webpack_require__.o(exports,key)&&Object.defineProperty(exports,key,{enumerable:!0,get:definition[key]})},__webpack_require__.f={},__webpack_require__.e=chunkId=>Promise.all(Object.keys(__webpack_require__.f).reduce(((promises,key)=>(__webpack_require__.f[key](chunkId,promises),promises)),[])),__webpack_require__.u=chunkId=>chunkId+"."+{51:"7070d385b30a646ee70e",229:"17d4ab2f2fe53489353e",295:"086f3c94c9e023c3caff",551:"40dddcc29c80ee6a1cee",807:"b6c07b84a21e65368b97",897:"9ce4e971c3718f12eeb4",935:"eff965ec22feacd9e876"}[chunkId]+".manager.bundle.js",__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.hmd=module=>((module=Object.create(module)).children||(module.children=[]),Object.defineProperty(module,"exports",{enumerable:!0,set:()=>{throw new Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+module.id)}}),module),__webpack_require__.o=(obj,prop)=>Object.prototype.hasOwnProperty.call(obj,prop),inProgress={},__webpack_require__.l=(url,done,key,chunkId)=>{if(inProgress[url])inProgress[url].push(done);else{var script,needAttach;if(void 0!==key)for(var scripts=document.getElementsByTagName("script"),i=0;i{script.onerror=script.onload=null,clearTimeout(timeout);var doneFns=inProgress[url];if(delete inProgress[url],script.parentNode&&script.parentNode.removeChild(script),doneFns&&doneFns.forEach((fn=>fn(event))),prev)return prev(event)},timeout=setTimeout(onScriptComplete.bind(null,void 0,{type:"timeout",target:script}),12e4);script.onerror=onScriptComplete.bind(null,script.onerror),script.onload=onScriptComplete.bind(null,script.onload),needAttach&&document.head.appendChild(script)}},__webpack_require__.r=exports=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.nmd=module=>(module.paths=[],module.children||(module.children=[]),module),__webpack_require__.p="",(()=>{var installedChunks={303:0};__webpack_require__.f.j=(chunkId,promises)=>{var installedChunkData=__webpack_require__.o(installedChunks,chunkId)?installedChunks[chunkId]:void 0;if(0!==installedChunkData)if(installedChunkData)promises.push(installedChunkData[2]);else if(303!=chunkId){var promise=new Promise(((resolve,reject)=>installedChunkData=installedChunks[chunkId]=[resolve,reject]));promises.push(installedChunkData[2]=promise);var url=__webpack_require__.p+__webpack_require__.u(chunkId),error=new Error;__webpack_require__.l(url,(event=>{if(__webpack_require__.o(installedChunks,chunkId)&&(0!==(installedChunkData=installedChunks[chunkId])&&(installedChunks[chunkId]=void 0),installedChunkData)){var errorType=event&&("load"===event.type?"missing":event.type),realSrc=event&&event.target&&event.target.src;error.message="Loading chunk "+chunkId+" failed.\n("+errorType+": "+realSrc+")",error.name="ChunkLoadError",error.type=errorType,error.request=realSrc,installedChunkData[1](error)}}),"chunk-"+chunkId,chunkId)}else installedChunks[chunkId]=0},__webpack_require__.O.j=chunkId=>0===installedChunks[chunkId];var webpackJsonpCallback=(parentChunkLoadingFunction,data)=>{var moduleId,chunkId,[chunkIds,moreModules,runtime]=data,i=0;if(chunkIds.some((id=>0!==installedChunks[id]))){for(moduleId in moreModules)__webpack_require__.o(moreModules,moduleId)&&(__webpack_require__.m[moduleId]=moreModules[moduleId]);if(runtime)var result=runtime(__webpack_require__)}for(parentChunkLoadingFunction&&parentChunkLoadingFunction(data);i", 10 | "license": "MIT", 11 | "private": false, 12 | "dependencies": { 13 | "@emotion/is-prop-valid": "^1.2.0", 14 | "nanoid": "^4.0.0", 15 | "react-draggable": "^4.4.5" 16 | }, 17 | "peerDependencies": { 18 | "react": "^18.2.0", 19 | "react-dom": "^18.2.0", 20 | "styled-components": "^5.3.6" 21 | }, 22 | "devDependencies": { 23 | "@babel/core": "^7.19.3", 24 | "@babel/preset-env": "^7.19.3", 25 | "@babel/preset-react": "^7.18.6", 26 | "@babel/preset-typescript": "^7.18.6", 27 | "@rollup/plugin-commonjs": "^22.0.2", 28 | "@rollup/plugin-node-resolve": "^14.1.0", 29 | "@rollup/plugin-typescript": "^8.5.0", 30 | "@storybook/addon-actions": "^6.5.12", 31 | "@storybook/addon-essentials": "^6.5.12", 32 | "@storybook/addon-interactions": "^6.5.12", 33 | "@storybook/addon-links": "^6.5.12", 34 | "@storybook/builder-webpack5": "^6.5.12", 35 | "@storybook/manager-webpack5": "^6.5.12", 36 | "@storybook/react": "^6.5.12", 37 | "@storybook/testing-library": "^0.0.13", 38 | "@svgr/rollup": "^6.3.1", 39 | "@svgr/webpack": "^6.3.1", 40 | "@testing-library/react": "^13.4.0", 41 | "@types/jest": "^29.1.0", 42 | "@types/node": "^18.7.23", 43 | "@types/react": "^18.0.21", 44 | "@types/react-test-renderer": "^18.0.0", 45 | "@types/styled-components": "^5.1.26", 46 | "@typescript-eslint/eslint-plugin": "^5.38.1", 47 | "@typescript-eslint/parser": "^5.38.1", 48 | "babel-jest": "^29.1.0", 49 | "babel-loader": "^8.2.5", 50 | "eslint": "^8.24.0", 51 | "eslint-config-prettier": "^8.5.0", 52 | "eslint-plugin-react": "^7.31.8", 53 | "eslint-plugin-storybook": "^0.6.4", 54 | "framer-motion": "^7.5.0", 55 | "husky": "^8.0.1", 56 | "jest": "^29.1.1", 57 | "prettier": "^2.7.1", 58 | "react": "^18.2.0", 59 | "react-dom": "^18.2.0", 60 | "rollup": "^2.79.1", 61 | "rollup-plugin-clear": "^2.0.7", 62 | "rollup-plugin-dts": "^4.2.2", 63 | "rollup-plugin-graph": "^2.0.0", 64 | "rollup-plugin-peer-deps-external": "^2.2.4", 65 | "rollup-plugin-progress": "^1.1.2", 66 | "rollup-plugin-size-snapshot": "^0.12.0", 67 | "rollup-plugin-svg": "^2.0.0", 68 | "rollup-plugin-terser": "^7.0.2", 69 | "styled-components": "^5.3.6", 70 | "svg-inline-loader": "^0.8.2", 71 | "tslib": "^2.4.0", 72 | "typescript": "^4.8.4", 73 | "watch": "^1.0.2", 74 | "yarn": "^1.22.19" 75 | }, 76 | "scripts": { 77 | "test": "jest", 78 | "build": "NODE_ENV=production rm -rf ./js && tsc -p tsconfig.build.json && yarn copy-files && rollup -c", 79 | "build-windows": "call buildWindows.bat", 80 | "watch": "watch 'yarn build' ./src", 81 | "copy-files": "cp ./src/assets/images/*.svg ./js/assets/images", 82 | "copy-files-windows": "copy .\\src\\assets\\images\\*.svg .\\js\\assets\\images", 83 | "storybook": "start-storybook -p 6006", 84 | "build-storybook": "build-storybook -o ./docs" 85 | }, 86 | "keywords": [ 87 | "react", 88 | "tree", 89 | "hierarchy", 90 | "folder", 91 | "list" 92 | ], 93 | "jest": { 94 | "testEnvironment": "jsdom", 95 | "moduleDirectories": [ 96 | "node_modules" 97 | ] 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import commonjs from '@rollup/plugin-commonjs' 2 | import peerDepsExternal from 'rollup-plugin-peer-deps-external' 3 | import { nodeResolve } from '@rollup/plugin-node-resolve' 4 | import { terser } from 'rollup-plugin-terser' 5 | import clear from 'rollup-plugin-clear' 6 | import { sizeSnapshot } from 'rollup-plugin-size-snapshot' 7 | import graph from 'rollup-plugin-graph' 8 | import progress from 'rollup-plugin-progress' 9 | import svgr from '@svgr/rollup' 10 | import pkg from './package.json' 11 | let graphOptions = { prune: true } 12 | 13 | const universalConfig = { 14 | input: 'js/index.js', 15 | plugins: [ 16 | clear({ 17 | targets: ['dist'] 18 | }), 19 | peerDepsExternal(), 20 | nodeResolve({ extensions: ['.js', '.svg'] }), 21 | commonjs(), 22 | graph(graphOptions), 23 | sizeSnapshot(), 24 | terser(), 25 | progress(), 26 | svgr({ 27 | svgoConfig: { 28 | plugins: [] 29 | } 30 | }) 31 | ] 32 | } 33 | 34 | const umd = { 35 | ...universalConfig, 36 | output: { 37 | file: 'dist/index.umd.js', 38 | format: 'umd', 39 | sourcemap: true, 40 | exports: 'auto', 41 | globals: { react: 'React', 'styled-components': 'styled' }, 42 | name: 'ReactTree' 43 | } 44 | } 45 | 46 | const es = { 47 | ...universalConfig, 48 | output: { 49 | file: pkg.module, 50 | format: 'esm', 51 | sourcemap: true, 52 | exports: 'auto' 53 | } 54 | } 55 | 56 | const cjs = { 57 | ...universalConfig, 58 | output: { 59 | file: pkg.main, 60 | format: 'cjs', 61 | sourcemap: true, 62 | exports: 'auto' 63 | } 64 | } 65 | 66 | export default [umd, es, cjs] 67 | -------------------------------------------------------------------------------- /src/Tree.ts: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { TReactTreeContext } from 'Tree/Context' 3 | 4 | /** 5 | * @public 6 | */ 7 | export declare type TreeNodeId = number | string 8 | 9 | /** 10 | * @public 11 | */ 12 | export declare interface TreeNode { 13 | id: TreeNodeId 14 | parentId: TreeNodeId | null 15 | label?: string 16 | items?: TreeNodeList | null 17 | } 18 | 19 | /** 20 | * @public 21 | */ 22 | export declare type TreeNodeList = TreeNode[] 23 | 24 | export declare type TreeRenderFn = ({ 25 | node, 26 | type, 27 | selected = false, 28 | open = false, 29 | Icon, 30 | context 31 | }: { 32 | node: TreeNode 33 | type: 'leaf' | 'node' | 'loader' 34 | selected: boolean 35 | open?: boolean 36 | Icon?: React.ReactNode 37 | context: TReactTreeContext 38 | }) => React.ReactNode 39 | 40 | /** 41 | * @public 42 | */ 43 | export declare interface ReactTreeTheme { 44 | text?: { 45 | fontSize?: SizeUnit | CSSUnit 46 | fontFamily?: string 47 | color?: string 48 | selectedColor?: string 49 | hoverColor?: string 50 | } 51 | nodes?: { 52 | height?: CSSUnit 53 | folder?: { 54 | bgColor?: string 55 | selectedBgColor?: string 56 | hoverBgColor?: string 57 | } 58 | leaf?: { 59 | bgColor?: string 60 | selectedBgColor?: string 61 | hoverBgColor?: string 62 | } 63 | separator?: { 64 | border?: string 65 | borderColor?: string 66 | } 67 | icons?: { 68 | size?: CSSUnit 69 | folderColor?: string 70 | leafColor?: string 71 | } 72 | } 73 | } 74 | 75 | /** 76 | * @public 77 | */ 78 | export declare interface ThemeSettings { 79 | [key: string]: ReactTreeTheme 80 | } 81 | 82 | type CSSNumber = number 83 | 84 | /** 85 | * @public 86 | */ 87 | export declare type CSSUnit = 88 | | `${CSSNumber}rem` 89 | | `${CSSNumber}em` 90 | | `${CSSNumber}px` 91 | 92 | /** 93 | * @public 94 | */ 95 | export declare type SizeUnit = 'xs' | 'sm' | 'std' | 'lg' | 'xl' 96 | -------------------------------------------------------------------------------- /src/Tree/Context.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { TreeNodeId, TreeNodeList } from 'Tree' 3 | 4 | /** 5 | * @public 6 | */ 7 | export declare interface ReactTreeApi { 8 | getOpenNodes: () => (number | string)[] 9 | getSelectedNodes: () => (number | string)[] 10 | toggleNodeSelectedState: (node: string | number) => void 11 | toggleNodeOpenState: (node: string | number) => void 12 | toggleAllNodesOpenState: (state: 'open' | 'closed') => void 13 | toggleAllNodesSelectedState: (state: 'selected' | 'unselected') => void 14 | toggleOpenNodes: (nodes: (number | string)[]) => void 15 | toggleOpenClosedNodes: (nodes: (number | string)[]) => void 16 | toggleClosedNodes: (nodes: (number | string)[]) => void 17 | selectNodes: (nodes: (number | string)[]) => void 18 | deselectNodes: (nodes: (number | string)[]) => void 19 | toggleSelectedNodes: (nodes: (number | string)[]) => void 20 | onToggleOpenNodes?: (nodes: TreeNodeId[]) => void 21 | onToggleSelectedNodes?: (nodes: TreeNodeId[]) => void 22 | } 23 | 24 | export interface ReactTreeState { 25 | nodes: TreeNodeList 26 | selectedNodes: TreeNodeId[] 27 | openNodes: TreeNodeId[] 28 | controlledOpen: boolean 29 | controlledSelected: boolean 30 | options: { 31 | folderAnimations: boolean 32 | indicatorAnimations: boolean 33 | lazy: boolean 34 | showEmptyItems: boolean 35 | noIcons: boolean 36 | truncateLongText: boolean 37 | multiSelect: boolean 38 | messages: { 39 | noData?: React.ReactNode 40 | loading?: React.ReactNode 41 | emptyItems?: React.ReactNode 42 | } 43 | } 44 | theme: string 45 | } 46 | 47 | export type TReactTreeContext = ReactTreeState & ReactTreeApi 48 | 49 | const _ReactTreeContext = React.createContext({ 50 | nodes: [], 51 | selectedNodes: [], 52 | openNodes: [], 53 | controlledOpen: false, 54 | controlledSelected: false, 55 | options: { 56 | folderAnimations: false, 57 | indicatorAnimations: false, 58 | showEmptyItems: false, 59 | noIcons: false, 60 | lazy: false, 61 | truncateLongText: false, 62 | multiSelect: false, 63 | messages: { 64 | loading: 'Loading...', 65 | noData: 'No data to render 😔', 66 | emptyItems: '[Empty]' 67 | } 68 | }, 69 | theme: 'light', 70 | getOpenNodes: () => [], 71 | getSelectedNodes: () => [], 72 | toggleNodeSelectedState: () => {}, 73 | toggleNodeOpenState: () => {}, 74 | toggleAllNodesOpenState: () => {}, 75 | toggleAllNodesSelectedState: () => {}, 76 | toggleOpenNodes: () => {}, 77 | toggleClosedNodes: () => {}, 78 | toggleOpenClosedNodes: () => {}, 79 | selectNodes: () => {}, 80 | deselectNodes: () => {}, 81 | toggleSelectedNodes: () => {}, 82 | onToggleOpenNodes: () => {}, 83 | onToggleSelectedNodes: () => {} 84 | }) 85 | 86 | const ReactTreeContextProvider = ({ 87 | children, 88 | nodes = [], 89 | defaultSelectedNodes, 90 | defaultOpenNodes, 91 | selectedNodes, 92 | openNodes, 93 | options = { 94 | folderAnimations: false, 95 | indicatorAnimations: false, 96 | lazy: false, 97 | showEmptyItems: false, 98 | noIcons: false, 99 | truncateLongText: false, 100 | messages: { 101 | loading: 'Loading...', 102 | noData: 'No data to render 😔', 103 | emptyItems: '[Empty]' 104 | } 105 | }, 106 | theme = 'light', 107 | apiRef, 108 | onToggleOpenNodes = () => {}, 109 | onToggleSelectedNodes = () => {} 110 | }: React.PropsWithChildren<{ 111 | nodes?: TreeNodeList 112 | defaultSelectedNodes?: TreeNodeId[] 113 | defaultOpenNodes?: TreeNodeId[] 114 | openNodes?: TreeNodeId[] 115 | selectedNodes?: TreeNodeId[] 116 | options?: { 117 | folderAnimations?: boolean 118 | indicatorAnimations?: boolean 119 | lazy?: boolean 120 | showEmptyItems?: boolean 121 | noIcons?: boolean 122 | truncateLongText?: boolean 123 | multiSelect?: boolean 124 | messages?: { 125 | noData?: React.ReactNode 126 | loading?: React.ReactNode 127 | emptyItems?: React.ReactNode 128 | } 129 | } 130 | theme: string 131 | apiRef?: React.MutableRefObject 132 | onToggleOpenNodes?: (nodes: TreeNodeId[]) => void 133 | onToggleSelectedNodes?: (nodes: TreeNodeId[]) => void 134 | }>) => { 135 | const [nodeList, setTreeNodeList] = React.useState(nodes) 136 | const [_selectedNodes, setSelectedNodes] = React.useState( 137 | defaultSelectedNodes || selectedNodes || [] 138 | ) 139 | const [_openNodes, setOpenNodes] = React.useState( 140 | defaultOpenNodes || openNodes || [] 141 | ) 142 | 143 | const [controlledOpen] = React.useState(() => { 144 | if (defaultOpenNodes) return false 145 | if (openNodes) return true 146 | return false 147 | }) 148 | 149 | const [controlledSelected] = React.useState(() => { 150 | if (defaultSelectedNodes) return false 151 | if (selectedNodes) return true 152 | return false 153 | }) 154 | 155 | const [treeConfig, setTreeConfig] = React.useState<{ 156 | folderAnimations: boolean 157 | indicatorAnimations: boolean 158 | lazy: boolean 159 | showEmptyItems: boolean 160 | noIcons: boolean 161 | truncateLongText: boolean 162 | multiSelect: boolean 163 | messages: { 164 | noData: React.ReactNode 165 | loading: React.ReactNode 166 | emptyItems: React.ReactNode 167 | } 168 | }>({ 169 | folderAnimations: options?.folderAnimations || false, 170 | indicatorAnimations: options?.indicatorAnimations || false, 171 | lazy: options.lazy || false, 172 | showEmptyItems: options.showEmptyItems || false, 173 | noIcons: options.noIcons || false, 174 | truncateLongText: options.truncateLongText || false, 175 | multiSelect: options.multiSelect || false, 176 | messages: { 177 | loading: options.messages?.loading || 'Loading...', 178 | noData: options.messages?.noData || 'No data to render 😔', 179 | emptyItems: options.messages?.emptyItems || '[Empty]' 180 | } 181 | }) 182 | 183 | // define API methods 184 | const treeApi = React.useMemo(() => { 185 | return { 186 | getOpenNodes: () => _openNodes, 187 | getSelectedNodes: () => _selectedNodes, 188 | toggleNodeSelectedState: (nodeId: TreeNodeId) => { 189 | setSelectedNodes(nodes => { 190 | const _nodes = nodes.slice() 191 | const i = _nodes.indexOf(nodeId) 192 | if (i !== -1) { 193 | _nodes.splice(i, 1) 194 | } else { 195 | _nodes.push(nodeId) 196 | } 197 | return _nodes 198 | }) 199 | }, 200 | toggleNodeOpenState: (nodeId: TreeNodeId) => { 201 | setOpenNodes(nodes => { 202 | const _nodes = nodes.slice() 203 | const i = _nodes.indexOf(nodeId) 204 | if (i !== -1) { 205 | _nodes.splice(i, 1) 206 | } else { 207 | _nodes.push(nodeId) 208 | } 209 | return _nodes 210 | }) 211 | }, 212 | toggleAllNodesOpenState: (state: 'open' | 'closed') => { 213 | const list = state === 'open' ? nodeList.map(n => n.id) : [] 214 | setOpenNodes(list) 215 | }, 216 | toggleAllNodesSelectedState: (state: 'selected' | 'unselected') => { 217 | const list = 218 | state === 'selected' 219 | ? nodeList 220 | .map(n => n.id) 221 | .concat(nodeList.flatMap(n => n.items || []).map(n => n.id)) 222 | : [] 223 | setSelectedNodes(list) 224 | }, 225 | toggleOpenNodes: (nodes: TreeNodeId[]) => { 226 | setOpenNodes(nList => { 227 | return Array.from(new Set(nList.concat(nodes))) 228 | }) 229 | }, 230 | toggleClosedNodes: (nodes: TreeNodeId[]) => { 231 | setOpenNodes(nList => { 232 | return nList.filter(n => !nodes.includes(n)) 233 | }) 234 | }, 235 | toggleOpenClosedNodes: (nodes: TreeNodeId[]) => { 236 | setOpenNodes(nodes) 237 | }, 238 | selectNodes: (nodes: TreeNodeId[]) => { 239 | setSelectedNodes(nList => { 240 | return Array.from(new Set(nList.concat(nodes))) 241 | }) 242 | }, 243 | deselectNodes: (nodes: TreeNodeId[]) => { 244 | setSelectedNodes(nList => { 245 | return nList.filter(n => !nodes.includes(n)) 246 | }) 247 | }, 248 | toggleSelectedNodes: (nodes: TreeNodeId[]) => { 249 | setSelectedNodes(nodes) 250 | } 251 | } 252 | }, [nodeList, _openNodes, _selectedNodes]) 253 | 254 | // provide external access to API 255 | React.useImperativeHandle(apiRef, () => treeApi) 256 | 257 | React.useEffect(() => { 258 | setTreeNodeList(nodes) 259 | }, [nodes]) 260 | 261 | // handle controlled component states 262 | React.useEffect(() => { 263 | if (!openNodes) return 264 | setOpenNodes(openNodes) 265 | }, [openNodes]) 266 | 267 | React.useEffect(() => { 268 | if (!selectedNodes) return 269 | setSelectedNodes(selectedNodes) 270 | }, [selectedNodes]) 271 | 272 | // handle event listeners 273 | React.useEffect(() => { 274 | onToggleOpenNodes(_openNodes) 275 | }, [_openNodes]) 276 | 277 | React.useEffect(() => { 278 | onToggleSelectedNodes(_selectedNodes) 279 | }, [_selectedNodes]) 280 | 281 | React.useEffect(() => { 282 | setTreeConfig({ 283 | folderAnimations: options?.folderAnimations || false, 284 | indicatorAnimations: options?.indicatorAnimations || false, 285 | lazy: options.lazy || false, 286 | showEmptyItems: options.showEmptyItems || false, 287 | noIcons: options.noIcons || false, 288 | truncateLongText: options.truncateLongText || false, 289 | multiSelect: options.multiSelect || false, 290 | messages: { 291 | loading: options.messages?.loading || 'Loading...', 292 | noData: options.messages?.noData || 'No data to render 😔', 293 | emptyItems: options.messages?.emptyItems || '[Empty]' 294 | } 295 | }) 296 | }, [options]) 297 | 298 | const value = React.useMemo(() => { 299 | return { 300 | nodes: nodeList, 301 | selectedNodes: _selectedNodes, 302 | openNodes: _openNodes, 303 | controlledOpen, 304 | controlledSelected, 305 | options: treeConfig, 306 | theme, 307 | ...treeApi, 308 | onToggleOpenNodes, 309 | onToggleSelectedNodes 310 | } 311 | }, [ 312 | nodes, 313 | _selectedNodes, 314 | _openNodes, 315 | controlledOpen, 316 | controlledSelected, 317 | theme, 318 | treeApi, 319 | onToggleOpenNodes, 320 | onToggleSelectedNodes 321 | ]) 322 | 323 | return ( 324 | <_ReactTreeContext.Provider value={value}> 325 | {children} 326 | 327 | ) 328 | } 329 | 330 | const useReactTreeContext = () => React.useContext(_ReactTreeContext) 331 | 332 | const ReactTreeContext = { 333 | Provider: ReactTreeContextProvider, 334 | Consumer: _ReactTreeContext.Consumer, 335 | useReactTreeContext 336 | } 337 | 338 | export default ReactTreeContext 339 | -------------------------------------------------------------------------------- /src/Tree/Elements.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | import { motion } from 'framer-motion' 3 | import { CSSUnit } from 'Tree' 4 | 5 | export const TruncatedNodeText = styled(motion.span)` 6 | white-space: nowrap; 7 | text-overflow: ellipsis; 8 | overflow-x: hidden; 9 | ` 10 | 11 | export const UniversalNodeContainer = styled(motion.div)<{ 12 | $selected?: boolean 13 | $indent?: number 14 | $truncateLongText?: boolean 15 | }>` 16 | display: flex; 17 | flex-direction: column; 18 | padding-left: ${({ $indent }) => `calc(${$indent || 0} * 1rem)`}; 19 | ${({ $truncateLongText }) => 20 | $truncateLongText 21 | ? ` 22 | overflow-x: hidden; 23 | min-width: 0; 24 | 25 | ` 26 | : ``} 27 | ` 28 | 29 | export const UniversalNode = styled(UniversalNodeContainer)<{ 30 | $height?: CSSUnit 31 | $border?: string 32 | $borderColor?: string 33 | $backgroundColor?: string 34 | $selected?: boolean | null 35 | $selectedBgColor?: string 36 | $hoverColor?: string | null 37 | }>` 38 | flex-direction: row; 39 | align-items: center; 40 | height: ${({ $height }) => $height || 'initial'}; 41 | ${({ $backgroundColor }) => { 42 | return `background-color: ${$backgroundColor || 'initial'};` 43 | }}; 44 | border-top: ${({ $border }) => $border || '1px solid'}; 45 | border-top-color: ${({ $borderColor }) => $borderColor || 'transparent'}; 46 | ${({ $selected, $selectedBgColor }) => { 47 | return $selected && $selectedBgColor 48 | ? `background-color: ${$selectedBgColor || 'initial'}` 49 | : '' 50 | }}; 51 | 52 | ${({ $hoverColor }) => { 53 | return $hoverColor 54 | ? ` 55 | &:hover { 56 | cursor: pointer; 57 | background-color: ${$hoverColor || 'initial'}; 58 | } 59 | ` 60 | : `` 61 | }} 62 | ` 63 | 64 | export const RowBlock = styled(motion.div)<{ 65 | $truncateLongText?: boolean 66 | }>(({ $truncateLongText }) => [ 67 | `display: flex;`, 68 | `flex-direction: row;`, 69 | $truncateLongText ? `overflow-x: hidden; min-width: 0;` : `` 70 | ]) 71 | 72 | export const ColumnBlock = styled(RowBlock)(() => [`flex-direction: column;`]) 73 | 74 | export const TextBlock = styled(motion.p)<{ 75 | $color?: string 76 | $selected?: boolean 77 | $selectedColor?: string | null 78 | $hoverColor?: string | null 79 | $truncateLongText?: boolean 80 | }>(({ $color, $hoverColor, $selected, $selectedColor, $truncateLongText }) => [ 81 | `padding: 0;`, 82 | `margin: 0;`, 83 | `color: ${$color || 'initial'};`, 84 | $selected && $selectedColor ? `color: ${$selectedColor || 'initial'};` : ``, 85 | $hoverColor 86 | ? `&:hover { 87 | color: ${$hoverColor}; 88 | }` 89 | : ``, 90 | $truncateLongText 91 | ? ` 92 | overflow-x: hidden; 93 | text-overflow: ellipsis; 94 | white-space: nowrap; 95 | ` 96 | : `` 97 | ]) 98 | 99 | export const TextFragment = styled(TextBlock).attrs({ as: 'span' })(() => []) 100 | 101 | export const IconBlock = styled(motion.span)<{ 102 | $size?: string 103 | $color?: string 104 | }>(({ $size, $color }) => [ 105 | `display: flex;`, 106 | `flex-direction: column;`, 107 | `align-items: center;`, 108 | `justify-content: center;`, 109 | `width: ${$size || '1rem'};`, 110 | `height: ${$size || '1rem'};`, 111 | `svg { 112 | width: 100%; 113 | height: 100%; 114 | & * { 115 | fill: ${$color}; 116 | stroke: ${$color}; 117 | } 118 | }` 119 | ]) 120 | -------------------------------------------------------------------------------- /src/Tree/Nodes.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { useTheme } from 'styled-components' 3 | import Icons from '../assets/images/Icons' 4 | import { TreeNodeId, TreeRenderFn } from 'Tree' 5 | import ReactTreeContext from './Context' 6 | import { 7 | IconBlock, 8 | RowBlock, 9 | TextBlock, 10 | UniversalNode, 11 | UniversalNodeContainer 12 | } from './Elements' 13 | 14 | // AnyNode is used recursively to render the tree 15 | export const AnyNode = ({ 16 | parentId = null, 17 | depth = 0, 18 | RenderNode, 19 | RenderIcon 20 | }: { 21 | parentId?: TreeNodeId | null 22 | depth?: number 23 | RenderNode?: TreeRenderFn 24 | RenderIcon?: TreeRenderFn 25 | }) => { 26 | const themeList = useTheme() 27 | // import all nodes 28 | const treeContext = ReactTreeContext.useReactTreeContext() 29 | const { 30 | nodes, 31 | openNodes, 32 | selectedNodes, 33 | controlledOpen, 34 | controlledSelected, 35 | theme, 36 | options: appOptions, 37 | toggleNodeOpenState, 38 | toggleSelectedNodes, 39 | onToggleOpenNodes, 40 | onToggleSelectedNodes 41 | } = treeContext 42 | 43 | // each node will calculate it's own set of open and selected nodes and children 44 | const theseNodes = React.useMemo(() => { 45 | return nodes.filter(n => n.parentId === parentId) 46 | }, [nodes]) 47 | 48 | const theseNodesOpen = React.useMemo(() => { 49 | return theseNodes.map(n => openNodes.includes(n.id)) 50 | }, [openNodes]) 51 | 52 | const theseNodesSelected = React.useMemo(() => { 53 | return theseNodes.map(n => selectedNodes.includes(n.id)) 54 | }, [selectedNodes]) 55 | 56 | const theseItemsSelected = React.useMemo(() => { 57 | return theseNodes.map(n => { 58 | if (!n.items) return [] as boolean[] // no items 59 | return n.items.map(i => selectedNodes.includes(i.id)) // which ones are selected 60 | }) 61 | }, [selectedNodes]) 62 | 63 | // check if user want to render their own icon 64 | const NodeIcon = React.useMemo(() => { 65 | if (RenderIcon && typeof RenderIcon === 'function') { 66 | return RenderIcon 67 | } 68 | return Icons.node 69 | }, [RenderIcon]) 70 | 71 | const LeafIcon = React.useMemo(() => { 72 | if (RenderIcon && typeof RenderIcon === 'function') { 73 | return RenderIcon 74 | } 75 | return Icons.file 76 | }, [RenderIcon]) 77 | 78 | const handleToggleOpenNode = React.useCallback((nodeId: TreeNodeId) => { 79 | if (controlledOpen) { 80 | if (onToggleOpenNodes) onToggleOpenNodes([nodeId]) 81 | return 82 | } 83 | toggleNodeOpenState(nodeId) 84 | }, []) 85 | 86 | // only one handler needed here that isn't a direct use of the API 87 | // which is keyboard modified selection 88 | const handleToggleSelectedNode = React.useCallback( 89 | ( 90 | event: React.MouseEvent, 91 | nodeId: TreeNodeId 92 | ) => { 93 | let nodeSet: TreeNodeId[] = [] 94 | 95 | // include already selected if modified key pressed (multiselect) 96 | if (appOptions.multiSelect && (event.ctrlKey || event.metaKey)) { 97 | nodeSet.push(...selectedNodes.filter(n => n !== nodeId)) 98 | } 99 | 100 | // exclude already selected (toggle) 101 | if (!selectedNodes.includes(nodeId)) nodeSet.push(nodeId) 102 | 103 | // handle unique case when component is in controlled mode 104 | // fire external event listeners instead of internal state management 105 | if (controlledSelected) { 106 | if (onToggleSelectedNodes) onToggleSelectedNodes(nodeSet) 107 | return 108 | } 109 | 110 | toggleSelectedNodes(nodeSet) 111 | }, 112 | [selectedNodes, toggleSelectedNodes, onToggleSelectedNodes, appOptions] 113 | ) 114 | 115 | // get current theme out of the theme list 116 | const currentTheme = themeList.themes[theme] 117 | 118 | return ( 119 | 120 | {/* Render list of nodes inside a container */} 121 | {theseNodes.map((n, i) => { 122 | const isOpen = theseNodesOpen[i] 123 | const isSelected = theseNodesSelected[i] 124 | 125 | // Render current node inside a container 126 | // N.B. Indentation is needed on each rendered node, not the container, because separator needs to cover whole width of container 127 | return ( 128 | { 133 | e.stopPropagation() 134 | handleToggleOpenNode(n.id) 135 | handleToggleSelectedNode(e, n.id) 136 | }} 137 | > 138 | 153 | 157 | {!appOptions.noIcons && ( 158 | 159 | 168 | {RenderIcon ? ( 169 | 177 | ) : ( 178 | 185 | )} 186 | 187 | 188 | )} 189 | {typeof RenderNode === 'function' ? ( 190 | RenderNode({ 191 | node: n, 192 | type: 'node', 193 | open: isOpen, 194 | selected: isSelected, 195 | context: treeContext 196 | }) 197 | ) : ( 198 | 199 | 207 | {n.label} 208 | 209 | 210 | )} 211 | 212 | 213 | {theseNodesOpen[i] && ( 214 | // Only if this node is open, render its children 215 | 218 | {/* 219 | 1. Recursively render any nodes that are children of this node at the top of the list 220 | 2. Render any items of this node beneath it 221 | */} 222 | {[ 223 | , 230 | appOptions.showEmptyItems && 231 | (!n.items || n.items?.length === 0) ? ( 232 | { 246 | e.stopPropagation() 247 | }} 248 | > 249 | 250 | 256 | {appOptions.messages.emptyItems} 257 | 258 | 259 | 260 | ) : null, 261 | n.items?.map((item, j) => { 262 | const isSelected = theseItemsSelected[i][j] 263 | return ( 264 | { 280 | e.stopPropagation() 281 | handleToggleSelectedNode(e, item.id) 282 | }} 283 | > 284 | 288 | {!appOptions.noIcons && ( 289 | 294 | {RenderIcon ? ( 295 | 302 | ) : ( 303 | 309 | )} 310 | 311 | )} 312 | {typeof RenderNode === 'function' ? ( 313 | RenderNode({ 314 | node: item, 315 | type: 'leaf', 316 | selected: isSelected, 317 | context: treeContext 318 | }) 319 | ) : ( 320 | 323 | 333 | {item.label} 334 | 335 | 336 | )} 337 | 338 | 339 | ) 340 | }) 341 | ]} 342 | 343 | )} 344 | 345 | ) 346 | })} 347 | 348 | ) 349 | } 350 | -------------------------------------------------------------------------------- /src/Tree/TreeRoot.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled, { useTheme } from 'styled-components' 3 | import { motion } from 'framer-motion' 4 | import ReactTreeContext from './Context' 5 | import { AnyNode } from './Nodes' 6 | import { ReactTreeTheme, SizeUnit, TreeRenderFn } from 'Tree' 7 | import { ColumnBlock, TextBlock } from './Elements' 8 | 9 | const TreeWrapper = styled(motion.div)<{ 10 | $backgroundColor?: string 11 | $fontFamily?: string 12 | $fontSize?: string 13 | $truncateLongText?: boolean 14 | }>(({ $backgroundColor, $fontFamily, $fontSize, $truncateLongText }) => { 15 | return [ 16 | `& * { 17 | font-size: ${$fontSize ? $fontSize : 'initial'}; 18 | font-family: ${$fontFamily ? $fontFamily : 'initial'}; 19 | }`, 20 | `display: flex; flex-direction: column; flex: 1;`, 21 | `background-color: ${$backgroundColor || 'initial'};`, 22 | `padding: 1rem;`, 23 | $truncateLongText 24 | ? `overflow-x: hidden; text-overflow: ellipsis; white-space: nowrap;` 25 | : `` 26 | ] 27 | }) 28 | 29 | const TreeMessage = styled(motion.div)<{ $theme: string }>` 30 | flex: 1; 31 | display: flex; 32 | flex-direction: column; 33 | align-items: center; 34 | justify-content: center; 35 | padding: 1rem; 36 | font-family: ${({ theme: options, $theme }) => 37 | options.themes[$theme as string].text?.fontFamily}; 38 | ` 39 | 40 | const TreeRoot = ({ 41 | loading, 42 | containerStyles, 43 | RenderNode, 44 | RenderIcon 45 | }: { 46 | loading: boolean 47 | containerStyles?: React.CSSProperties 48 | RenderNode?: TreeRenderFn 49 | RenderIcon?: TreeRenderFn 50 | }) => { 51 | const options = useTheme() 52 | const { 53 | nodes, 54 | theme, 55 | options: appOptions 56 | } = ReactTreeContext.useReactTreeContext() 57 | 58 | const currentTheme = options.themes[theme] as ReactTreeTheme 59 | if (!currentTheme) throw new Error('Specified theme does not exit') 60 | 61 | let fontSize = currentTheme?.text?.fontSize || 'std' 62 | 63 | if (fontSize in options.app.fontSizes) { 64 | fontSize = options.app.fontSizes[fontSize as SizeUnit] 65 | } 66 | 67 | return ( 68 | 76 | {!loading && nodes.length === 0 && ( 77 | 80 | {appOptions.messages.noData} 81 | 82 | )} 83 | {loading && Loading (more)...} 84 | {!loading && } 85 | 86 | ) 87 | } 88 | 89 | export default TreeRoot 90 | -------------------------------------------------------------------------------- /src/__tests__/Tree.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { cleanup, render, screen, waitFor } from '@testing-library/react' 3 | import Tree from '..' 4 | 5 | afterEach(cleanup) 6 | 7 | describe('React Tree core functions', () => { 8 | it('Renders a message when there is no data', async () => { 9 | const { container } = render() 10 | expect(container).toMatchSnapshot() 11 | const message = await screen.findByText(/No Data 😔/i) 12 | expect(message).toBeTruthy() 13 | }) 14 | 15 | it('Renders a loader and nothing else when `isLoading` state is `true`', async () => { 16 | const { container } = render() 17 | expect(container).toMatchSnapshot() 18 | const message = await screen.findByText(/Loading/i) 19 | expect(message).toBeTruthy() 20 | }) 21 | 22 | it('Re-renders nodes when the data set changes', async () => { 23 | const { rerender } = render() 24 | const firstRender = await screen.findByText(/TEST_NODE_1/) 25 | expect(firstRender).toBeTruthy() 26 | rerender() 27 | const secondRender = await screen.findByText(/TEST_NODE_2/) 28 | expect(secondRender).toBeTruthy() 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /src/__tests__/__snapshots__/Tree.spec.tsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`React Tree core functions Renders a loader and nothing else when \`isLoading\` state is \`true\` 1`] = ` 4 |
5 |
8 |
11 |
12 | Loading... 🌀 13 |
14 |
15 |
16 |
17 | `; 18 | 19 | exports[`React Tree core functions Renders a message when there is no data 1`] = ` 20 |
21 |
24 |
25 | 26 | No Data 😔 27 | 28 |
29 |
30 |
31 | `; 32 | -------------------------------------------------------------------------------- /src/__tests__/mocks/full_list_data.tsx: -------------------------------------------------------------------------------- 1 | import { nanoid } from 'nanoid' 2 | import type { TreeNodeList } from '../../Tree' 3 | 4 | const rootNodes: TreeNodeList = [ 5 | { 6 | id: nanoid(), 7 | parentId: null, 8 | label: 'Root 1' 9 | }, 10 | { 11 | id: nanoid(), 12 | parentId: null, 13 | label: 'Root 2' 14 | }, 15 | { 16 | id: nanoid(), 17 | parentId: null, 18 | label: 'Root 3' 19 | } 20 | ] 21 | 22 | const childNodes: TreeNodeList = [ 23 | { 24 | id: nanoid(), 25 | parentId: rootNodes[0].id, 26 | label: 'Child 1', 27 | items: [] 28 | }, 29 | { 30 | id: nanoid(), 31 | parentId: rootNodes[1].id, 32 | label: 'Child 2' 33 | }, 34 | { 35 | id: nanoid(), 36 | parentId: rootNodes[1].id, 37 | label: 'Child 3' 38 | }, 39 | { 40 | id: nanoid(), 41 | parentId: rootNodes[2].id, 42 | label: 'Child 4' 43 | } 44 | ] 45 | 46 | const childChildNodes: TreeNodeList = [ 47 | { 48 | id: nanoid(), 49 | parentId: childNodes[0].id, 50 | label: 'Child Child 1' 51 | }, 52 | { 53 | id: nanoid(), 54 | parentId: childNodes[1].id, 55 | label: 'Child Child 2', 56 | items: [] 57 | }, 58 | { 59 | id: nanoid(), 60 | parentId: childNodes[2].id, 61 | label: 'Child Child 3' 62 | } 63 | ] 64 | 65 | for (let i = 0; i < 3; i++) { 66 | if (childNodes[0].items) { 67 | childNodes[0].items.push({ 68 | id: nanoid(), 69 | parentId: childNodes[0].id, 70 | label: 'File ' + (i + 1) 71 | }) 72 | } 73 | 74 | if (childChildNodes[1].items) { 75 | childChildNodes[1].items.push({ 76 | id: nanoid(), 77 | parentId: childChildNodes[1].id, 78 | label: 'File ' + (i + 3) 79 | }) 80 | } 81 | } 82 | 83 | export const nodes: TreeNodeList = [ 84 | ...rootNodes, 85 | ...childNodes, 86 | ...childChildNodes 87 | ] 88 | -------------------------------------------------------------------------------- /src/__tests__/mocks/full_list_long_names_data.tsx: -------------------------------------------------------------------------------- 1 | import { nanoid as uid } from 'nanoid' 2 | import type { TreeNodeList } from '../../Tree' 3 | 4 | const rootNodes: TreeNodeList = [ 5 | { 6 | id: uid(), 7 | parentId: null, 8 | label: 9 | 'Root 1 - lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor', 10 | items: null 11 | }, 12 | { 13 | id: uid(), 14 | parentId: null, 15 | label: 16 | 'Root 2 - lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor ', 17 | items: null 18 | }, 19 | { 20 | id: uid(), 21 | parentId: null, 22 | label: 23 | 'Root 3 - lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor', 24 | items: null 25 | } 26 | ] 27 | 28 | const childNodes: TreeNodeList = [ 29 | { 30 | id: uid(), 31 | parentId: rootNodes[0].id, 32 | label: 33 | 'Child 1 - lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor', 34 | items: [] 35 | }, 36 | { 37 | id: uid(), 38 | parentId: rootNodes[1].id, 39 | label: 40 | 'Child 2 - lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor', 41 | items: null 42 | }, 43 | { 44 | id: uid(), 45 | parentId: rootNodes[2].id, 46 | label: 47 | 'Child 3 - lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor', 48 | items: null 49 | } 50 | ] 51 | 52 | const childChildNodes: TreeNodeList = [ 53 | { 54 | id: uid(), 55 | parentId: childNodes[0].id, 56 | label: 57 | 'Child Child 1 - lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor', 58 | items: null 59 | }, 60 | { 61 | id: uid(), 62 | parentId: childNodes[1].id, 63 | label: 64 | 'Child Child 2 - lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor', 65 | items: [] 66 | }, 67 | { 68 | id: uid(), 69 | parentId: childNodes[2].id, 70 | label: 71 | 'Child Child 3 - lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor', 72 | items: null 73 | } 74 | ] 75 | 76 | for (let i = 0; i < 3; i++) { 77 | childNodes[0].items.push({ 78 | id: uid(), 79 | parentId: childNodes[0].id, 80 | label: 81 | 'File ' + 82 | (i + 1) + 83 | ' - lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor' 84 | }) 85 | 86 | childChildNodes[1].items.push({ 87 | id: uid(), 88 | parentId: childChildNodes[1].id, 89 | label: 90 | 'File ' + 91 | (i + 3) + 92 | ' - lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor, lorum ipsum dolor' 93 | }) 94 | } 95 | 96 | export const nodes: TreeNodeList = [ 97 | ...rootNodes, 98 | ...childNodes, 99 | ...childChildNodes 100 | ] 101 | -------------------------------------------------------------------------------- /src/assets/images/Icons.ts: -------------------------------------------------------------------------------- 1 | import chevronRight from './chevron-right.svg' 2 | import circleNotch from './circle-notch.svg' 3 | import paperclip from './paperclip.svg' 4 | 5 | export default { 6 | file: paperclip, 7 | loader: circleNotch, 8 | node: chevronRight 9 | } 10 | -------------------------------------------------------------------------------- /src/assets/images/chevron-right.svg: -------------------------------------------------------------------------------- 1 | 2 | chevron-right 3 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/images/circle-notch.svg: -------------------------------------------------------------------------------- 1 | 2 | circle-notch 3 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/images/paperclip.svg: -------------------------------------------------------------------------------- 1 | 2 | paperclip 3 | 5 | 6 | -------------------------------------------------------------------------------- /src/hooks/useReactTreeApi.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { ReactTreeApi } from '../Tree/Context' 3 | 4 | export const useReactTreeApi = () => { 5 | return React.useRef() as React.MutableRefObject 6 | } 7 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { LazyMotion, domAnimation } from 'framer-motion' 3 | import { DefaultTheme, ThemeProvider } from 'styled-components' 4 | export { useReactTreeApi } from './hooks/useReactTreeApi' 5 | import { TreeNodeId, TreeNodeList, ThemeSettings, TreeRenderFn } from './Tree' 6 | import ReactTreeContext, { ReactTreeApi } from './Tree/Context' 7 | export { 8 | TreeNodeId, 9 | TreeNode, 10 | TreeNodeList, 11 | TreeRenderFn, 12 | ReactTreeTheme, 13 | ThemeSettings 14 | } from './Tree' 15 | export { ReactTreeApi, TReactTreeContext } from './Tree/Context' 16 | 17 | import TreeRoot from './Tree/TreeRoot' 18 | import coreTheme from './styles/theme' 19 | 20 | /** 21 | * @public 22 | */ 23 | export declare interface ReactTreeProps { 24 | nodes: TreeNodeList 25 | defaultOpenNodes?: TreeNodeId[] 26 | defaultSelectedNodes?: TreeNodeId[] 27 | messages?: { 28 | noData?: React.ReactNode 29 | loading?: React.ReactNode 30 | emptyItems?: React.ReactNode 31 | } 32 | loading?: boolean 33 | theme?: string 34 | themes?: ThemeSettings 35 | enableItemAnimations?: boolean 36 | enableIndicatorAnimations?: boolean 37 | showEmptyItems?: boolean 38 | noIcons?: boolean 39 | truncateLongText?: boolean 40 | multiSelect?: boolean 41 | containerStyles?: React.CSSProperties 42 | RenderNode?: TreeRenderFn 43 | RenderIcon?: TreeRenderFn 44 | selectedNodes?: TreeNodeId[] 45 | openNodes?: TreeNodeId[] 46 | onToggleSelectedNodes?: (nodes: TreeNodeId[]) => void 47 | onToggleOpenNodes?: (nodes: TreeNodeId[]) => void 48 | } 49 | 50 | export const ReactTree = React.forwardRef( 51 | ( 52 | { 53 | nodes = [], 54 | defaultOpenNodes, 55 | defaultSelectedNodes, 56 | selectedNodes, 57 | openNodes, 58 | messages = { 59 | loading: 'Loading...', 60 | noData: 'No data to render 😔', 61 | emptyItems: '[Empty]' 62 | }, 63 | loading = false, 64 | theme = 'light', 65 | themes, 66 | enableIndicatorAnimations = false, 67 | enableItemAnimations = false, 68 | showEmptyItems = false, 69 | noIcons = false, 70 | truncateLongText = false, 71 | multiSelect = false, 72 | containerStyles, 73 | RenderNode, 74 | RenderIcon, 75 | onToggleSelectedNodes, 76 | onToggleOpenNodes 77 | }: ReactTreeProps, 78 | ref: React.MutableRefObject 79 | ) => { 80 | /** 81 | * Complete react-tree theme 82 | */ 83 | const config: DefaultTheme = React.useMemo(() => { 84 | return { 85 | themes: { 86 | ...coreTheme.themes, 87 | ...themes 88 | }, 89 | app: coreTheme.app 90 | } 91 | }, [themes]) 92 | 93 | return ( 94 | 95 | 96 | 117 | 123 | 124 | 125 | 126 | ) 127 | } 128 | ) 129 | -------------------------------------------------------------------------------- /src/stories/Tree.stories.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import { ComponentStory, ComponentMeta } from '@storybook/react' 4 | 5 | import { ReactTree, TreeRenderFn } from '..' 6 | 7 | import { storyNodes } from './fixtures/Nodes' 8 | import { storyCustomTheme } from './fixtures/Theme' 9 | 10 | const CustomNode: TreeRenderFn = ({ node }) => { 11 | return
{node.label}
12 | } 13 | 14 | const CustomIcon: TreeRenderFn = () => { 15 | return ( 16 |
17 | 23 | 24 | 25 |
26 | ) 27 | } 28 | 29 | export default { 30 | title: '@naisutech/react-tree', 31 | component: ReactTree, 32 | argTypes: { 33 | theme: { 34 | options: ['light', 'dark', 'exampleCustomTheme'], 35 | control: { 36 | type: 'select' 37 | } 38 | }, 39 | themes: { 40 | control: { 41 | type: 'object' 42 | } 43 | }, 44 | RenderNode: { 45 | options: ['None', 'Custom'], 46 | mapping: { 47 | None: undefined, 48 | Custom: CustomNode 49 | } 50 | }, 51 | 52 | RenderIcon: { 53 | options: ['None', 'Custom'], 54 | mapping: { 55 | None: undefined, 56 | Custom: CustomIcon 57 | } 58 | } 59 | } 60 | } as ComponentMeta 61 | 62 | const TreeStoryTemplate: ComponentStory = args => ( 63 | 64 | ) 65 | 66 | export const Basic = TreeStoryTemplate.bind({}) 67 | 68 | Basic.args = { 69 | nodes: storyNodes, 70 | loading: false, 71 | theme: 'light', 72 | themes: storyCustomTheme, 73 | defaultOpenNodes: undefined, 74 | defaultSelectedNodes: undefined, 75 | messages: { 76 | loading: 'Loading...', 77 | noData: 'No data to render 😔', 78 | emptyItems: '[Empty]' 79 | }, 80 | enableItemAnimations: true, 81 | enableIndicatorAnimations: true, 82 | showEmptyItems: true, 83 | noIcons: false, 84 | truncateLongText: false, 85 | multiSelect: false, 86 | containerStyles: {}, 87 | RenderNode: 'None', 88 | RenderIcon: 'None', 89 | selectedNodes: undefined, 90 | openNodes: undefined 91 | } 92 | 93 | export const ControlledSelectedNodes = TreeStoryTemplate.bind({}) 94 | 95 | ControlledSelectedNodes.args = { 96 | nodes: storyNodes, 97 | loading: false, 98 | theme: 'light', 99 | themes: storyCustomTheme, 100 | defaultOpenNodes: undefined, 101 | defaultSelectedNodes: undefined, 102 | messages: { 103 | loading: 'Loading...', 104 | noData: 'No data to render 😔', 105 | emptyItems: '[Empty]' 106 | }, 107 | enableItemAnimations: true, 108 | enableIndicatorAnimations: true, 109 | showEmptyItems: true, 110 | noIcons: false, 111 | truncateLongText: false, 112 | containerStyles: {}, 113 | RenderNode: '', 114 | RenderIcon: '', 115 | selectedNodes: ['FTest'], 116 | openNodes: ['NodeTest1', 'NodeTest1-1'] 117 | } 118 | 119 | export const ControlledOpenNodes = TreeStoryTemplate.bind({}) 120 | 121 | ControlledOpenNodes.args = { 122 | nodes: storyNodes, 123 | loading: false, 124 | theme: 'light', 125 | themes: storyCustomTheme, 126 | defaultOpenNodes: undefined, 127 | defaultSelectedNodes: undefined, 128 | messages: { 129 | loading: 'Loading...', 130 | noData: 'No data to render 😔', 131 | emptyItems: '[Empty]' 132 | }, 133 | enableItemAnimations: true, 134 | enableIndicatorAnimations: true, 135 | showEmptyItems: true, 136 | noIcons: false, 137 | truncateLongText: false, 138 | containerStyles: {}, 139 | RenderNode: '', 140 | RenderIcon: '', 141 | selectedNodes: undefined, 142 | openNodes: ['NodeTest1'] 143 | } 144 | -------------------------------------------------------------------------------- /src/stories/fixtures/Nodes.ts: -------------------------------------------------------------------------------- 1 | import { customAlphabet } from 'nanoid' 2 | import { TreeNodeList } from 'Tree' 3 | 4 | const nanoid = customAlphabet('0123456789', 3) 5 | 6 | const rootNodes: TreeNodeList = [ 7 | { 8 | id: 'NodeTest1', 9 | parentId: null, 10 | label: 'Root 1' 11 | }, 12 | { 13 | id: '2', 14 | parentId: null, 15 | label: 'Root 2' 16 | }, 17 | { 18 | id: '3', 19 | parentId: null, 20 | label: 'Root 3' 21 | } 22 | ] 23 | 24 | const childNodes: TreeNodeList = [ 25 | { 26 | id: 'NodeTest1-1', 27 | parentId: rootNodes[0].id, 28 | label: 'Child 1', 29 | items: [] 30 | }, 31 | { 32 | id: nanoid(), 33 | parentId: rootNodes[1].id, 34 | label: 'Child 2' 35 | }, 36 | { 37 | id: nanoid(), 38 | parentId: rootNodes[1].id, 39 | label: 'Child 3' 40 | }, 41 | { 42 | id: nanoid(), 43 | parentId: rootNodes[2].id, 44 | label: 'Child 4' 45 | } 46 | ] 47 | 48 | const childChildNodes: TreeNodeList = [ 49 | { 50 | id: nanoid(), 51 | parentId: childNodes[0].id, 52 | label: 'Child 1 Child 1' 53 | }, 54 | { 55 | id: nanoid(), 56 | parentId: childNodes[1].id, 57 | label: 'Child 2 Child 1', 58 | items: [] 59 | }, 60 | { 61 | id: nanoid(), 62 | parentId: childNodes[2].id, 63 | label: 'Child 3 Child 1' 64 | }, 65 | { 66 | id: nanoid(), 67 | parentId: childNodes[2].id, 68 | label: 'Child 3 Child 2' 69 | } 70 | ] 71 | 72 | for (let i = 0; i < 3; i++) { 73 | if (childNodes[0].items) { 74 | childNodes[0].items.push({ 75 | id: nanoid(), 76 | parentId: childNodes[0].id, 77 | label: 'File ' + (i + 1) 78 | }) 79 | } 80 | 81 | if (childChildNodes[1].items) { 82 | childChildNodes[1].items.push({ 83 | id: nanoid(), 84 | parentId: childChildNodes[1].id, 85 | label: 'File ' + (i + 3) 86 | }) 87 | } 88 | } 89 | 90 | if (childNodes[0].items) { 91 | childNodes[0].items.push({ 92 | id: 'FTest', 93 | parentId: childNodes[0].id, 94 | label: 'File Test' 95 | }) 96 | } 97 | 98 | export const storyNodes: TreeNodeList = [ 99 | ...rootNodes, 100 | ...childNodes, 101 | ...childChildNodes 102 | ] 103 | -------------------------------------------------------------------------------- /src/stories/fixtures/Theme.ts: -------------------------------------------------------------------------------- 1 | import { ThemeSettings } from '../../Tree' 2 | 3 | export const storyCustomTheme: ThemeSettings = { 4 | exampleCustomTheme: { 5 | text: { 6 | fontSize: 'xl', 7 | fontFamily: `cursive`, 8 | color: '#fafafa', 9 | selectedColor: '#fafafa', 10 | hoverColor: '#fafafa' 11 | }, 12 | nodes: { 13 | height: '3.5rem', 14 | folder: { 15 | bgColor: 'gold', 16 | selectedBgColor: 'goldenrod', 17 | hoverBgColor: 'yellow' 18 | }, 19 | leaf: { 20 | bgColor: 'magenta', 21 | selectedBgColor: 'blueviolet', 22 | hoverBgColor: 'violet' 23 | }, 24 | separator: { 25 | border: '3px solid', 26 | borderColor: 'transparent' 27 | }, 28 | icons: { 29 | size: '1rem', 30 | folderColor: 'crimson', 31 | leafColor: 'white' 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/styles/theme.ts: -------------------------------------------------------------------------------- 1 | import { IAppSettings } from 'styled-components' 2 | import type { ThemeSettings } from '../Tree' 3 | 4 | const reactTreeBuiltInThemes: ThemeSettings = { 5 | dark: { 6 | text: { 7 | fontSize: 'std', 8 | fontFamily: `-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, 9 | Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;`, 10 | color: '#fafafa', 11 | selectedColor: '#fafafa', 12 | hoverColor: '#fafafa' 13 | }, 14 | nodes: { 15 | height: '2.5rem', 16 | folder: { 17 | bgColor: '#2d3439', 18 | selectedBgColor: '#3f464e', 19 | hoverBgColor: '#505a63' 20 | }, 21 | leaf: { 22 | bgColor: '#2d3439', 23 | selectedBgColor: '#3f464e', 24 | hoverBgColor: '#505a63' 25 | }, 26 | separator: { 27 | border: '1px solid', 28 | borderColor: '#555' 29 | }, 30 | icons: { 31 | size: '1rem', 32 | folderColor: '#64abd4', 33 | leafColor: '#64abd4' 34 | } 35 | } 36 | }, 37 | light: { 38 | text: { 39 | fontSize: 'std', 40 | fontFamily: `-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, 41 | Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;`, 42 | color: '#000', 43 | selectedColor: '#333', 44 | hoverColor: '#555' 45 | }, 46 | nodes: { 47 | height: '2.5rem', 48 | folder: { 49 | bgColor: '#fff', 50 | selectedBgColor: '#eee', 51 | hoverBgColor: '#ccc' 52 | }, 53 | leaf: { 54 | bgColor: '#fff', 55 | selectedBgColor: '#eee', 56 | hoverBgColor: '#ccc' 57 | }, 58 | separator: { 59 | border: '1px solid', 60 | borderColor: '#eee' 61 | }, 62 | icons: { 63 | size: '1rem', 64 | folderColor: '#64abd4', 65 | leafColor: '#64abd4' 66 | } 67 | } 68 | } 69 | } 70 | 71 | const reactTreeAppSettings: IAppSettings = { 72 | fontSizes: { 73 | xs: '0.625rem', 74 | sm: '0.875rem', 75 | std: '1rem', 76 | lg: '1.25rem', 77 | xl: '2.125rem' 78 | } 79 | } 80 | 81 | export default { 82 | themes: { 83 | ...reactTreeBuiltInThemes 84 | }, 85 | app: { 86 | ...reactTreeAppSettings 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/types/ReactSvg.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.svg' { 2 | import React = require('react') 3 | export const ReactComponent: React.SFC> 4 | const src: string 5 | export default src 6 | } 7 | -------------------------------------------------------------------------------- /src/types/global.d.ts: -------------------------------------------------------------------------------- 1 | import 'styled-components' 2 | import { CSSUnit, SizeUnit } from 'Tree' 3 | 4 | declare module 'styled-components' { 5 | interface ReactTreeTheme { 6 | text?: { 7 | fontSize?: SizeUnit | CSSUnit 8 | fontFamily?: string 9 | color?: string 10 | selectedColor?: string | null 11 | hoverColor?: string | null 12 | } 13 | nodes?: { 14 | height?: CSSUnit 15 | folder?: { 16 | bgColor?: string 17 | selectedBgColor?: string 18 | hoverBgColor?: string | null 19 | } 20 | leaf?: { 21 | bgColor?: string 22 | selectedBgColor?: string 23 | hoverBgColor?: string | null 24 | } 25 | indicator?: { 26 | bgColor?: string 27 | size?: CSSUnit 28 | } 29 | separator?: { 30 | border?: string 31 | borderColor?: string 32 | } 33 | icons?: { 34 | size?: CSSUnit 35 | folderColor?: string 36 | leafColor?: string 37 | } 38 | } 39 | } 40 | 41 | interface IAppSettings { 42 | fontSizes: Record 43 | } 44 | export interface DefaultTheme { 45 | themes: Record 46 | app: IAppSettings 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src"], 3 | "exclude": ["node_modules", "dist", "src/stories", "src/__tests__", "src/mocks"], 4 | "compilerOptions": { 5 | "allowSyntheticDefaultImports": true, 6 | "baseUrl": "src", 7 | "checkJs": true, 8 | "declaration": true, 9 | "declarationDir": "types", 10 | "downlevelIteration": true, 11 | "emitDecoratorMetadata": true, 12 | "esModuleInterop": true, 13 | "experimentalDecorators": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "importHelpers": true, 16 | "isolatedModules": false, 17 | "jsx": "react", 18 | "lib": ["es6", "dom", "es2016", "es2017", "es2018", "es2019"], 19 | "module": "esnext", 20 | "moduleResolution": "node", 21 | "noImplicitAny": true, 22 | "noImplicitThis": true, 23 | "noImplicitUseStrict": false, 24 | "noLib": false, 25 | "noUnusedLocals": true, 26 | "noUnusedParameters": true, 27 | "outDir": "js", 28 | "removeComments": false, 29 | "rootDir": "src", 30 | "skipLibCheck": true, 31 | "sourceMap": true, 32 | "strictNullChecks": true, 33 | "target": "es5", 34 | "paths": { 35 | "@naisu-tech/react-tree": ["./src/index"], 36 | "@naisu-tech/react-tree/*": ["./src/*"] 37 | } 38 | }, 39 | "filesGlob": ["./src/**/*.ts", "./src/**/*.tsx"] 40 | } 41 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src"], 3 | "exclude": ["node_modules", "dist"], 4 | "compilerOptions": { 5 | "allowSyntheticDefaultImports": true, 6 | "baseUrl": "src", 7 | "checkJs": true, 8 | "declaration": true, 9 | "declarationDir": "types", 10 | "downlevelIteration": true, 11 | "emitDecoratorMetadata": true, 12 | "esModuleInterop": true, 13 | "experimentalDecorators": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "importHelpers": true, 16 | "isolatedModules": false, 17 | "jsx": "react", 18 | "lib": ["es6", "dom", "es2016", "es2017", "es2018", "es2019"], 19 | "module": "esnext", 20 | "moduleResolution": "node", 21 | "noImplicitAny": true, 22 | "noImplicitThis": true, 23 | "noImplicitUseStrict": false, 24 | "noLib": false, 25 | "noUnusedLocals": true, 26 | "noUnusedParameters": true, 27 | "outDir": "lib", 28 | "removeComments": false, 29 | "rootDir": "src", 30 | "skipLibCheck": true, 31 | "sourceMap": true, 32 | "strictNullChecks": true, 33 | "target": "es2019", 34 | "paths": { 35 | "@naisu-tech/react-tree": ["./src/index"], 36 | "@naisu-tech/react-tree/*": ["./src/*"] 37 | } 38 | }, 39 | "filesGlob": ["./src/**/*.ts", "./src/**/*.tsx"] 40 | } 41 | --------------------------------------------------------------------------------