├── README.md
├── .prettierignore
├── lerna.json
├── www
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── bundle.html
├── src
│ ├── tsconfig.json
│ ├── react-app-env.d.ts
│ └── index.tsx
├── tsconfig.json
├── package.json
└── .kktrc.ts
├── .lintstagedrc
├── .husky
└── pre-commit
├── .gitpod.yml
├── .github
├── FUNDING.yml
└── workflows
│ └── ci.yml
├── core
├── tsconfig.json
├── .kktrc.ts
├── package.json
├── src
│ ├── style
│ │ └── index.less
│ └── index.tsx
└── README.md
├── renovate.json
├── .gitignore
├── .prettierrc
├── tsconfig.json
├── LICENSE
├── test
└── index.test.tsx
├── package.json
└── README-zh.md
/README.md:
--------------------------------------------------------------------------------
1 | ./core/README.md
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | package.json
2 | coverage
3 | dist
4 | build
5 | cjs
6 | esm
7 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "5.9.3",
3 | "packages": ["core", "www"]
4 | }
5 |
--------------------------------------------------------------------------------
/www/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uiwjs/react-split/HEAD/www/public/favicon.ico
--------------------------------------------------------------------------------
/.lintstagedrc:
--------------------------------------------------------------------------------
1 | {
2 | "*.{js,jsx,ts,tsx,html,less,md,json}": [
3 | "prettier --write"
4 | ]
5 | }
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | npx --no-install lint-staged
--------------------------------------------------------------------------------
/.gitpod.yml:
--------------------------------------------------------------------------------
1 | ports:
2 | - port: 3000
3 | onOpen: open-preview
4 | tasks:
5 | - init: npm install
6 | command: npm run build && npm run start
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | ko_fi: jaywcjlove
2 | buy_me_a_coffee: jaywcjlove
3 | custom: ["https://www.paypal.me/kennyiseeyou", "https://jaywcjlove.github.io/#/sponsor"]
4 |
--------------------------------------------------------------------------------
/core/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig",
3 | "include": ["src"],
4 | "compilerOptions": {
5 | "outDir": "./cjs",
6 | "baseUrl": ".",
7 | "noEmit": false
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/www/src/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig",
3 | "include": ["./"],
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "emitDeclarationOnly": true,
7 | "noEmit": false
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/www/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig",
3 | "include": ["./src"],
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "emitDeclarationOnly": true,
7 | "noEmit": false
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": ["config:base"],
4 | "packageRules": [
5 | {
6 | "matchPackagePatterns": ["*"],
7 | "rangeStrategy": "replace"
8 | }
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | cjs
2 | esm
3 | coverage
4 | build
5 | dist
6 | node_modules
7 | npm-debug.log*
8 | package-lock.json
9 | dist.css
10 |
11 | .eslintcache
12 | .DS_Store
13 | .cache
14 | .rdoc-dist
15 | .vscode
16 |
17 | *.bak
18 | *.tem
19 | *.temp
20 | #.swp
21 | *.*~
22 | ~*.*
23 |
--------------------------------------------------------------------------------
/www/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | declare var VERSION: string;
4 |
5 | declare module '*.md' {
6 | import { CodeBlockData } from 'markdown-react-code-preview-loader';
7 | const src: CodeBlockData;
8 | export default src;
9 | }
10 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "all",
4 | "printWidth": 120,
5 | "overrides": [
6 | {
7 | "files": ".prettierrc",
8 | "options": { "parser": "json" }
9 | },
10 | {
11 | "files": ".lintstagedrc",
12 | "options": { "parser": "json" }
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/core/.kktrc.ts:
--------------------------------------------------------------------------------
1 | import { LoaderConfOptions, WebpackConfiguration } from 'kkt';
2 | import lessModules from '@kkt/less-modules';
3 |
4 | export default (conf: WebpackConfiguration, env: 'production' | 'development', options: LoaderConfOptions) => {
5 | conf = lessModules(conf, env, options);
6 | if (options.bundle) {
7 | conf.output!.library = '@uiw/react-split';
8 | conf.externals = {
9 | react: {
10 | root: 'React',
11 | commonjs2: 'react',
12 | commonjs: 'react',
13 | amd: 'react',
14 | },
15 | };
16 | }
17 |
18 | return conf;
19 | };
20 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "esModuleInterop": true,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "declaration": true,
16 | "baseUrl": ".",
17 | "jsx": "react-jsx",
18 | "noFallthroughCasesInSwitch": true,
19 | "noEmit": true
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/www/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | React Split
9 |
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/www/src/index.tsx:
--------------------------------------------------------------------------------
1 | import { createRoot } from 'react-dom/client';
2 | import MarkdownPreviewExample from '@uiw/react-markdown-preview-example';
3 | import data from '@uiw/react-split/README.md';
4 |
5 | const Github = MarkdownPreviewExample.Github;
6 |
7 | const container = document.getElementById('root');
8 | const root = createRoot(container!);
9 | root.render(
10 |
18 |
19 | ,
20 | );
21 |
--------------------------------------------------------------------------------
/core/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@uiw/react-split",
3 | "version": "5.9.3",
4 | "description": "A piece of content can be divided into areas that can be dragged to adjust the width or height.",
5 | "main": "cjs/index.js",
6 | "module": "esm/index.js",
7 | "homepage": "https://uiwjs.github.io/react-split",
8 | "funding": "https://jaywcjlove.github.io/#/sponsor",
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/uiwjs/react-split.git"
12 | },
13 | "author": "Kenny Wong ",
14 | "license": "MIT",
15 | "files": [
16 | "src/**/*.{ts,tsx,less}",
17 | "README-zh.md",
18 | "dist.css",
19 | "dist",
20 | "esm",
21 | "cjs"
22 | ],
23 | "peerDependencies": {
24 | "react": ">=16.8.0",
25 | "react-dom": ">=16.8.0"
26 | },
27 | "devDependencies": {
28 | "react": "^18.2.0",
29 | "react-dom": "^18.2.0"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/www/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "www",
3 | "private": true,
4 | "version": "5.9.3",
5 | "license": "MIT",
6 | "scripts": {
7 | "build": "kkt build",
8 | "start": "kkt start"
9 | },
10 | "dependencies": {
11 | "@uiw/react-markdown-preview-example": "^2.0.0",
12 | "@uiw/react-split": "5.9.3"
13 | },
14 | "devDependencies": {
15 | "@types/react": "^18.2.14",
16 | "@types/react-dom": "^18.2.6",
17 | "kkt": "^7.4.9",
18 | "markdown-react-code-preview-loader": "^2.1.2",
19 | "react": "^18.2.0",
20 | "react-dom": "^18.2.0",
21 | "uiw": "^4.21.14"
22 | },
23 | "eslintConfig": {
24 | "extends": [
25 | "react-app",
26 | "react-app/jest"
27 | ]
28 | },
29 | "browserslist": {
30 | "production": [
31 | ">0.2%",
32 | "not dead",
33 | "not op_mini all"
34 | ],
35 | "development": [
36 | "last 1 chrome version",
37 | "last 1 firefox version",
38 | "last 1 safari version"
39 | ]
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 uiw
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 |
--------------------------------------------------------------------------------
/test/index.test.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * @jest-environment jsdom
3 | */
4 | import { render, screen } from '@testing-library/react';
5 | import '@testing-library/jest-dom';
6 | import React from 'react';
7 | import Split from '../core/src/';
8 |
9 | test('renders react-split', () => {
10 | render(
11 |
12 | Header
13 |
14 | Sider
15 | Content
16 |
17 | Footer
18 | ,
19 | );
20 | const element = screen.getByTestId('split');
21 | expect(element.className).toEqual('w-split w-split-vertical');
22 | expect(element).toBeInTheDocument();
23 | });
24 |
25 | test('lineBar props', () => {
26 | render(
27 |
28 | Header
29 | ,
30 | );
31 | const element = screen.getByTestId('split');
32 | expect(element.className).toEqual('w-split w-split-vertical');
33 | expect(element.childNodes.length).toEqual(1);
34 | expect(element).toBeInTheDocument();
35 | });
36 |
37 | test('disable props', () => {
38 | render(
39 |
40 | Header
41 | Header
42 | ,
43 | );
44 | const element = screen.getByTestId('split');
45 | expect(element.className).toEqual('w-split w-split-horizontal');
46 | expect((element.childNodes[1] as any).className).toEqual('w-split-bar w-split-large-bar disable');
47 | expect(element.childNodes.length).toEqual(3);
48 | expect(element).toBeInTheDocument();
49 | });
50 |
--------------------------------------------------------------------------------
/www/.kktrc.ts:
--------------------------------------------------------------------------------
1 | import webpack from 'webpack';
2 | import { WebpackConfiguration } from 'kkt';
3 | import { mdCodeModulesLoader } from 'markdown-react-code-preview-loader';
4 | import pkg from './package.json';
5 |
6 | export default (conf: WebpackConfiguration, env: 'production' | 'development') => {
7 | conf = mdCodeModulesLoader(conf);
8 | // Get the project version.
9 | conf.plugins!.push(
10 | new webpack.DefinePlugin({
11 | VERSION: JSON.stringify(pkg.version),
12 | }),
13 | );
14 | conf.module!.exprContextCritical = false;
15 | if (env === 'production') {
16 | conf.module!.exprContextCritical = false;
17 | conf.output = { ...conf.output, publicPath: './' };
18 | conf.optimization = {
19 | ...conf.optimization,
20 | splitChunks: {
21 | cacheGroups: {
22 | reactvendor: {
23 | test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
24 | name: 'react-vendor',
25 | chunks: 'all',
26 | },
27 | babelstandalone: {
28 | test: /[\\/]node_modules[\\/](@babel[\\/]standalone)[\\/]/,
29 | name: 'babel-standalone-vendor',
30 | chunks: 'all',
31 | },
32 | prismjs: {
33 | test: /[\\/]node_modules[\\/](refractor)[\\/]/,
34 | name: 'refractor-vendor',
35 | chunks: 'all',
36 | },
37 | codemirror: {
38 | test: /[\\/]node_modules[\\/](@codemirror)[\\/]/,
39 | name: 'codemirror-vendor',
40 | chunks: 'all',
41 | },
42 | uiw: {
43 | test: /[\\/]node_modules[\\/](@uiw)[\\/]/,
44 | name: 'uiw-vendor',
45 | chunks: 'all',
46 | },
47 | parse5: {
48 | test: /[\\/]node_modules[\\/](parse5)[\\/]/,
49 | name: 'parse5-vendor',
50 | chunks: 'all',
51 | },
52 | },
53 | },
54 | };
55 | }
56 |
57 | return conf;
58 | };
59 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "doc": "lerna exec --scope www -- npm run build",
5 | "start": "lerna exec --scope www -- npm run start",
6 | "⬇️⬇️⬇️⬇️⬇️ package ⬇️⬇️⬇️⬇️⬇️": "▼▼▼▼▼ package ▼▼▼▼▼",
7 | "build": "lerna exec --scope @uiw/* -- tsbb build src/*.tsx --use-babel --cjs cjs --bail && npm run css:build && npm run css:build:dist",
8 | "watch": "lerna exec \"tsbb watch src/*.tsx --use-babel --cjs cjs\" --scope @uiw/* & npm run css:watch",
9 | "css:build": "lerna exec --scope @uiw/* -- compile-less -d src -o esm",
10 | "css:watch": "lerna exec --scope @uiw/* -- compile-less -d src -o esm --watch",
11 | "css:build:dist": "lerna exec --scope @uiw/* -- compile-less -d src -o lib --combine=dist.css",
12 | "bundle": "lerna exec --scope @uiw/* -- ncc build src/index.tsx --target web --filename dist",
13 | "bundle:min": "lerna exec --scope @uiw/* -- ncc build src/index.tsx --target web --filename dist --minify",
14 | "⬆️⬆️⬆️⬆️⬆️ package ⬆️⬆️⬆️⬆️⬆️": "▲▲▲▲▲ package ▲▲▲▲▲",
15 | "type-check": "tsc --noEmit",
16 | "test": "tsbb test",
17 | "coverage": "tsbb test --coverage --bail",
18 | "prepare": "husky install",
19 | "version": "lerna version --exact --force-publish --no-push --no-git-tag-version",
20 | "prettier": "prettier --write '**/*.{js,jsx,ts,tsx,html,less,md,json}'",
21 | "remove": "npm run clean && lerna exec \"rm -rf package-lock.json\" --scope react-code-preview-layout --scope www",
22 | "clean": "lerna clean --yes"
23 | },
24 | "workspaces": [
25 | "core",
26 | "www"
27 | ],
28 | "engines": {
29 | "node": ">=16.0.0"
30 | },
31 | "lint-staged": {
32 | "*.{js,jsx,ts,tsx,html,less,md,json}": [
33 | "prettier --write"
34 | ]
35 | },
36 | "jest": {
37 | "collectCoverageFrom": [
38 | "/core/src/*.{tsx,ts}"
39 | ],
40 | "coverageReporters": [
41 | "lcov",
42 | "json-summary"
43 | ]
44 | },
45 | "devDependencies": {
46 | "@kkt/ncc": "^1.0.15",
47 | "@kkt/less-modules": "^7.5.2",
48 | "compile-less-cli": "^1.9.0",
49 | "jest": "^29.5.0",
50 | "jest-environment-jsdom": "^29.6.0",
51 | "jest-environment-node": "^29.5.0",
52 | "jest-watch-typeahead": "^2.2.2",
53 | "husky": "~8.0.3",
54 | "kkt": "^7.5.2",
55 | "lerna": "^8.0.0",
56 | "lint-staged": "^15.1.0",
57 | "prettier": "^3.0.0",
58 | "tsbb": "^4.2.4"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on:
3 | push:
4 | branches:
5 | - master
6 | paths-ignore:
7 | - '.github/**/*.yml'
8 |
9 | jobs:
10 | build-deploy:
11 | runs-on: ubuntu-latest
12 | permissions:
13 | contents: write
14 | id-token: write
15 | steps:
16 | - uses: actions/checkout@v4
17 | - uses: actions/setup-node@v4
18 | with:
19 | node-version: 20
20 | registry-url: 'https://registry.npmjs.org'
21 |
22 | - run: npm install
23 | - run: npm run build
24 | - run: npm run doc
25 | - run: npm run bundle
26 | - run: npm run bundle:min
27 | - run: npm run coverage
28 | - run: npm run type-check
29 | - run: cp -rp coverage www/build
30 | - run: cp -rp README-zh.md core
31 |
32 | - name: Generate Contributors Images
33 | uses: jaywcjlove/github-action-contributors@main
34 | with:
35 | filter-author: (renovate\[bot\]|renovate-bot|dependabot\[bot\])
36 | output: www/build/CONTRIBUTORS.svg
37 | avatarSize: 42
38 |
39 | - name: Create Coverage Badges
40 | uses: jaywcjlove/coverage-badges-cli@main
41 | with:
42 | output: www/build/badges.svg
43 |
44 | - name: Deploy
45 | uses: peaceiris/actions-gh-pages@v3
46 | with:
47 | github_token: ${{ secrets.GITHUB_TOKEN }}
48 | publish_dir: ./www/build
49 |
50 | - name: Create Tag
51 | id: create_tag
52 | uses: jaywcjlove/create-tag-action@main
53 | with:
54 | package-path: ./core/package.json
55 |
56 | - name: Generate Changelog
57 | id: changelog
58 | uses: jaywcjlove/changelog-generator@main
59 | with:
60 | head-ref: ${{steps.create_tag.outputs.version}}
61 | filter-author: (renovate-bot|Renovate Bot)
62 | filter: '[R|r]elease[d]\s+[v|V]\d(\.\d+){0,2}'
63 |
64 | - name: Create Release
65 | uses: ncipollo/release-action@v1
66 | if: steps.create_tag.outputs.successful
67 | with:
68 | allowUpdates: true
69 | token: ${{ secrets.GITHUB_TOKEN }}
70 | name: ${{ steps.create_tag.outputs.version }}
71 | tag: ${{ steps.create_tag.outputs.version }}
72 | body: |
73 | [](https://jaywcjlove.github.io/#/sponsor) [](https://uiwjs.github.io/npm-unpkg/#/pkg/@uiw/react-split@${{steps.create_tag.outputs.versionNumber}}/file/README.md)
74 |
75 | Documentation ${{ steps.changelog.outputs.tag }}: https://raw.githack.com/uiwjs/react-split/${{ steps.changelog.outputs.gh-pages-short-hash }}/index.html
76 | Comparing Changes: ${{ steps.changelog.outputs.compareurl }}
77 |
78 | ```bash
79 | npm i @uiw/react-split@${{steps.create_tag.outputs.versionNumber}}
80 | ```
81 |
82 | ${{ steps.changelog.outputs.changelog }}
83 |
84 | Bundle Example: https://uiwjs.github.io/react-split/bundle.html
85 |
86 | - run: npm publish --access public --provenance
87 | name: 📦 @uiw/react-split publish to NPM
88 | continue-on-error: true
89 | working-directory: core
90 | env:
91 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
92 |
93 |
94 | # outputs:
95 | # successful: ${{steps.create_tag.outputs.successful }}
96 |
97 | # github-package:
98 | # runs-on: ubuntu-latest
99 | # needs: build-deploy
100 | # if: needs.build-deploy.outputs.successful
101 | # steps:
102 | # - uses: actions/checkout@v3
103 | # - uses: actions/setup-node@v3
104 | # with:
105 | # node-version: 16
106 | # registry-url: https://npm.pkg.github.com
107 | # scope: '@uiwjs'
108 |
109 | # - run: npm install
110 | # - run: npm run build
111 | # - run: npm run bundle
112 | # - run: npm run bundle:min
113 |
114 | # - name: "Modify @uiw/react-split => @uiwjs/react-split"
115 | # uses: jaywcjlove/github-action-package@main
116 | # with:
117 | # path: package.json
118 | # data: |
119 | # { "name": "@uiwjs/react-split" }
120 |
121 | # - run: npm publish
122 | # env:
123 | # NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
--------------------------------------------------------------------------------
/core/src/style/index.less:
--------------------------------------------------------------------------------
1 | @split-prefix: ~'w-split';
2 |
3 | .@{split-prefix} {
4 | height: 100%;
5 | display: flex;
6 | flex-direction: row;
7 | --w-split-bar-shadow: #d5d5d5;
8 | --w-split-bar-shadow-disable: #d5d5d5;
9 | &-bar {
10 | z-index: 10;
11 | position: relative;
12 | justify-content: center;
13 | display: flex;
14 | background: var(--w-split-bar-background, rgb(248, 248, 249));
15 | user-select: none;
16 | &::before,
17 | &::after {
18 | content: '';
19 | display: block;
20 | }
21 | &.disable {
22 | pointer-events: none;
23 | cursor: not-allowed !important;
24 | }
25 | &:hover:not(.disable) {
26 | transition: background-color 0.3s;
27 | background: var(--w-split-bar-hover-background, #ecf7ff);
28 | }
29 | }
30 | &.dragging &-pane {
31 | position: relative;
32 | &::before {
33 | content: '';
34 | display: block;
35 | position: absolute;
36 | height: 100%;
37 | width: 100%;
38 | z-index: 10;
39 | }
40 | }
41 | & > &-pane {
42 | transform: none;
43 | }
44 | &:not(.dragging) > &-pane {
45 | transition: all 0.3s;
46 | }
47 | &-horizontal > &-bar {
48 | cursor: col-resize;
49 | width: 5px;
50 | flex-direction: column;
51 | box-shadow:
52 | inset 1px 0 0 0 var(--w-split-bar-shadow),
53 | 1px 0 0 0 var(--w-split-bar-shadow);
54 | &::before,
55 | &::after {
56 | height: 3px;
57 | width: 100%;
58 | box-shadow:
59 | inset 0 1px 0 0 var(--w-split-bar-shadow),
60 | 0 1px 0 0 var(--w-split-bar-shadow);
61 | }
62 | &::before {
63 | margin-top: -1px;
64 | }
65 | &::after {
66 | margin-top: 3px;
67 | }
68 | &.disable {
69 | box-shadow:
70 | inset 1px 0 0 0 var(--w-split-bar-shadow-disable),
71 | 1px 0 0 0 var(--w-split-bar-shadow-disable) !important;
72 | }
73 | }
74 | &-vertical {
75 | flex-direction: column;
76 | }
77 | &-vertical > &-bar {
78 | cursor: row-resize;
79 | width: 100%;
80 | height: 5px;
81 | align-items: center;
82 | flex-direction: row;
83 | box-shadow:
84 | inset 0 1px 0 0 var(--w-split-bar-shadow),
85 | 0 1px 0 0 var(--w-split-bar-shadow);
86 | &.disable {
87 | box-shadow:
88 | inset 0 1px 0 0 var(--w-split-bar-shadow-disable),
89 | 0 1px 0 0 var(--w-split-bar-shadow-disable) !important;
90 | }
91 | &::before,
92 | &::after {
93 | height: 100%;
94 | width: 3px;
95 | box-shadow:
96 | inset 1px 0 0 0 var(--w-split-bar-shadow),
97 | 1px 0 0 0 var(--w-split-bar-shadow);
98 | }
99 | &::before {
100 | margin-left: -1px;
101 | }
102 | &::after {
103 | margin-left: 3px;
104 | }
105 | }
106 | &-large-bar {
107 | div {
108 | position: absolute;
109 | left: 0;
110 | right: 0;
111 | bottom: 0;
112 | top: 0;
113 | }
114 | }
115 | &-vertical > &-line-bar:hover,
116 | &-horizontal > &-line-bar:hover {
117 | &::before {
118 | background: var(--w-split-line-bar-hover-border-color, #008ef0);
119 | }
120 | }
121 | &-vertical > &-line-bar {
122 | height: 1px;
123 | div {
124 | cursor: row-resize;
125 | width: 100%;
126 | height: 8px;
127 | margin-top: -2px;
128 | margin-bottom: -2px;
129 | &:hover,
130 | &:active,
131 | &:focus {
132 | margin-top: -6px;
133 | margin-bottom: -6px;
134 | height: 6px;
135 | &::after {
136 | background: var(--w-split-line-bar-active-background, #008ef0);
137 | }
138 | }
139 | &::after {
140 | height: 1px;
141 | width: 100%;
142 | }
143 | }
144 | }
145 | &-horizontal > &-line-bar {
146 | width: 1px;
147 | div {
148 | cursor: col-resize;
149 | height: 100%;
150 | width: 8px;
151 | margin-left: -2px;
152 | margin-right: -2px;
153 | &:hover,
154 | &:active,
155 | &:focus {
156 | margin-left: -6px;
157 | margin-right: -6px;
158 | width: 6px;
159 | &::after {
160 | background: var(--w-split-line-bar-active-background, #008ef0);
161 | }
162 | }
163 | &::after {
164 | width: 1px;
165 | height: 100%;
166 | }
167 | }
168 | }
169 | &-vertical > &-line-bar,
170 | &-horizontal > &-line-bar {
171 | flex-direction: inherit;
172 | &::before {
173 | display: none;
174 | }
175 | div {
176 | position: relative;
177 | display: flex;
178 | align-items: center;
179 | justify-content: center;
180 | &::after {
181 | content: '';
182 | display: block;
183 | background-color: var(--w-split-line-bar-background, #d5d5d5);
184 | }
185 | }
186 | }
187 | &-line-bar {
188 | box-shadow: inset 0 0 0 0 !important;
189 | background: transparent;
190 | &::before {
191 | box-shadow: inset 0 0 0 0 !important;
192 | }
193 | &::after {
194 | display: none;
195 | }
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/www/public/bundle.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | @uiw/react-split
13 |
14 |
15 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/core/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useRef, useEffect, useCallback } from 'react';
2 | import './style/index.less';
3 |
4 | export interface SplitProps extends Omit, 'onDragEnd'> {
5 | style?: React.CSSProperties;
6 | className?: string;
7 | prefixCls?: string;
8 | /**
9 | * Drag width/height change callback function,
10 | * the width or height is determined according to the mode parameter
11 | */
12 | onDragging?: (preSize: number, nextSize: number, paneNumber: number) => void;
13 | /** Callback function for dragging end */
14 | onDragEnd?: (preSize: number, nextSize: number, paneNumber: number) => void;
15 | /** Support custom drag and drop toolbar */
16 | renderBar?: (props: React.HTMLAttributes) => React.ReactElement;
17 | /** Set the drag and drop toolbar as a line style. */
18 | lineBar?: boolean;
19 | /** Set the dragged toolbar, whether it is visible or not */
20 | visible?: boolean | number[];
21 | /**
22 | * @deprecated Use `visible` instead
23 | */
24 | visiable?: boolean | number[];
25 | /**
26 | * Set the drag and drop toolbar, disable
27 | */
28 | disable?: boolean | number[];
29 | /**
30 | * type, optional `horizontal` or `vertical`
31 | */
32 | mode?: 'horizontal' | 'vertical';
33 | }
34 |
35 | const Split: React.FC = (props: SplitProps) => {
36 | const {
37 | prefixCls = 'w-split',
38 | visiable = true,
39 | mode = 'horizontal',
40 | className,
41 | children,
42 | visible = props.visible ?? props.visiable,
43 | renderBar,
44 | lineBar,
45 | disable,
46 | onDragEnd,
47 | onDragging,
48 | ...other
49 | } = props;
50 | const [dragging, setDragging] = useState(false);
51 |
52 | const wrapperRef = useRef(null);
53 | const paneNumberRef = useRef(0);
54 | const startXRef = useRef(0);
55 | const startYRef = useRef(0);
56 | const moveRef = useRef(false);
57 | const targetRef = useRef(null);
58 |
59 | const boxWidthRef = useRef(0);
60 | const boxHeightRef = useRef(0);
61 | const preWidthRef = useRef(0);
62 | const nextWidthRef = useRef(0);
63 | const preHeightRef = useRef(0);
64 | const nextHeightRef = useRef(0);
65 |
66 | const preSizeRef = useRef(0);
67 | const nextSizeRef = useRef(0);
68 |
69 | const removeEvent = useCallback(() => {
70 | window.removeEventListener('mousemove', onDraggingHandler, false);
71 | window.removeEventListener('mouseup', onDragEndHandler, false);
72 | }, []);
73 |
74 | const onDraggingHandler = useCallback(
75 | (env: Event) => {
76 | if (!moveRef.current) {
77 | return;
78 | }
79 | if (!dragging) {
80 | setDragging(true);
81 | }
82 | const nextTarget = targetRef.current?.nextElementSibling as HTMLDivElement;
83 | const prevTarget = targetRef.current?.previousElementSibling as HTMLDivElement;
84 | const x = (env as MouseEvent).clientX - startXRef.current;
85 | const y = (env as MouseEvent).clientY - startYRef.current;
86 | preSizeRef.current = 0;
87 | nextSizeRef.current = 0;
88 | if (mode === 'horizontal') {
89 | preSizeRef.current = preWidthRef.current + x > -1 ? preWidthRef.current + x : 0;
90 | nextSizeRef.current = nextWidthRef.current - x > -1 ? nextWidthRef.current - x : 0;
91 | if (preSizeRef.current === 0 || nextSizeRef.current === 0) {
92 | return;
93 | }
94 | preSizeRef.current =
95 | (preSizeRef.current / boxWidthRef.current >= 1 ? 1 : preSizeRef.current / boxWidthRef.current) * 100;
96 | nextSizeRef.current =
97 | (nextSizeRef.current / boxWidthRef.current >= 1 ? 1 : nextSizeRef.current / boxWidthRef.current) * 100;
98 | if (prevTarget && nextTarget) {
99 | prevTarget.style.width = `${preSizeRef.current}%`;
100 | nextTarget.style.width = `${nextSizeRef.current}%`;
101 | }
102 | }
103 | if (mode === 'vertical' && preHeightRef.current + y > -1 && nextHeightRef.current - y > -1) {
104 | preSizeRef.current = preHeightRef.current + y > -1 ? preHeightRef.current + y : 0;
105 | nextSizeRef.current = nextHeightRef.current - y > -1 ? nextHeightRef.current - y : 0;
106 | preSizeRef.current =
107 | (preSizeRef.current / boxHeightRef.current >= 1 ? 1 : preSizeRef.current / boxHeightRef.current) * 100;
108 | nextSizeRef.current =
109 | (nextSizeRef.current / boxHeightRef.current >= 1 ? 1 : nextSizeRef.current / boxHeightRef.current) * 100;
110 | if (preSizeRef.current === 0 || nextSizeRef.current === 0) {
111 | return;
112 | }
113 | if (prevTarget && nextTarget) {
114 | prevTarget.style.height = `${preSizeRef.current}%`;
115 | nextTarget.style.height = `${nextSizeRef.current}%`;
116 | }
117 | }
118 | onDragging && onDragging(preSizeRef.current, nextSizeRef.current, paneNumberRef.current);
119 | },
120 | [mode, onDragging, dragging],
121 | );
122 |
123 | const onDragEndHandler = useCallback(() => {
124 | moveRef.current = false;
125 | onDragEnd && onDragEnd(preSizeRef.current, nextSizeRef.current, paneNumberRef.current);
126 | removeEvent();
127 | setDragging(false);
128 | }, [onDragEnd, removeEvent]);
129 |
130 | const onMouseDown = useCallback(
131 | (paneNumber: number, env: React.MouseEvent) => {
132 | if (!env.target || !wrapperRef.current) {
133 | return;
134 | }
135 | paneNumberRef.current = paneNumber;
136 | startXRef.current = env.clientX;
137 | startYRef.current = env.clientY;
138 | moveRef.current = true;
139 | targetRef.current = (env.target as HTMLDivElement).parentNode as HTMLDivElement;
140 | const prevTarget = targetRef.current.previousElementSibling;
141 | const nextTarget = targetRef.current.nextElementSibling;
142 | boxWidthRef.current = wrapperRef.current.clientWidth;
143 | boxHeightRef.current = wrapperRef.current.clientHeight;
144 | if (prevTarget) {
145 | preWidthRef.current = prevTarget.clientWidth;
146 | preHeightRef.current = prevTarget.clientHeight;
147 | }
148 | if (nextTarget) {
149 | nextWidthRef.current = nextTarget.clientWidth;
150 | nextHeightRef.current = nextTarget.clientHeight;
151 | }
152 | window.addEventListener('mousemove', onDraggingHandler);
153 | window.addEventListener('mouseup', onDragEndHandler, false);
154 | setDragging(true);
155 | },
156 | [onDraggingHandler, onDragEndHandler],
157 | );
158 |
159 | useEffect(() => {
160 | return () => {
161 | removeEvent();
162 | };
163 | }, [removeEvent]);
164 |
165 | const cls = [prefixCls, className, `${prefixCls}-${mode}`, dragging ? 'dragging' : null]
166 | .filter(Boolean)
167 | .join(' ')
168 | .trim();
169 | const child = React.Children.toArray(children);
170 |
171 | return (
172 |
173 | {React.Children.map(child, (element: any, idx: number) => {
174 | const props = Object.assign({}, element.props, {
175 | className: [`${prefixCls}-pane`, element.props.className].filter(Boolean).join(' ').trim(),
176 | style: { ...element.props.style },
177 | });
178 | const visibleBar = visible === true || (visible && visible.includes((idx + 1) as never)) || false;
179 | const barProps = {
180 | className: [
181 | `${prefixCls}-bar`,
182 | lineBar ? `${prefixCls}-line-bar` : null,
183 | !lineBar ? `${prefixCls}-large-bar` : null,
184 | ]
185 | .filter(Boolean)
186 | .join(' ')
187 | .trim(),
188 | };
189 | if (disable === true || (disable && disable.includes((idx + 1) as never))) {
190 | barProps.className = [barProps.className, disable ? 'disable' : null].filter(Boolean).join(' ').trim();
191 | }
192 | let BarCom = null;
193 | if (idx !== 0 && visibleBar && renderBar) {
194 | BarCom = renderBar({
195 | ...barProps,
196 | onMouseDown: (e: React.MouseEvent
) => onMouseDown(idx + 1, e),
197 | });
198 | } else if (idx !== 0 && visibleBar) {
199 | BarCom = React.createElement(
200 | 'div',
201 | { ...barProps },
202 | ) => onMouseDown(idx + 1, e)} />,
203 | );
204 | }
205 | return (
206 |
207 | {BarCom}
208 | {React.cloneElement(element, { ...props })}
209 |
210 | );
211 | })}
212 |
213 | );
214 | };
215 |
216 | export default Split;
217 |
--------------------------------------------------------------------------------
/README-zh.md:
--------------------------------------------------------------------------------
1 |
2 | English
3 |
4 |
5 |
6 |
使用我的应用 ,也是对我的支持 :
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | # Split 面板分割
42 |
43 | [](https://jaywcjlove.github.io/#/sponsor)
44 | [](https://www.npmjs.com/package/@uiw/react-split)
45 | [](https://github.com/uiwjs/react-split/actions/workflows/ci.yml)
46 | [](https://uiwjs.github.io/npm-unpkg/#/pkg/@uiw/react-split/file/README.md)
47 | [](https://www.npmjs.com/package/@uiw/react-split)
48 | [](https://uiwjs.github.io/react-split/coverage/lcov-report/)
49 | [](https://gitpod.io/#https://github.com/uiwjs/react-split)
50 | [](https://github.com/uiwjs/react-split/network/dependents)
51 |
52 | 可将一块内容,分割为可以拖拽调整宽度或高度的区域。
53 |
54 | ```jsx
55 | import { Split } from 'uiw';
56 | ```
57 |
58 | 从组件库 `uiw` 中抽离出来的 `@uiw/react-split`,可以单独使用。
59 |
60 | ```jsx
61 | import Split from '@uiw/react-split';
62 | ```
63 |
64 | ### 基础用法
65 |
66 | > ~~通过设置子节点的 `minWidth` 样式,即可设置拖拽最小宽度值。通过设置子节点样式 `flexBasis` 样式即可设置默认分割内容的占比宽度。~~
67 |
68 | - 固定初始宽度或者高度,可通过设置子节点,样式 `width: '80%'` 宽度百分百来计算。
69 | - 拖拽至最小宽度,可通过设置子节点样式 `minWidth: 30`,来达到效果
70 | - 默认情况下,不设置样式 `width`,需要将某个子节点样式设为 `flex: 1`,来自适应
71 |
72 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
73 | import React from 'react';
74 | import Split from '@uiw/react-split';
75 |
76 | const Demo = () => (
77 |
78 |
79 |
80 |
86 |
87 | Right Pane
88 |
89 |
90 | test
91 | Right Pane
92 |
93 |
94 | );
95 | export default Demo;
96 | ```
97 |
98 | ### 可用于布局
99 |
100 | 设置 `visiable={false}` 禁用拖拽栏,可用于布局。
101 |
102 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
103 | import React from 'react';
104 | import Split from '@uiw/react-split';
105 |
106 | const Demo = () => (
107 |
108 |
109 | Header
110 |
111 | Sider
112 | Content
113 |
114 | Footer
115 |
116 |
117 |
118 | Sider
119 |
120 | Header
121 | Content
122 | Footer
123 |
124 |
125 |
126 | );
127 | export default Demo;
128 | ```
129 |
130 | ### 多栏分割
131 |
132 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
133 | import React from 'react';
134 | import Split from '@uiw/react-split';
135 |
136 | const Demo = () => (
137 |
138 | Left Pane
139 | Center Pane
140 | Center Pane
141 | Right Pane
142 |
143 | );
144 | export default Demo;
145 | ```
146 |
147 | ### 线条拖拽
148 |
149 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
150 | import React from 'react';
151 | import Split from '@uiw/react-split';
152 |
153 | const Demo = () => (
154 |
155 |
156 | Left Pane
157 | Center Pane
158 | Center Pane
159 | Right Pane
160 |
161 |
162 | Left Pane
163 | Center Pane
164 | Right Pane
165 |
166 |
167 | );
168 | export default Demo;
169 | ```
170 |
171 | ### 垂直分割
172 |
173 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
174 | import React from 'react';
175 | import Split from '@uiw/react-split';
176 |
177 | const Demo = () => (
178 |
179 | Top Pane
180 | Bottom Pane
181 |
182 | );
183 | export default Demo;
184 | ```
185 |
186 | ### 嵌套使用
187 |
188 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
189 | import React from 'react';
190 | import Split from '@uiw/react-split';
191 |
192 | const Demo = () => (
193 |
194 |
195 | Top Pane
196 |
197 | Left Pane
198 | Right Pane
199 |
200 |
201 | Right Pane
202 |
203 | );
204 | export default Demo;
205 | ```
206 |
207 | ### 拖拽工具不显示
208 |
209 | 下面实例通过设置 `visiable` 的值来设置拖拽工具是否可见
210 |
211 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
212 | import React from 'react';
213 | import Split from '@uiw/react-split';
214 |
215 | const Demo = () => (
216 |
217 |
218 | Left Pane
219 | Right Pane
220 |
221 |
222 | Pane 1
223 | Pane 2
224 | Pane 3
225 | Pane 4
226 | Pane 5
227 |
228 |
229 | );
230 | export default Demo;
231 | ```
232 |
233 | ### 禁用拖拽
234 |
235 | 通过设置 `disable` 的值,禁用拖拽工具拖拽。
236 |
237 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
238 | import React from 'react';
239 | import Split from '@uiw/react-split';
240 |
241 | const Demo = () => (
242 |
243 |
244 | Left Pane
245 |
246 | Top Pane
247 | Bottom Pane
248 |
249 | Right Pane
250 |
251 |
252 | Pane 1
253 | Pane 2
254 | Pane 3
255 | Pane 4
256 | Pane 5
257 |
258 |
259 | );
260 | export default Demo;
261 | ```
262 |
263 | ### 抽屉
264 |
265 | 可拖拽左边栏宽度。
266 |
267 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
268 | import React from 'react';
269 | import Split from '@uiw/react-split';
270 | import { Menu, Button } from 'uiw';
271 |
272 | class Demo extends React.Component {
273 | constructor(props) {
274 | super(props);
275 | this.state = {
276 | width: 210,
277 | };
278 | }
279 | onClick() {
280 | this.setState({
281 | width: this.state.width === 0 ? 210 : 0,
282 | });
283 | }
284 | render() {
285 | const styl = { lineHeight: 0 };
286 | if (this.state.width === 0) {
287 | styl.width = `0%`;
288 | } else {
289 | styl.width = this.state.width;
290 | }
291 | return (
292 | <>
293 |
294 |
295 | {this.state.width === 0 ? '隐藏菜单' : '展示菜单'}
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 | Right Pane
310 |
311 | >
312 | );
313 | }
314 | }
315 | export default Demo;
316 | ```
317 |
318 | ### 支持自定义拖拽工具栏
319 |
320 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
321 | import React from 'react';
322 | import Split from '@uiw/react-split';
323 |
324 | const Demo = () => (
325 |
326 |
{
328 | return (
329 |
332 | );
333 | }}
334 | style={{ height: 100, border: '1px solid #d5d5d5', borderRadius: 3 }}
335 | >
336 | test
337 | Right Pane
338 |
339 |
340 | );
341 | export default Demo;
342 | ```
343 |
344 | ## Props
345 |
346 | ```ts
347 | export interface SplitProps extends Omit, 'onDragEnd'> {
348 | style?: React.CSSProperties;
349 | className?: string;
350 | prefixCls?: string;
351 | /**
352 | * 拖拽宽度/高度变化回调函数,宽度或者高度根据 mode 参数来确定
353 | */
354 | onDragging?: (preSize: number, nextSize: number, paneNumber: number) => void;
355 | /**
356 | * 拖拽结束的回调函数
357 | */
358 | onDragEnd?: (preSize: number, nextSize: number, paneNumber: number) => void;
359 | /** 支持自定义拖拽工具栏 */
360 | renderBar?: (props: React.HTMLAttributes) => JSX.Element;
361 | /**
362 | * 设置拖拽的工具条,为线条样式。
363 | */
364 | lineBar?: boolean;
365 | /**
366 | * 设置拖拽的工具条,是否可见
367 | */
368 | visiable?: boolean | number[];
369 | /**
370 | * 设置拖拽的工具条,禁用
371 | */
372 | disable?: boolean | number[];
373 | /**
374 | * 类型,可选值为 `horizontal` 或 `vertical`
375 | */
376 | mode?: 'horizontal' | 'vertical';
377 | }
378 | ```
379 |
380 | ## Development
381 |
382 | Runs the project in development mode.
383 |
384 | ```bash
385 | # Step 1, run first, listen to the component compile and output the .js file
386 | npm run watch
387 | npm run build
388 | # Step 2, development mode, listen to compile preview website instance
389 | npm run doc
390 | ```
391 |
392 | **production**
393 |
394 | Builds the app for production to the build folder.
395 |
396 | ```bash
397 | npm run released
398 | ```
399 |
400 | The build is minified and the filenames include the hashes.
401 | Your app is ready to be deployed!
402 |
403 | ## Contributors
404 |
405 | As always, thanks to our amazing contributors!
406 |
407 |
408 |
409 |
410 |
411 | Made with [action-contributors](https://github.com/jaywcjlove/github-action-contributors).
412 |
413 | ### License
414 |
415 | Licensed under the MIT License.
416 |
--------------------------------------------------------------------------------
/core/README.md:
--------------------------------------------------------------------------------
1 |
2 | 简体中文
3 |
4 |
5 |
6 |
Using my app is also a way to support me:
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | # Split
42 |
43 | [](https://jaywcjlove.github.io/#/sponsor)
44 | [](https://www.npmjs.com/package/@uiw/react-split)
45 | [](https://github.com/uiwjs/react-split/actions/workflows/ci.yml)
46 | [](https://uiwjs.github.io/npm-unpkg/#/pkg/@uiw/react-split/file/README.md)
47 | [](https://www.npmjs.com/package/@uiw/react-split)
48 | [](https://uiwjs.github.io/react-split/coverage/lcov-report/)
49 | [](https://gitpod.io/#https://github.com/uiwjs/react-split)
50 | [](https://github.com/uiwjs/react-split/network/dependents)
51 |
52 | A piece of content can be divided into areas that can be dragged to adjust the width or height.
53 |
54 | ```jsx
55 | import { Split } from 'uiw';
56 | ```
57 |
58 | `@uiw/react-split` extracted from the component library `uiw` can be used alone.
59 |
60 | ```jsx
61 | import Split from '@uiw/react-split';
62 | ```
63 |
64 | ### Basic usage
65 |
66 | > ~~By setting the `minWidth` style of the child node, you can set the minimum drag width value. By setting the child node style `flexBasis` style, you can set the proportion width of the default split content.~~
67 |
68 | - Fixed initial width or height, which can be calculated by setting the child node, style `width: '80%'` to 100% width.
69 | - Drag to the minimum width, you can achieve the effect by setting the child node style `minWidth: 30`.
70 | - By default, the style `width` is not set, and a child node style needs to be set to `flex: 1` to adapt
71 |
72 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
73 | import React from 'react';
74 | import Split from '@uiw/react-split';
75 |
76 | const Demo = () => (
77 |
78 |
79 |
80 |
86 |
87 | Right Pane
88 |
89 |
90 | test
91 | Right Pane
92 |
93 |
94 | );
95 | export default Demo;
96 | ```
97 |
98 | ### Available for layout
99 |
100 | Setting `visible={false}` disables the drag bar, which can be used for layout.
101 |
102 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
103 | import React from 'react';
104 | import Split from '@uiw/react-split';
105 |
106 | const Demo = () => (
107 |
108 |
109 | Header
110 |
111 | Sider
112 | Content
113 |
114 | Footer
115 |
116 |
117 |
118 | Sider
119 |
120 | Header
121 | Content
122 | Footer
123 |
124 |
125 |
126 | );
127 | export default Demo;
128 | ```
129 |
130 | ### multi-column split
131 |
132 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
133 | import React from 'react';
134 | import Split from '@uiw/react-split';
135 |
136 | const Demo = () => (
137 |
138 | Left Pane
139 | Center Pane
140 | Center Pane
141 | Right Pane
142 |
143 | );
144 | export default Demo;
145 | ```
146 |
147 | ### line drag
148 |
149 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
150 | import React from 'react';
151 | import Split from '@uiw/react-split';
152 |
153 | const Demo = () => (
154 |
155 |
156 | Left Pane
157 | Center Pane
158 | Center Pane
159 | Right Pane
160 |
161 |
162 | Left Pane
163 | Center Pane
164 | Right Pane
165 |
166 |
167 | );
168 | export default Demo;
169 | ```
170 |
171 | ### vertical split
172 |
173 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
174 | import React from 'react';
175 | import Split from '@uiw/react-split';
176 |
177 | const Demo = () => (
178 |
179 | Top Pane
180 | Bottom Pane
181 |
182 | );
183 | export default Demo;
184 | ```
185 |
186 | ### nested use
187 |
188 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
189 | import React from 'react';
190 | import Split from '@uiw/react-split';
191 |
192 | const Demo = () => (
193 |
194 |
195 | Top Pane
196 |
197 | Left Pane
198 | Right Pane
199 |
200 |
201 | Right Pane
202 |
203 | );
204 | export default Demo;
205 | ```
206 |
207 | ### Drag tool not showing
208 |
209 | The following example sets whether the drag tool is visible by setting the value of `visiable`.
210 |
211 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
212 | import React from 'react';
213 | import Split from '@uiw/react-split';
214 |
215 | const Demo = () => (
216 |
217 |
218 | Left Pane
219 | Right Pane
220 |
221 |
222 | Pane 1
223 | Pane 2
224 | Pane 3
225 | Pane 4
226 | Pane 5
227 |
228 |
229 | );
230 | export default Demo;
231 | ```
232 |
233 | ### Disable drag and drop
234 |
235 | Disable drag tool dragging by setting the value of `disable`.
236 |
237 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
238 | import React from 'react';
239 | import Split from '@uiw/react-split';
240 |
241 | const Demo = () => (
242 |
243 |
244 | Left Pane
245 |
246 | Top Pane
247 | Bottom Pane
248 |
249 | Right Pane
250 |
251 |
252 | Pane 1
253 | Pane 2
254 | Pane 3
255 | Pane 4
256 | Pane 5
257 |
258 |
259 | );
260 | export default Demo;
261 | ```
262 |
263 | ### drawer
264 |
265 | Draggable left column width.
266 |
267 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
268 | import React from 'react';
269 | import Split from '@uiw/react-split';
270 | import { Menu, Button } from 'uiw';
271 |
272 | class Demo extends React.Component {
273 | constructor(props) {
274 | super(props);
275 | this.state = {
276 | width: 210,
277 | };
278 | }
279 | onClick() {
280 | this.setState({
281 | width: this.state.width === 0 ? 210 : 0,
282 | });
283 | }
284 | render() {
285 | const styl = { lineHeight: 0 };
286 | if (this.state.width === 0) {
287 | styl.width = `0%`;
288 | } else {
289 | styl.width = this.state.width;
290 | }
291 | return (
292 | <>
293 |
294 |
295 | {this.state.width === 0 ? '隐藏菜单' : '展示菜单'}
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 | Right Pane
310 |
311 | >
312 | );
313 | }
314 | }
315 | export default Demo;
316 | ```
317 |
318 | ### Support custom drag and drop toolbar
319 |
320 | ```jsx mdx:preview&background=#fff&codeSandbox=true&codePen=true
321 | import React from 'react';
322 | import Split from '@uiw/react-split';
323 |
324 | const Demo = () => (
325 |
326 |
{
328 | return (
329 |
332 | );
333 | }}
334 | style={{ height: 100, border: '1px solid #d5d5d5', borderRadius: 3 }}
335 | >
336 | test
337 | Right Pane
338 |
339 |
340 | );
341 | export default Demo;
342 | ```
343 |
344 | ## Props
345 |
346 | ```ts
347 | export interface SplitProps extends Omit, 'onDragEnd'> {
348 | style?: React.CSSProperties;
349 | className?: string;
350 | prefixCls?: string;
351 | /**
352 | * Drag width/height change callback function,
353 | * the width or height is determined according to the mode parameter
354 | */
355 | onDragging?: (preSize: number, nextSize: number, paneNumber: number) => void;
356 | /** Callback function for dragging end */
357 | onDragEnd?: (preSize: number, nextSize: number, paneNumber: number) => void;
358 | /** Support custom drag and drop toolbar */
359 | renderBar?: (props: React.HTMLAttributes) => JSX.Element;
360 | /** Set the drag and drop toolbar as a line style. */
361 | lineBar?: boolean;
362 | /** Set the dragged toolbar, whether it is visible or not */
363 | visible?: boolean | number[];
364 | /**
365 | * @deprecated Use `visible` instead
366 | */
367 | visiable?: boolean | number[];
368 | /**
369 | * Set the drag and drop toolbar, disable
370 | */
371 | disable?: boolean | number[];
372 | /**
373 | * type, optional `horizontal` or `vertical`
374 | */
375 | mode?: 'horizontal' | 'vertical';
376 | }
377 | ```
378 |
379 | ## Development
380 |
381 | Runs the project in development mode.
382 |
383 | ```bash
384 | # Step 1, run first, listen to the component compile and output the .js file
385 | npm run watch
386 | npm run build
387 | # Step 2, development mode, listen to compile preview website instance
388 | npm run doc
389 | ```
390 |
391 | **production**
392 |
393 | Builds the app for production to the build folder.
394 |
395 | ```bash
396 | npm run released
397 | ```
398 |
399 | The build is minified and the filenames include the hashes.
400 | Your app is ready to be deployed!
401 |
402 | ## Contributors
403 |
404 | As always, thanks to our amazing contributors!
405 |
406 |
407 |
408 |
409 |
410 | Made with [contributors](https://github.com/jaywcjlove/github-action-contributors).
411 |
412 | ### License
413 |
414 | Licensed under the MIT License.
415 |
--------------------------------------------------------------------------------