├── .github
├── autolabeler.yml
├── release-drafter.yml
└── workflows
│ ├── drafter_release.yml
│ └── main.yml
├── .gitignore
├── LICENSE
├── README.md
├── README.zh-CN.md
├── examples
├── README.md
├── main.py
├── pages
│ ├── cell_slot.py
│ ├── get_selected_data.py
│ ├── pagination.py
│ └── theme.py
└── utils
│ ├── intersection.py
│ └── module_utils.py
├── nicegui_tabulator
├── __init__.py
├── core
│ ├── events.py
│ ├── libs
│ │ ├── tabulator.min.css
│ │ ├── tabulator.min.js
│ │ ├── tabulator_bootstrap3.min.css
│ │ ├── tabulator_bootstrap4.min.css
│ │ ├── tabulator_bootstrap5.min.css
│ │ ├── tabulator_bulma.min.css
│ │ ├── tabulator_materialize.min.css
│ │ ├── tabulator_midnight.min.css
│ │ ├── tabulator_modern.min.css
│ │ ├── tabulator_semanticui.min.css
│ │ ├── tabulator_simple.min.css
│ │ ├── tabulator_site.min.css
│ │ └── tabulator_site_dark.min.css
│ ├── tabulator.js
│ ├── tabulator.py
│ ├── themes.py
│ ├── types.py
│ └── utils.py
└── version.py
├── poetry.lock
├── pyproject.toml
├── scripts
└── css_processor.py
└── tests
├── __init__.py
├── conftest.py
├── pytest.ini
├── screen.py
└── test_tabulator.py
/.github/autolabeler.yml:
--------------------------------------------------------------------------------
1 | frontend: ["*.js", "*.css", "*.html"]
2 | backend: ["/app", "*.rb"]
3 | legal: ["LICENSE*", "NOTICES*"]
4 | config: .github
--------------------------------------------------------------------------------
/.github/release-drafter.yml:
--------------------------------------------------------------------------------
1 | name-template: 'v$RESOLVED_VERSION 🌈'
2 | tag-template: 'v$RESOLVED_VERSION'
3 | categories:
4 | - title: '🚀 Features'
5 | labels:
6 | - 'feature'
7 | - 'enhancement'
8 | - title: '🐛 Bug Fixes'
9 | labels:
10 | - 'fix'
11 | - 'bugfix'
12 | - 'bug'
13 | - title: '📁 Documentation'
14 | label: 'docs'
15 |
16 | exclude-labels:
17 | - 'chore'
18 |
19 | autolabeler:
20 | - label: 'feature'
21 | branch:
22 | - '/feat[-/_].+/'
23 | - label: 'docs'
24 | branch:
25 | - '/docs[-/_].+/'
26 | - label: 'chore'
27 | branch:
28 | - '/chore[-/_].+/'
29 | - label: 'bug'
30 | branch:
31 | - '/fix[-/_].+/'
32 | title:
33 | - '/fix/i'
34 |
35 | change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
36 | change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
37 | version-resolver:
38 | major:
39 | labels:
40 | - 'major'
41 | minor:
42 | labels:
43 | - 'minor'
44 | patch:
45 | labels:
46 | - 'patch'
47 | default: patch
48 | template: |
49 | ## Changes
50 |
51 | $CHANGES
--------------------------------------------------------------------------------
/.github/workflows/drafter_release.yml:
--------------------------------------------------------------------------------
1 | name: Release Drafter
2 |
3 |
4 | on:
5 | workflow_dispatch:
6 | push:
7 | # branches to consider in the event; optional, defaults to all
8 | branches:
9 | - main
10 | # pull_request event is required only for autolabeler
11 | pull_request:
12 | # Only following types are handled by the action, but one can default to all as well
13 | types: [opened, reopened, synchronize]
14 | # pull_request_target event is required for autolabeler to support PRs from forks
15 | # pull_request_target:
16 | # types: [opened, reopened, synchronize]
17 |
18 | permissions:
19 | contents: read
20 |
21 |
22 | jobs:
23 | update_release_draft:
24 | permissions:
25 | # write permission is required to create a github release
26 | contents: write
27 | # write permission is required for autolabeler
28 | # otherwise, read permission is required at least
29 | pull-requests: write
30 | runs-on: ubuntu-latest
31 | steps:
32 | # (Optional) GitHub Enterprise requires GHE_HOST variable set
33 | #- name: Set GHE_HOST
34 | # run: |
35 | # echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV
36 |
37 | # Drafts your next Release notes as Pull Requests are merged into "master"
38 | - uses: release-drafter/release-drafter@v5
39 | # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml
40 | # with:
41 | # config-name: my-config.yml
42 | # disable-autolabeler: true
43 | env:
44 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: testing
2 | run-name: test Actions
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: '0 0 * * *'
7 | pull_request:
8 | branches:
9 | - main
10 | jobs:
11 | run-all-test:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v3
15 | - uses: actions/setup-python@v4
16 | with:
17 | python-version: '3.8'
18 | - name: set up Poetry
19 | uses: abatilo/actions-poetry@v2.0.0
20 | with:
21 | poetry-version: "1.6.1"
22 | - name: install dependencies
23 | run: |
24 | set -x
25 | poetry config virtualenvs.create false
26 | poetry install
27 | python -m playwright install
28 | - run: pytest tests/
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .vscode
3 | temp
4 |
5 | # Byte-compiled / optimized / DLL files
6 | __pycache__/
7 | *.py[cod]
8 | *$py.class
9 |
10 | # C extensions
11 | *.so
12 |
13 | # Distribution / packaging
14 | .Python
15 | build/
16 | develop-eggs/
17 | dist/
18 | downloads/
19 | eggs/
20 | .eggs/
21 | lib/
22 | lib64/
23 | parts/
24 | sdist/
25 | var/
26 | wheels/
27 | share/python-wheels/
28 | *.egg-info/
29 | .installed.cfg
30 | *.egg
31 | MANIFEST
32 |
33 | # PyInstaller
34 | # Usually these files are written by a python script from a template
35 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
36 | *.manifest
37 | *.spec
38 |
39 | # Installer logs
40 | pip-log.txt
41 | pip-delete-this-directory.txt
42 |
43 | # Unit test / coverage reports
44 | htmlcov/
45 | .tox/
46 | .nox/
47 | .coverage
48 | .coverage.*
49 | .cache
50 | nosetests.xml
51 | coverage.xml
52 | *.cover
53 | *.py,cover
54 | .hypothesis/
55 | .pytest_cache/
56 | cover/
57 |
58 | # Translations
59 | *.mo
60 | *.pot
61 |
62 | # Django stuff:
63 | *.log
64 | local_settings.py
65 | db.sqlite3
66 | db.sqlite3-journal
67 |
68 | # Flask stuff:
69 | instance/
70 | .webassets-cache
71 |
72 | # Scrapy stuff:
73 | .scrapy
74 |
75 | # Sphinx documentation
76 | docs/_build/
77 |
78 | # PyBuilder
79 | .pybuilder/
80 | target/
81 |
82 | # Jupyter Notebook
83 | .ipynb_checkpoints
84 |
85 | # IPython
86 | profile_default/
87 | ipython_config.py
88 |
89 | # pyenv
90 | # For a library or package, you might want to ignore these files since the code is
91 | # intended to run in multiple environments; otherwise, check them in:
92 | # .python-version
93 |
94 | # pipenv
95 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
96 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
97 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
98 | # install all needed dependencies.
99 | #Pipfile.lock
100 |
101 | # poetry
102 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
103 | # This is especially recommended for binary packages to ensure reproducibility, and is more
104 | # commonly ignored for libraries.
105 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
106 | #poetry.lock
107 |
108 | # pdm
109 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
110 | #pdm.lock
111 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
112 | # in version control.
113 | # https://pdm.fming.dev/#use-with-ide
114 | .pdm.toml
115 |
116 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
117 | __pypackages__/
118 |
119 | # Celery stuff
120 | celerybeat-schedule
121 | celerybeat.pid
122 |
123 | # SageMath parsed files
124 | *.sage.py
125 |
126 | # Environments
127 | .env
128 | .venv
129 | env/
130 | venv/
131 | ENV/
132 | env.bak/
133 | venv.bak/
134 |
135 | # Spyder project settings
136 | .spyderproject
137 | .spyproject
138 |
139 | # Rope project settings
140 | .ropeproject
141 |
142 | # mkdocs documentation
143 | /site
144 |
145 | # mypy
146 | .mypy_cache/
147 | .dmypy.json
148 | dmypy.json
149 |
150 | # Pyre type checker
151 | .pyre/
152 |
153 | # pytype static type analyzer
154 | .pytype/
155 |
156 | # Cython debug symbols
157 | cython_debug/
158 |
159 | # PyCharm
160 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
161 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
162 | # and can be added to the global gitignore or merged into this file. For a more nuclear
163 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
164 | #.idea/
165 | pyrightconfig.json
166 | Taskfile.yml
167 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 CrystalWindSnake
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 | ## NiceGUI Tabulator
2 |
3 | This is a Python package that provides a simple way to create tables using the [Tabulator](https://github.com/olifolkerd/tabulator) library. It is built on top of the [NiceGUI](https://github.com/zauberzeug/nicegui) library.
4 |
5 |
6 |
7 |
8 | English| [简体中文](./README.zh-CN.md)
9 |
10 |
11 |
12 | ## Features
13 |
14 | - ✅Easily utilize various events and methods from the Tabulator library.
15 | - ✅Built-in themes for Bootstrap 4 and Material Design.[Example](#use_theme)
16 | - ✅Cell Slots: Place any NiceGUI component within a cell and access all its functionalities without writing string templates. [Example](#cell-slot)
17 | - ✅Built-in support for creating tables from pandas data. [Example](#from_pandas)
18 | - 🔲Built-in support for downloading in formats such as Excel, PDF, etc.
19 | - 🔲Row Slots
20 |
21 |
22 | ## Installation
23 |
24 | ```
25 | pip install nicegui-tabulator
26 | ```
27 |
28 | ## Usage
29 |
30 | ```python
31 | from nicegui_tabulator import tabulator
32 | from nicegui import ui
33 |
34 | tabledata = [
35 | {"id": 1, "name": "Oli Bob", "age": "12", "col": "red", "dob": ""},
36 | {"id": 2, "name": "Mary May", "age": "1", "col": "blue", "dob": "14/05/1982"},
37 | {
38 | "id": 3,
39 | "name": "Christine Lobowski",
40 | "age": "42",
41 | "col": "green",
42 | "dob": "22/05/1982",
43 | },
44 | {
45 | "id": 4,
46 | "name": "Brendon Philips",
47 | "age": "125",
48 | "col": "orange",
49 | "dob": "01/08/1980",
50 | },
51 | {
52 | "id": 5,
53 | "name": "Margret Marmajuke",
54 | "age": "16",
55 | "col": "yellow",
56 | "dob": "31/01/1999",
57 | },
58 | ]
59 |
60 | table_config = {
61 | "height": 205,
62 | "data": tabledata,
63 | "columns": [
64 | {"title": "Name", "field": "name", "width": 150, "headerFilter": "input"},
65 | {"title": "Age", "field": "age", "hozAlign": "left", "formatter": "progress"},
66 | {"title": "Favourite Color", "field": "col"},
67 | {
68 | "title": "Date Of Birth",
69 | "field": "dob",
70 | "sorter": "date",
71 | "hozAlign": "center",
72 | },
73 | ],
74 | }
75 |
76 | table = tabulator(table_config).on_event("rowClick", lambda e: ui.notify(e))
77 |
78 |
79 | def on_sort():
80 | table.run_table_method(
81 | "setSort",
82 | [
83 | {"column": "name", "dir": "desc"},
84 | {"column": "age", "dir": "asc"},
85 | ],
86 | )
87 |
88 |
89 | ui.button("sort", on_click=on_sort)
90 |
91 | ```
92 |
93 | ---
94 |
95 | ## API
96 |
97 | ### from_pandas
98 | create from pandas dataframe:
99 |
100 | ```python
101 | from nicegui_tabulator import tabulator
102 | import pandas as pd
103 |
104 |
105 | df = pd.DataFrame(
106 | {
107 | "name": ["Alice", "Bob", "Charlie"],
108 | "age": [25, 30, 35],
109 | "color": ["blue", "red", "green"],
110 | "dob": [None, "2021-01-01", "2021-02-02"],
111 | }
112 | )
113 |
114 |
115 | tabulator.from_pandas(df)
116 | ```
117 |
118 | ---
119 |
120 | You can update column configurations immediately after creating the table.
121 |
122 |
123 | ```python
124 | tabulator.from_pandas(df).update_column_definition(
125 | "age", {"hozAlign": "left", "formatter": "progress"}
126 | )
127 | ```
128 |
129 |
130 | ---
131 |
132 | ### Cell Slot
133 |
134 | Cell Slots allow you to place any NiceGUI component within a cell and access all its functionalities without writing string templates.
135 |
136 | ```python
137 | from nicegui import ui
138 | from nicegui_tabulator import tabulator, CellSlotProps
139 |
140 |
141 | tabledata = [
142 | {"id": 1, "name": "bar", "age": "12"},
143 | {"id": 2, "name": "foo", "age": "1"},
144 | ]
145 |
146 | table_config = {
147 | "data": tabledata,
148 | "columns": [
149 | {"title": "Name", "field": "name"},
150 | {"title": "Age", "field": "age"},
151 | ],
152 | "printConfig": {
153 | "formatCells": False,
154 | },
155 | }
156 |
157 | table = tabulator(table_config)
158 |
159 |
160 | @table.add_cell_slot("name")
161 | def _(props: CellSlotProps):
162 | # This function is called when rendering the cell of the table, and it receives the properties of the cell,
163 | # including the value of the cell, row index, column name, etc.
164 | # props.update_value(new_value) can update the value of the cell (updates server-side only, the client needs to manually refresh `sync_data_to_client`).
165 | ui.input(value=props.value, on_change=lambda e: props.update_value(e.value))
166 |
167 |
168 | @table.add_cell_slot("age")
169 | def _(props: CellSlotProps):
170 | ui.number(value=props.value, min=0, max=100,on_change=lambda e: props.update_value(e.value))
171 |
172 |
173 | def print_table_data():
174 | table.sync_data_to_client()
175 | table.run_table_method("print", True)
176 |
177 | ui.button("print table data", on_click=print_table_data)
178 | ```
179 |
180 | ---
181 |
182 | ### use_theme
183 |
184 | ```python
185 | from nicegui_tabulator import tabulator, use_theme
186 |
187 | # use the theme for all clients
188 | use_theme('bootstrap4')
189 |
190 | # use the theme only for the current client
191 | use_theme('bootstrap4', shared=False)
192 |
193 | @ui.page('/')
194 | def my_page():
195 | # use the theme only for this page
196 | use_theme('bootstrap4')
197 | ```
--------------------------------------------------------------------------------
/README.zh-CN.md:
--------------------------------------------------------------------------------
1 | ## NiceGUI Tabulator
2 |
3 | 这是一个Python包,它通过 [Tabulator](https://github.com/olifolkerd/tabulator) 库提供了一种简单的方式来创建表格。该包构建于 [NiceGUI](https://github.com/zauberzeug/nicegui) 库之上。
4 |
5 |
6 |
7 |
8 |
9 | 简体中文| [English](./README.md)
10 |
11 |
12 |
13 | ## 功能
14 |
15 | - ✅轻松使用 Tabulator 库各种事件、方法
16 | - ✅内置主题:支持 bootstrap4、bulma、materialize、semantic-ui 等。[示例](#use_theme)
17 | - ✅单元格插槽:可以在单元格中放入任意 nicegui 组件并获得所有功能,而无须编写字符串模板。[示例](#cell-slot)
18 | - ✅内置支持从 pandas 数据创建表格。[示例](#from_pandas)
19 | - 🔲内置支持 excel、pdf 等格式下载
20 | - 🔲行插槽
21 |
22 | ## 安装
23 |
24 | ```
25 | pip install nicegui-tabulator
26 | ```
27 |
28 | ## 使用
29 |
30 | ```python
31 | from nicegui_tabulator import tabulator
32 | from nicegui import ui
33 |
34 | tabledata = [
35 | {"id": 1, "name": "Oli Bob", "age": "12", "col": "red", "dob": ""},
36 | {"id": 2, "name": "Mary May", "age": "1", "col": "blue", "dob": "14/05/1982"},
37 | {
38 | "id": 3,
39 | "name": "Christine Lobowski",
40 | "age": "42",
41 | "col": "green",
42 | "dob": "22/05/1982",
43 | },
44 | {
45 | "id": 4,
46 | "name": "Brendon Philips",
47 | "age": "125",
48 | "col": "orange",
49 | "dob": "01/08/1980",
50 | },
51 | {
52 | "id": 5,
53 | "name": "Margret Marmajuke",
54 | "age": "16",
55 | "col": "yellow",
56 | "dob": "31/01/1999",
57 | },
58 | ]
59 |
60 | table_config = {
61 | "height": 205,
62 | "data": tabledata,
63 | "columns": [
64 | {"title": "Name", "field": "name", "width": 150, "headerFilter": "input"},
65 | {"title": "Age", "field": "age", "hozAlign": "left", "formatter": "progress"},
66 | {"title": "Favourite Color", "field": "col"},
67 | {
68 | "title": "Date Of Birth",
69 | "field": "dob",
70 | "sorter": "date",
71 | "hozAlign": "center",
72 | },
73 | ],
74 | }
75 |
76 | table = tabulator(table_config).on_event("rowClick", lambda e: ui.notify(e))
77 |
78 |
79 | def on_sort():
80 | table.run_table_method(
81 | "setSort",
82 | [
83 | {"column": "name", "dir": "desc"},
84 | {"column": "age", "dir": "asc"},
85 | ],
86 | )
87 |
88 |
89 | ui.button("sort", on_click=on_sort)
90 |
91 | ```
92 |
93 | ---
94 |
95 | ## API
96 |
97 | ### from_pandas
98 | 从 pandas 数据创建表格。
99 |
100 | ```python
101 | from nicegui_tabulator import tabulator
102 | import pandas as pd
103 |
104 |
105 | df = pd.DataFrame(
106 | {
107 | "name": ["Alice", "Bob", "Charlie"],
108 | "age": [25, 30, 35],
109 | "color": ["blue", "red", "green"],
110 | "dob": [None, "2021-01-01", "2021-02-02"],
111 | }
112 | )
113 |
114 |
115 | tabulator.from_pandas(df)
116 | ```
117 |
118 | ---
119 |
120 | 你可以在创建表格之后立即更新列配置。
121 |
122 | ```python
123 | tabulator.from_pandas(df).update_column_definition(
124 | "age", {"hozAlign": "left", "formatter": "progress"}
125 | )
126 | ```
127 |
128 |
129 | ### cell-slot
130 |
131 | 单元格插槽允许你在单元格中放入任意 nicegui 组件并获得所有功能,而无须编写字符串模板。
132 |
133 | ```python
134 | from nicegui import ui
135 | from nicegui_tabulator import tabulator, CellSlotProps
136 |
137 |
138 | tabledata = [
139 | {"id": 1, "name": "bar", "age": "12"},
140 | {"id": 2, "name": "foo", "age": "1"},
141 | ]
142 |
143 | table_config = {
144 | "data": tabledata,
145 | "columns": [
146 | {"title": "Name", "field": "name"},
147 | {"title": "Age", "field": "age"},
148 | ],
149 | "printConfig": {
150 | "formatCells": False,
151 | },
152 | }
153 |
154 | table = tabulator(table_config)
155 |
156 |
157 | @table.add_cell_slot("name")
158 | def _(props: CellSlotProps):
159 | # 当表格渲染单元格时,会调用这个函数,并传入单元格的属性,包括单元格的值、行索引、列名等信息。
160 | # props.update_value(new_value) 可以更新单元格的值(只更新服务端,客户端需要手动刷新 `sync_data_to_client`)。
161 | ui.input(value=props.value, on_change=lambda e: props.update_value(e.value))
162 |
163 |
164 | @table.add_cell_slot("age")
165 | def _(props: CellSlotProps):
166 | ui.number(value=props.value, min=0, max=100,on_change=lambda e: props.update_value(e.value))
167 |
168 |
169 | def print_table_data():
170 | table.sync_data_to_client()
171 | table.run_table_method("print", True)
172 |
173 |
174 | ui.button("print table data", on_click=print_table_data)
175 |
176 |
177 | ```
178 |
179 | ---
180 |
181 | ### use_theme
182 |
183 | ```python
184 | from nicegui_tabulator import tabulator, use_theme
185 |
186 | # 所有客户端都使用 bootstrap4 主题
187 | use_theme('bootstrap4')
188 |
189 | # 仅当前客户端使用 bootstrap4 主题
190 | use_theme('bootstrap4', shared=False)
191 |
192 | @ui.page('/')
193 | def my_page():
194 | # 仅本页面使用 bootstrap4 主题
195 | use_theme('bootstrap4')
196 | ```
197 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | ## usage
2 |
3 | ```shell
4 | python -m examples.main
5 | ```
--------------------------------------------------------------------------------
/examples/main.py:
--------------------------------------------------------------------------------
1 | from nicegui import ui
2 | from .utils.intersection import Intersection
3 | from .utils.module_utils import (
4 | load_and_execute_module,
5 | get_page_module_names,
6 | get_source_code,
7 | )
8 | import sys
9 |
10 | sys.path.append(r"e:\working\github\nicegui-tabulator\examples\pages")
11 |
12 |
13 | ui.context.client.content.classes("items-center")
14 |
15 | modules = get_page_module_names()
16 |
17 |
18 | for module in modules:
19 |
20 | @ui.page(f"/{module}", title=module)
21 | def _(module=module):
22 | load_and_execute_module(module, "")
23 |
24 |
25 | for module in modules:
26 | with ui.card():
27 | ui.markdown(f"## {module}")
28 | iframe = (
29 | ui.element("iframe").classes("w-[80vw] h-[50vh]").props(f'src="/{module}"')
30 | )
31 |
32 | with ui.expansion("source code").classes("w-full").props(
33 | "header-class='outline'"
34 | ):
35 | ui.code(get_source_code(module)).classes("w-full")
36 |
37 |
38 | ui.run(title="Tabulator Example", port=8999)
39 |
--------------------------------------------------------------------------------
/examples/pages/cell_slot.py:
--------------------------------------------------------------------------------
1 | from nicegui_tabulator import tabulator, use_theme, CellSlotProps
2 | from nicegui import ui
3 |
4 | use_theme("semanticui", shared=False)
5 |
6 |
7 | chart_data = {
8 | "bar": [
9 | {"type": "bar", "name": "Alpha", "data": [0.1, 0.2]},
10 | {"type": "bar", "name": "Beta", "data": [0.3, 0.4]},
11 | ],
12 | "foo": [
13 | {"type": "bar", "name": "Alpha", "data": [20, 50]},
14 | {"type": "bar", "name": "Beta", "data": [39, 20]},
15 | ],
16 | }
17 |
18 | tabledata = [
19 | {"id": 1, "name": "bar", "age": "12", "chart": None},
20 | {"id": 2, "name": "foo", "age": "1", "chart": None},
21 | ]
22 |
23 | table_config = {
24 | "data": tabledata,
25 | "layout": "fitDataStretch",
26 | "columnDefaults": {"vertAlign": "middle"},
27 | "columns": [
28 | {"title": "Name", "field": "name"},
29 | {"title": "Age", "field": "age"},
30 | {"title": "Chart", "field": "chart", "widthGrow": 1},
31 | ],
32 | "printConfig": {
33 | "formatCells": False,
34 | },
35 | }
36 |
37 |
38 | table = tabulator(table_config)
39 |
40 |
41 | @table.add_cell_slot("name")
42 | def _(props: CellSlotProps):
43 | def on_blur():
44 | props.update_to_client()
45 |
46 | ui.input(value=props.value, on_change=lambda e: props.update_value(e.value)).on(
47 | "blur", on_blur
48 | )
49 |
50 |
51 | @table.add_cell_slot("chart")
52 | def _(props: CellSlotProps):
53 | series_data = chart_data[props.row["name"]]
54 |
55 | ui.echart(
56 | {
57 | "xAxis": {"type": "value"},
58 | "yAxis": {"type": "category", "data": ["A", "B"], "inverse": True},
59 | "legend": {"textStyle": {"color": "gray"}},
60 | "series": series_data,
61 | }
62 | )
63 |
64 |
65 | if __name__ in {"__main__", "__mp_main__"}:
66 | ui.run()
67 |
--------------------------------------------------------------------------------
/examples/pages/get_selected_data.py:
--------------------------------------------------------------------------------
1 | from nicegui_tabulator import tabulator
2 | from nicegui import ui
3 |
4 | tabledata = [
5 | {
6 | "id": 1,
7 | "name": "Oli Bob",
8 | "age": "12",
9 | },
10 | {
11 | "id": 2,
12 | "name": "Mary May",
13 | "age": "1",
14 | },
15 | {
16 | "id": 3,
17 | "name": "Christine Lobowski",
18 | "age": "42",
19 | },
20 | ]
21 |
22 | table_config = {
23 | "height": 205,
24 | "data": tabledata,
25 | "rowHeader": {
26 | "formatter": "rowSelection",
27 | "titleFormatter": "rowSelection",
28 | },
29 | "columns": [
30 | {
31 | "title": "Name",
32 | "field": "name",
33 | },
34 | {
35 | "title": "Age",
36 | "field": "age",
37 | },
38 | ],
39 | }
40 |
41 |
42 | table = tabulator(table_config)
43 |
44 |
45 | async def get_rows():
46 | rows = await table.get_selected_data()
47 | ui.notify(rows)
48 |
49 |
50 | ui.button("Get Selected Rows", on_click=get_rows)
51 |
52 |
53 | if __name__ in {"__main__", "__mp_main__"}:
54 | ui.run()
55 |
--------------------------------------------------------------------------------
/examples/pages/pagination.py:
--------------------------------------------------------------------------------
1 | from nicegui_tabulator import tabulator, use_theme
2 | from nicegui import ui
3 |
4 |
5 | use_theme("semanticui", shared=False)
6 |
7 | columns = [{"title": f"col{i}", "field": f"col{i}"} for i in range(30)]
8 | columns[0]["frozen"] = True # type: ignore
9 |
10 | tabledata = [
11 | {"id": i + 1, **{col["field"]: f"row{i+1}-{col['field']}" for col in columns}}
12 | for i in range(100)
13 | ]
14 |
15 | langs = {
16 | "cn": {
17 | "pagination": {
18 | "page_size": "每页数量",
19 | "page_title": "显示页面",
20 | "first": "首页",
21 | "first_title": "第一页",
22 | "last": "末页",
23 | "last_title": "最后一页",
24 | "prev": "上一页",
25 | "prev_title": "上一页",
26 | "next": "下一页",
27 | "next_title": "下一页",
28 | "all": "全部",
29 | "counter": {
30 | "showing": "正在显示",
31 | "of": "共",
32 | "rows": "条记录",
33 | "pages": "页",
34 | },
35 | }
36 | }
37 | }
38 |
39 | table_config = {
40 | "rowHeader": True,
41 | "data": tabledata,
42 | # "layout": "fitDataFill",
43 | "maxHeight": "50vh",
44 | "columns": columns,
45 | "pagination": "local",
46 | "paginationSize": 6,
47 | "paginationSizeSelector": [3, 6, 8, 10],
48 | "movableColumns": True,
49 | "paginationCounter": "rows",
50 | "langs": langs,
51 | "locale": "cn",
52 | }
53 |
54 | tabulator(table_config)
55 |
56 |
57 | if __name__ in {"__main__", "__mp_main__"}:
58 | ui.run()
59 |
--------------------------------------------------------------------------------
/examples/pages/theme.py:
--------------------------------------------------------------------------------
1 | from nicegui_tabulator import tabulator, use_theme
2 | from nicegui import ui
3 |
4 | use_theme("semanticui", shared=False)
5 |
6 |
7 | tabledata = [
8 | {"id": 1, "name": "bar", "age": "12"},
9 | {"id": 2, "name": "foo", "age": "1"},
10 | ]
11 |
12 | table_config = {
13 | "data": tabledata,
14 | "columns": [
15 | {"title": "Name", "field": "name"},
16 | {"title": "Age", "field": "age"},
17 | ],
18 | "printConfig": {
19 | "formatCells": False,
20 | },
21 | }
22 |
23 |
24 | def select_theme():
25 | use_theme(theme.value or "default", shared=False)
26 |
27 |
28 | theme = ui.toggle(
29 | [
30 | "default",
31 | "bootstrap3",
32 | "bootstrap4",
33 | "bootstrap5",
34 | "bulma",
35 | "materialize",
36 | "midnight",
37 | "modern",
38 | "semanticui",
39 | "simple",
40 | "site",
41 | "site_dark",
42 | ],
43 | value="semanticui",
44 | on_change=select_theme,
45 | ).props("no-caps")
46 |
47 | tabulator(table_config)
48 |
49 |
50 | if __name__ in {"__main__", "__mp_main__"}:
51 | ui.run()
52 |
--------------------------------------------------------------------------------
/examples/utils/intersection.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Optional, Callable
2 | from nicegui import ui
3 | from nicegui.events import UiEventArguments, GenericEventArguments, handle_event
4 | from nicegui.dataclasses import KWONLY_SLOTS
5 |
6 | from dataclasses import dataclass
7 |
8 |
9 | @dataclass(**KWONLY_SLOTS)
10 | class VisibilityEventArguments(UiEventArguments):
11 | value: bool
12 |
13 |
14 | class Intersection(ui.element):
15 | def __init__(
16 | self,
17 | *,
18 | once: bool = False,
19 | on_visibility: Optional[Callable[..., Any]] = None,
20 | ) -> None:
21 | """Intersection Quasar element
22 |
23 | Args:
24 | on_visibility (Optional[Callable[..., Any]], optional): _description_. Defaults to None.
25 | """
26 | super().__init__("q-intersection")
27 |
28 | self._props["once"] = once
29 |
30 | if on_visibility:
31 | self.on_visibility(on_visibility)
32 |
33 | def on_visibility(self, callback: Callable[..., Any]):
34 | def handle_visibility(e: GenericEventArguments) -> None:
35 | handle_event(
36 | callback,
37 | VisibilityEventArguments(
38 | sender=self,
39 | client=self.client,
40 | value=e.args,
41 | ),
42 | )
43 |
44 | return self.on("visibility", handle_visibility)
45 |
--------------------------------------------------------------------------------
/examples/utils/module_utils.py:
--------------------------------------------------------------------------------
1 | import importlib
2 | from pathlib import Path
3 | import sys
4 |
5 |
6 | PAGES_DIR = Path(__file__).parent.joinpath("../pages")
7 |
8 |
9 | def load_and_execute_module(module_name, package=None):
10 | try:
11 | if module_name in sys.modules:
12 | module = importlib.reload(sys.modules[module_name])
13 | else:
14 | module = importlib.import_module(module_name, package=package)
15 | print(f"Module {module_name} has been loaded and executed.")
16 | return module
17 | except ModuleNotFoundError as e:
18 | print(f"Module {module_name} not found: {e}")
19 | return None
20 | except Exception as e:
21 | print(f"Error loading module {module_name}: {e}")
22 | return None
23 |
24 |
25 | def get_page_module_names():
26 | return [p.stem for p in PAGES_DIR.glob("*.py")]
27 |
28 |
29 | def get_source_code(module_name: str):
30 | module_path = PAGES_DIR.joinpath(f"{module_name}.py")
31 | return module_path.read_text(encoding="utf-8")
32 |
--------------------------------------------------------------------------------
/nicegui_tabulator/__init__.py:
--------------------------------------------------------------------------------
1 | from .version import __version__
2 | from .core.tabulator import Tabulator as tabulator
3 | from .core.types import CellSlotProps
4 | from .core.themes import use_theme
5 |
6 | __all__ = ["__version__", "tabulator", "CellSlotProps", "use_theme"]
7 |
--------------------------------------------------------------------------------
/nicegui_tabulator/core/events.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | from dataclasses import dataclass
4 | from typing import (
5 | Any,
6 | )
7 |
8 | from nicegui.events import UiEventArguments
9 | from nicegui.dataclasses import KWONLY_SLOTS
10 |
11 |
12 | @dataclass(**KWONLY_SLOTS)
13 | class TabulatorEventArguments(UiEventArguments):
14 | args: Any
15 |
--------------------------------------------------------------------------------
/nicegui_tabulator/core/libs/tabulator_bulma.min.css:
--------------------------------------------------------------------------------
1 | .tabulator{background-color:#fff;border:1px solid #999;font-size:16px;overflow:hidden;position:relative;text-align:left;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}.tabulator[tabulator-layout=fitDataFill] .tabulator-tableholder .tabulator-table{min-width:100%}.tabulator[tabulator-layout=fitDataTable]{display:inline-block}.tabulator.tabulator-block-select,.tabulator.tabulator-ranges .tabulator-cell:not(.tabulator-editing){user-select:none}.tabulator .tabulator-header{background-color:transparent;border-bottom:1px solid #999;box-sizing:border-box;color:#363636;font-weight:700;outline:none;overflow:hidden;position:relative;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;white-space:nowrap;width:100%}.tabulator .tabulator-header.tabulator-header-hidden{display:none}.tabulator .tabulator-header .tabulator-header-contents{overflow:hidden;position:relative}.tabulator .tabulator-header .tabulator-header-contents .tabulator-headers{display:inline-block}.tabulator .tabulator-header .tabulator-col{background:transparent;border-right:1px solid #aaa;box-sizing:border-box;display:inline-flex;flex-direction:column;justify-content:flex-start;overflow:hidden;position:relative;text-align:left;vertical-align:bottom}.tabulator .tabulator-header .tabulator-col.tabulator-moving{background:transparent;border:1px solid #999;pointer-events:none;position:absolute}.tabulator .tabulator-header .tabulator-col.tabulator-range-highlight{background-color:#d6d6d6;color:#000}.tabulator .tabulator-header .tabulator-col.tabulator-range-selected{background-color:#009e86;color:#fff}.tabulator .tabulator-header .tabulator-col .tabulator-col-content{box-sizing:border-box;padding:4px;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button{padding:0 8px}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button:hover{cursor:pointer;opacity:.6}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title-holder{position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title{box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title.tabulator-col-title-wrap{text-overflow:clip;white-space:normal}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor{background:#fff;border:1px solid #999;box-sizing:border-box;padding:1px;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-header-popup-button+.tabulator-title-editor{width:calc(100% - 22px)}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{align-items:center;bottom:0;display:flex;position:absolute;right:4px;top:0}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #bbb;border-left:6px solid transparent;border-right:6px solid transparent;height:0;width:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{border-top:1px solid #aaa;display:flex;margin-right:-1px;overflow:hidden;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter{box-sizing:border-box;margin-top:2px;position:relative;text-align:center;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea{height:auto!important}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg{margin-top:3px}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear{height:0;width:0}.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-right:25px}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable.tabulator-col-sorter-element:hover{background-color:transparent;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter{color:#bbb}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-bottom:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #bbb;border-top:none}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter{color:#363636}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-bottom:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #363636;border-top:none}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter{color:#363636}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-top:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:none;border-top:6px solid #363636;color:#363636}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title{align-items:center;display:flex;justify-content:center;text-orientation:mixed;writing-mode:vertical-rl}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title{transform:rotate(180deg)}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title{padding-right:0;padding-top:20px}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title{padding-bottom:20px;padding-right:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-sorter{bottom:auto;justify-content:center;left:0;right:0;top:4px}.tabulator .tabulator-header .tabulator-frozen{left:0;position:sticky;z-index:11}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left{border-right:2px solid #aaa}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right{border-left:2px solid #aaa}.tabulator .tabulator-header .tabulator-calcs-holder{background:hsla(0,0%,5%,0)!important;border-bottom:1px solid #aaa;border-top:1px solid #aaa;box-sizing:border-box;display:inline-block}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row{background:hsla(0,0%,5%,0)!important}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-header .tabulator-frozen-rows-holder{display:inline-block}.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty{display:none}.tabulator .tabulator-tableholder{-webkit-overflow-scrolling:touch;overflow:auto;position:relative;white-space:nowrap;width:100%}.tabulator .tabulator-tableholder:focus{outline:none}.tabulator .tabulator-tableholder .tabulator-placeholder{align-items:center;box-sizing:border-box;display:flex;justify-content:center;min-width:100%;width:100%}.tabulator .tabulator-tableholder .tabulator-placeholder[tabulator-render-mode=virtual]{min-height:100%}.tabulator .tabulator-tableholder .tabulator-placeholder .tabulator-placeholder-contents{color:#ccc;display:inline-block;font-size:20px;font-weight:700;padding:10px;text-align:center;white-space:normal}.tabulator .tabulator-tableholder .tabulator-table{background-color:transparent;color:#363636;display:inline-block;overflow:visible;position:relative;white-space:nowrap}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs{background:#ededed!important;font-weight:700}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top{border-bottom:2px solid #aaa}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom{border-top:2px solid #aaa}.tabulator .tabulator-tableholder .tabulator-range-overlay{inset:0;pointer-events:none;position:absolute;z-index:10}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range{border:1px solid #009e86;box-sizing:border-box;position:absolute}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{background-color:#009e86;border-radius:999px;bottom:-3px;content:"";height:6px;position:absolute;right:-3px;width:6px}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range-cell-active{border:2px solid #009e86;box-sizing:border-box;position:absolute}.tabulator .tabulator-footer{background-color:transparent;border-top:1px solid #999;color:#363636;font-weight:700;user-select:none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;white-space:nowrap}.tabulator .tabulator-footer .tabulator-footer-contents{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:5px 10px}.tabulator .tabulator-footer .tabulator-footer-contents:empty{display:none}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs{margin-top:-5px;overflow-x:auto}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab{border:1px solid #999;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top:none;display:inline-block;font-size:.9em;padding:5px}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab:hover{cursor:pointer;opacity:.7}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active{background:#fff}.tabulator .tabulator-footer .tabulator-calcs-holder{background:hsla(0,0%,5%,0)!important;border-bottom:1px solid #aaa;border-top:1px solid #aaa;box-sizing:border-box;overflow:hidden;text-align:left;width:100%}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row{background:hsla(0,0%,5%,0)!important;display:inline-block}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-footer .tabulator-calcs-holder:only-child{border-bottom:none;margin-bottom:-5px}.tabulator .tabulator-footer>*+.tabulator-page-counter{margin-left:10px}.tabulator .tabulator-footer .tabulator-page-counter{font-weight:400}.tabulator .tabulator-footer .tabulator-paginator{color:#363636;flex:1;font-family:inherit;font-size:inherit;font-weight:inherit;text-align:right}.tabulator .tabulator-footer .tabulator-page-size{border:1px solid #dbdbdb;border-radius:3px;display:inline-block;margin:0 5px;padding:2px 5px}.tabulator .tabulator-footer .tabulator-pages{margin:0 7px}.tabulator .tabulator-footer .tabulator-page{background:hsla(0,0%,100%,.2);border-radius:3px;display:inline-block;margin:0 2px;padding:2px 5px}.tabulator .tabulator-footer .tabulator-page.active{color:#d00}.tabulator .tabulator-footer .tabulator-page:disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-footer .tabulator-page:not(disabled):hover{background:rgba(0,0,0,.2);color:#fff;cursor:pointer}}.tabulator .tabulator-col-resize-handle{display:inline-block;margin-left:-3px;margin-right:-3px;position:relative;vertical-align:middle;width:6px;z-index:11}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-col-resize-handle:hover{cursor:ew-resize}}.tabulator .tabulator-col-resize-handle:last-of-type{margin-right:0;width:3px}.tabulator .tabulator-col-resize-guide{background-color:#999;height:100%;margin-left:-.5px;opacity:.5;position:absolute;top:0;width:4px}.tabulator .tabulator-row-resize-guide{background-color:#999;height:4px;left:0;margin-top:-.5px;opacity:.5;position:absolute;width:100%}.tabulator .tabulator-alert{align-items:center;background:rgba(0,0,0,.4);display:flex;height:100%;left:0;position:absolute;text-align:center;top:0;width:100%;z-index:100}.tabulator .tabulator-alert .tabulator-alert-msg{background:#fff;border-radius:10px;display:inline-block;font-size:16px;font-weight:700;margin:0 auto;padding:10px 20px}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-msg{border:4px solid #333;color:#000}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-error{border:4px solid #d00;color:#590000}.tabulator-row{background-color:transparent;box-sizing:border-box;min-height:24px;position:relative}.tabulator-row.tabulator-row-even{background-color:#fafafa}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selectable:hover{background-color:#fafafa;cursor:pointer}}.tabulator-row.tabulator-selected{background-color:#00d1b2}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selected:hover{background-color:#769bcc;cursor:pointer}}.tabulator-row.tabulator-row-moving{background:#fff;border:1px solid #000}.tabulator-row.tabulator-moving{border-bottom:1px solid #aaa;border-top:1px solid #aaa;pointer-events:none;position:absolute;z-index:15}.tabulator-row.tabulator-range-highlight .tabulator-cell.tabulator-range-row-header{background-color:#d6d6d6;color:#000}.tabulator-row.tabulator-range-highlight.tabulator-range-selected .tabulator-cell.tabulator-range-row-header,.tabulator-row.tabulator-range-selected .tabulator-cell.tabulator-range-row-header{background-color:#009e86;color:#fff}.tabulator-row .tabulator-row-resize-handle{bottom:0;height:5px;left:0;position:absolute;right:0}.tabulator-row .tabulator-row-resize-handle.prev{bottom:auto;top:0}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-row-resize-handle:hover{cursor:ns-resize}}.tabulator-row .tabulator-responsive-collapse{border-bottom:1px solid #aaa;border-top:1px solid #aaa;box-sizing:border-box;padding:5px}.tabulator-row .tabulator-responsive-collapse:empty{display:none}.tabulator-row .tabulator-responsive-collapse table{font-size:16px}.tabulator-row .tabulator-responsive-collapse table tr td{position:relative}.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type{padding-right:10px}.tabulator-row .tabulator-cell{border-right:1px solid #aaa;box-sizing:border-box;display:inline-block;outline:none;overflow:hidden;padding:4px;position:relative;text-overflow:ellipsis;vertical-align:middle;white-space:nowrap}.tabulator-row .tabulator-cell.tabulator-row-header{border-bottom:1px solid #aaa;border-right:1px solid #999}.tabulator-row .tabulator-cell.tabulator-frozen{background-color:inherit;display:inline-block;left:0;position:sticky;z-index:11}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-right:2px solid #aaa}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-left:2px solid #aaa}.tabulator-row .tabulator-cell.tabulator-editing{border:1px solid #1d68cd;outline:none;padding:0}.tabulator-row .tabulator-cell.tabulator-editing input,.tabulator-row .tabulator-cell.tabulator-editing select{background:transparent;border:1px;outline:none}.tabulator-row .tabulator-cell.tabulator-validation-fail{border:1px solid #d00}.tabulator-row .tabulator-cell.tabulator-validation-fail input,.tabulator-row .tabulator-cell.tabulator-validation-fail select{background:transparent;border:1px;color:#d00}.tabulator-row .tabulator-cell.tabulator-row-handle{align-items:center;display:inline-flex;justify-content:center;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box{width:80%}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar{background:#666;height:3px;margin-top:2px;width:100%}.tabulator-row .tabulator-cell.tabulator-range-selected:not(.tabulator-range-only-cell-selected):not(.tabulator-range-row-header){background-color:#00d1b2}.tabulator-row .tabulator-cell .tabulator-data-tree-branch-empty{display:inline-block;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-branch{border-bottom:2px solid #aaa;border-bottom-left-radius:1px;border-left:2px solid #aaa;display:inline-block;height:9px;margin-right:5px;margin-top:-9px;vertical-align:middle;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-control{align-items:center;background:rgba(0,0,0,.1);border:1px solid #363636;border-radius:2px;display:inline-flex;height:11px;justify-content:center;margin-right:5px;overflow:hidden;vertical-align:middle;width:11px}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover{background:rgba(0,0,0,.2);cursor:pointer}}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:transparent;display:inline-block;height:7px;position:relative;width:1px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{background:#363636;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:#363636;display:inline-block;height:7px;position:relative;width:1px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:#363636;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle{align-items:center;background:#666;border-radius:20px;color:transparent;display:inline-flex;font-size:1.1em;font-weight:700;height:15px;justify-content:center;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;width:15px}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover{cursor:pointer;opacity:.7}}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close{display:initial}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open{display:none}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle svg{stroke:transparent}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close{display:none}.tabulator-row .tabulator-cell .tabulator-traffic-light{border-radius:14px;display:inline-block;height:14px;width:14px}.tabulator-row.tabulator-group{background:#ccc;border-right:1px solid #aaa;box-sizing:border-box;font-weight:700;min-width:100%;padding:5px 5px 5px 10px}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-group:hover{background-color:rgba(0,0,0,.1);cursor:pointer}}.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow{border-bottom:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #363636;margin-right:10px}.tabulator-row.tabulator-group.tabulator-group-level-1{padding-left:30px}.tabulator-row.tabulator-group.tabulator-group-level-2{padding-left:50px}.tabulator-row.tabulator-group.tabulator-group-level-3{padding-left:70px}.tabulator-row.tabulator-group.tabulator-group-level-4{padding-left:90px}.tabulator-row.tabulator-group.tabulator-group-level-5{padding-left:110px}.tabulator-row.tabulator-group .tabulator-group-toggle{display:inline-block}.tabulator-row.tabulator-group .tabulator-arrow{border-bottom:6px solid transparent;border-left:6px solid #363636;border-right:0;border-top:6px solid transparent;display:inline-block;height:0;margin-right:16px;vertical-align:middle;width:0}.tabulator-row.tabulator-group span{color:#d00;margin-left:10px}.tabulator-toggle{background:#dcdcdc;border:1px solid #ccc;box-sizing:border-box;display:flex;flex-direction:row}.tabulator-toggle.tabulator-toggle-on{background:#1c6cc2}.tabulator-toggle .tabulator-toggle-switch{background:#fff;border:1px solid #ccc;box-sizing:border-box}.tabulator-popup-container{-webkit-overflow-scrolling:touch;background:transparent;border:1px solid #aaa;box-shadow:0 0 5px 0 rgba(0,0,0,.2);box-sizing:border-box;display:inline-block;font-size:16px;overflow-y:auto;position:absolute;z-index:10000}.tabulator-popup{border-radius:3px;padding:5px}.tabulator-tooltip{border-radius:2px;box-shadow:none;font-size:12px;max-width:Min(500px,100%);padding:3px 5px;pointer-events:none}.tabulator-menu .tabulator-menu-item{box-sizing:border-box;padding:5px 10px;position:relative;user-select:none}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator-menu .tabulator-menu-item:not(.tabulator-menu-item-disabled):hover{background:#fafafa;cursor:pointer}}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu{padding-right:25px}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu:after{border-color:#aaa;border-style:solid;border-width:1px 1px 0 0;content:"";display:inline-block;height:7px;position:absolute;right:10px;top:calc(5px + .4em);transform:rotate(45deg);vertical-align:top;width:7px}.tabulator-menu .tabulator-menu-separator{border-top:1px solid #aaa}.tabulator-edit-list{-webkit-overflow-scrolling:touch;font-size:16px;max-height:200px;overflow-y:auto}.tabulator-edit-list .tabulator-edit-list-item{color:#363636;outline:none;padding:4px}.tabulator-edit-list .tabulator-edit-list-item.active{background:#1d68cd;color:transparent}.tabulator-edit-list .tabulator-edit-list-item.active.focused{outline:1px solid rgba(0,0,0,.5)}.tabulator-edit-list .tabulator-edit-list-item.focused{outline:1px solid #1d68cd}@media (hover:hover) and (pointer:fine){.tabulator-edit-list .tabulator-edit-list-item:hover{background:#1d68cd;color:transparent;cursor:pointer}}.tabulator-edit-list .tabulator-edit-list-placeholder{color:#363636;padding:4px;text-align:center}.tabulator-edit-list .tabulator-edit-list-group{border-bottom:1px solid #aaa;color:#363636;font-weight:700;padding:6px 4px 4px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-2,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-2{padding-left:12px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-3,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-3{padding-left:20px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-4,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-4{padding-left:28px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-5,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-5{padding-left:36px}.tabulator.tabulator-ltr{direction:ltr}.tabulator.tabulator-rtl{direction:rtl;text-align:initial}.tabulator.tabulator-rtl .tabulator-header .tabulator-col{border-left:1px solid #aaa;border-right:initial;text-align:initial}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{margin-left:-1px;margin-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-left:25px;padding-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{left:8px;right:auto}.tabulator.tabulator-rtl .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{background-color:#009e86;border-radius:999px;bottom:-3px;content:"";height:6px;left:-3px;position:absolute;right:auto;width:6px}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell{border-left:1px solid #aaa;border-right:initial}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-branch{border-bottom-left-radius:0;border-bottom-right-radius:1px;border-left:initial;border-right:2px solid #aaa;margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-control{margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-left:2px solid #aaa}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-right:2px solid #aaa}.tabulator.tabulator-rtl .tabulator-row .tabulator-col-resize-handle:last-of-type{margin-left:0;margin-right:-3px;width:3px}.tabulator.tabulator-rtl .tabulator-footer .tabulator-calcs-holder{text-align:initial}.tabulator-print-fullscreen{bottom:0;left:0;position:absolute;right:0;top:0;z-index:10000}body.tabulator-print-fullscreen-hide>:not(.tabulator-print-fullscreen){display:none!important}.tabulator-print-table{border-collapse:collapse}.tabulator-print-table .tabulator-data-tree-branch{border-bottom:2px solid #aaa;border-bottom-left-radius:1px;border-left:2px solid #aaa;display:inline-block;height:9px;margin-right:5px;margin-top:-9px;vertical-align:middle;width:7px}.tabulator-print-table .tabulator-print-table-group{background:#ccc;border-right:1px solid #aaa;font-weight:700;min-width:100%;padding:5px 5px 5px 10px}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-print-table-group:hover{background-color:rgba(0,0,0,.1);cursor:pointer}}.tabulator-print-table .tabulator-print-table-group.tabulator-group-visible .tabulator-arrow{border-bottom:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #363636;margin-right:10px}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-1 td{padding-left:30px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-2 td{padding-left:50px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-3 td{padding-left:70px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-4 td{padding-left:90px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-5 td{padding-left:110px!important}.tabulator-print-table .tabulator-print-table-group .tabulator-group-toggle{display:inline-block}.tabulator-print-table .tabulator-print-table-group .tabulator-arrow{border-bottom:6px solid transparent;border-left:6px solid #363636;border-right:0;border-top:6px solid transparent;display:inline-block;height:0;margin-right:16px;vertical-align:middle;width:0}.tabulator-print-table .tabulator-print-table-group span{color:#d00;margin-left:10px}.tabulator-print-table .tabulator-data-tree-control{align-items:center;background:rgba(0,0,0,.1);border:1px solid #363636;border-radius:2px;display:inline-flex;height:11px;justify-content:center;margin-right:5px;overflow:hidden;vertical-align:middle;width:11px}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-data-tree-control:hover{background:rgba(0,0,0,.2);cursor:pointer}}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:transparent;display:inline-block;height:7px;position:relative;width:1px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{background:#363636;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:#363636;display:inline-block;height:7px;position:relative;width:1px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:#363636;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator{border:none}.tabulator .tabulator-header{border:solid #dbdbdb;border-width:0 0 2px}.tabulator .tabulator-header .tabulator-col{border-right:none}.tabulator .tabulator-header .tabulator-col.tabulator-moving{border:none}.tabulator .tabulator-header .tabulator-col .tabulator-col-content{padding:.5em .75em}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{right:0}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input{border:1px solid #dbdbdb}.tabulator .tabulator-header .tabulator-calcs-holder{border:solid #dbdbdb;border-width:2px 0 0}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-cell{border-bottom-width:0}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top{border:solid #dbdbdb;border-width:0 0 2px}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom{border:solid #dbdbdb;border-width:2px 0 0}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs .tabulator-cell{border-bottom-width:0}.tabulator .tabulator-footer{border:solid #dbdbdb;border-width:2px 0 0;padding:.5em .75em}.tabulator .tabulator-footer .tabulator-calcs-holder{border:solid #dbdbdb;border-width:0 0 2px;margin:-5px -10px 10px}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-cell{border-bottom-width:0}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs{margin-top:calc(-.5em - 5px)}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab{border-color:#dbdbdb;font-weight:400}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active{border-color:#4a4a4a;color:#363636;font-weight:700}.tabulator .tabulator-footer .tabulator-page{border:1px solid #dbdbdb;font-size:16px;margin:0 .1875em;padding:calc(.375em - 1px) .75em}.tabulator .tabulator-footer .tabulator-page.active{border-color:#4a4a4a;color:#363636;font-weight:700}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-footer .tabulator-page:not(.disabled):hover{background:inherit;border-color:#b5b5b5;color:inherit;cursor:pointer}}.tabulator.is-striped .tabulator-row:nth-child(2n){background-color:#fafafa}.tabulator.is-bordered{border:1px solid #dbdbdb}.tabulator.is-bordered .tabulator-header .tabulator-col,.tabulator.is-bordered .tabulator-tableholder .tabulator-table .tabulator-row .tabulator-cell{border-right:1px solid #dbdbdb}.tabulator.is-narrow .tabulator-header .tabulator-col .tabulator-col-content,.tabulator.is-narrow .tabulator-tableholder .tabulator-table .tabulator-row .tabulator-cell{padding:.25em .5em}.tabulator-row{min-height:22px}.tabulator-row.tabulator-row-even{background-color:inherit}.tabulator-row.tabulator-selected{background-color:#00d1b2!important}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selected:hover{background-color:#009e86!important}}.tabulator-row .tabulator-cell{border:solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em}.tabulator-row .tabulator-cell.tabulator-row-header{background:transparent;border:1px solid #dbdbdb;border-width:0 1px 1px 0}.tabulator-print-table .tabulator-print-table-group,.tabulator-row.tabulator-group{border-bottom:1px solid #999;border-right:none;border-top:1px solid #999;color:#363636}.tabulator-print-table .tabulator-print-table-group{box-sizing:border-box}.tabulator-popup-container{background:#fff}.tabulator-edit-list .tabulator-edit-list-item.active{color:#fff}@media (hover:hover) and (pointer:fine){.tabulator-edit-list .tabulator-edit-list-item:hover{color:#fff}}
2 |
--------------------------------------------------------------------------------
/nicegui_tabulator/core/libs/tabulator_midnight.min.css:
--------------------------------------------------------------------------------
1 | .tabulator{border:1px solid #333;font-size:14px;overflow:hidden;position:relative;text-align:left;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}.tabulator[tabulator-layout=fitDataFill] .tabulator-tableholder .tabulator-table{min-width:100%}.tabulator[tabulator-layout=fitDataTable]{display:inline-block}.tabulator.tabulator-block-select,.tabulator.tabulator-ranges .tabulator-cell:not(.tabulator-editing){user-select:none}.tabulator .tabulator-header{background-color:#333;border-bottom:1px solid #999;box-sizing:border-box;color:#fff;font-weight:700;outline:none;overflow:hidden;position:relative;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;white-space:nowrap;width:100%}.tabulator .tabulator-header.tabulator-header-hidden{display:none}.tabulator .tabulator-header .tabulator-header-contents{overflow:hidden;position:relative}.tabulator .tabulator-header .tabulator-header-contents .tabulator-headers{display:inline-block}.tabulator .tabulator-header .tabulator-col{background:#333;border-right:1px solid #aaa;box-sizing:border-box;display:inline-flex;flex-direction:column;justify-content:flex-start;overflow:hidden;position:relative;text-align:left;vertical-align:bottom}.tabulator .tabulator-header .tabulator-col.tabulator-moving{background:#1a1a1a;border:1px solid #999;pointer-events:none;position:absolute}.tabulator .tabulator-header .tabulator-col.tabulator-range-highlight{background-color:#999;color:#000}.tabulator .tabulator-header .tabulator-col.tabulator-range-selected{background-color:#ccc;color:#333}.tabulator .tabulator-header .tabulator-col .tabulator-col-content{box-sizing:border-box;padding:4px;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button{padding:0 8px}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button:hover{cursor:pointer;opacity:.6}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title-holder{position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title{box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title.tabulator-col-title-wrap{text-overflow:clip;white-space:normal}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor{background:#fff;border:1px solid #999;box-sizing:border-box;padding:1px;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-header-popup-button+.tabulator-title-editor{width:calc(100% - 22px)}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{align-items:center;bottom:0;display:flex;position:absolute;right:4px;top:0}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #bbb;border-left:6px solid transparent;border-right:6px solid transparent;height:0;width:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{border-top:1px solid #aaa;display:flex;margin-right:-1px;overflow:hidden;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter{box-sizing:border-box;margin-top:2px;position:relative;text-align:center;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea{height:auto!important}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg{margin-top:3px}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear{height:0;width:0}.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-right:25px}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable.tabulator-col-sorter-element:hover{background-color:#1a1a1a;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter{color:#bbb}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-bottom:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #bbb;border-top:none}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter{color:#666}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-bottom:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #666;border-top:none}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter{color:#666}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-top:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:none;border-top:6px solid #666;color:#666}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title{align-items:center;display:flex;justify-content:center;text-orientation:mixed;writing-mode:vertical-rl}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title{transform:rotate(180deg)}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title{padding-right:0;padding-top:20px}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title{padding-bottom:20px;padding-right:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-sorter{bottom:auto;justify-content:center;left:0;right:0;top:4px}.tabulator .tabulator-header .tabulator-frozen{left:0;position:sticky;z-index:11}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left{border-right:2px solid #888}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right{border-left:2px solid #888}.tabulator .tabulator-header .tabulator-calcs-holder{background:#404040!important;border-bottom:1px solid #aaa;border-top:1px solid #888;box-sizing:border-box;display:inline-block}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row{background:#404040!important}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-header .tabulator-frozen-rows-holder{display:inline-block}.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty{display:none}.tabulator .tabulator-tableholder{-webkit-overflow-scrolling:touch;overflow:auto;position:relative;white-space:nowrap;width:100%}.tabulator .tabulator-tableholder:focus{outline:none}.tabulator .tabulator-tableholder .tabulator-placeholder{align-items:center;box-sizing:border-box;display:flex;justify-content:center;min-width:100%;width:100%}.tabulator .tabulator-tableholder .tabulator-placeholder[tabulator-render-mode=virtual]{min-height:100%}.tabulator .tabulator-tableholder .tabulator-placeholder .tabulator-placeholder-contents{color:#ccc;display:inline-block;font-size:20px;font-weight:700;padding:10px;text-align:center;white-space:normal}.tabulator .tabulator-tableholder .tabulator-table{background-color:#666;color:#fff;display:inline-block;overflow:visible;position:relative;white-space:nowrap}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs{background:#373737!important;font-weight:700}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top{border-bottom:2px solid #888}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom{border-top:2px solid #888}.tabulator .tabulator-tableholder .tabulator-range-overlay{inset:0;pointer-events:none;position:absolute;z-index:10}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range{border:1px solid #ccc;box-sizing:border-box;position:absolute}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{background-color:#ccc;border-radius:999px;bottom:-3px;content:"";height:6px;position:absolute;right:-3px;width:6px}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range-cell-active{border:2px solid #ccc;box-sizing:border-box;position:absolute}.tabulator .tabulator-footer{background-color:#333;border-top:1px solid #999;color:#333;font-weight:700;user-select:none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;white-space:nowrap}.tabulator .tabulator-footer .tabulator-footer-contents{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:5px 10px}.tabulator .tabulator-footer .tabulator-footer-contents:empty{display:none}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs{margin-top:-5px;overflow-x:auto}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab{border:1px solid #333;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top:none;display:inline-block;font-size:.9em;padding:5px}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab:hover{cursor:pointer;opacity:.7}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active{background:#fff}.tabulator .tabulator-footer .tabulator-calcs-holder{background:#404040!important;border-bottom:1px solid #888;border-top:1px solid #888;box-sizing:border-box;overflow:hidden;text-align:left;width:100%}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row{background:#404040!important;display:inline-block}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-footer .tabulator-calcs-holder:only-child{border-bottom:none;margin-bottom:-5px}.tabulator .tabulator-footer>*+.tabulator-page-counter{margin-left:10px}.tabulator .tabulator-footer .tabulator-page-counter{font-weight:400}.tabulator .tabulator-footer .tabulator-paginator{color:#333;flex:1;font-family:inherit;font-size:inherit;font-weight:inherit;text-align:right}.tabulator .tabulator-footer .tabulator-page-size{border:1px solid #aaa;border-radius:3px;display:inline-block;margin:0 5px;padding:2px 5px}.tabulator .tabulator-footer .tabulator-pages{margin:0 7px}.tabulator .tabulator-footer .tabulator-page{background:hsla(0,0%,100%,.2);border:1px solid #aaa;border-radius:3px;display:inline-block;margin:0 2px;padding:2px 5px}.tabulator .tabulator-footer .tabulator-page.active{color:#fff}.tabulator .tabulator-footer .tabulator-page:disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-footer .tabulator-page:not(disabled):hover{background:rgba(0,0,0,.2);color:#fff;cursor:pointer}}.tabulator .tabulator-col-resize-handle{display:inline-block;margin-left:-3px;margin-right:-3px;position:relative;vertical-align:middle;width:6px;z-index:11}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-col-resize-handle:hover{cursor:ew-resize}}.tabulator .tabulator-col-resize-handle:last-of-type{margin-right:0;width:3px}.tabulator .tabulator-col-resize-guide{background-color:#999;height:100%;margin-left:-.5px;opacity:.5;position:absolute;top:0;width:4px}.tabulator .tabulator-row-resize-guide{background-color:#999;height:4px;left:0;margin-top:-.5px;opacity:.5;position:absolute;width:100%}.tabulator .tabulator-alert{align-items:center;background:rgba(0,0,0,.4);display:flex;height:100%;left:0;position:absolute;text-align:center;top:0;width:100%;z-index:100}.tabulator .tabulator-alert .tabulator-alert-msg{background:#fff;border-radius:10px;display:inline-block;font-size:16px;font-weight:700;margin:0 auto;padding:10px 20px}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-msg{border:4px solid #333;color:#000}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-error{border:4px solid #d00;color:#590000}.tabulator-row{background-color:#666;box-sizing:border-box;min-height:22px;position:relative}.tabulator-row.tabulator-row-even{background-color:#444}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selectable:hover{background-color:#999;cursor:pointer}}.tabulator-row.tabulator-selected{background-color:#000}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selected:hover{background-color:#888;cursor:pointer}}.tabulator-row.tabulator-row-moving{background:#fff;border:1px solid #000}.tabulator-row.tabulator-moving{border-bottom:1px solid #888;border-top:1px solid #888;pointer-events:none;position:absolute;z-index:15}.tabulator-row.tabulator-range-highlight .tabulator-cell.tabulator-range-row-header{background-color:#999;color:#000}.tabulator-row.tabulator-range-highlight.tabulator-range-selected .tabulator-cell.tabulator-range-row-header,.tabulator-row.tabulator-range-selected .tabulator-cell.tabulator-range-row-header{background-color:#ccc;color:#333}.tabulator-row .tabulator-row-resize-handle{bottom:0;height:5px;left:0;position:absolute;right:0}.tabulator-row .tabulator-row-resize-handle.prev{bottom:auto;top:0}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-row-resize-handle:hover{cursor:ns-resize}}.tabulator-row .tabulator-responsive-collapse{border-bottom:1px solid #888;border-top:1px solid #888;box-sizing:border-box;padding:5px}.tabulator-row .tabulator-responsive-collapse:empty{display:none}.tabulator-row .tabulator-responsive-collapse table{font-size:14px}.tabulator-row .tabulator-responsive-collapse table tr td{position:relative}.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type{padding-right:10px}.tabulator-row .tabulator-cell{border-right:1px solid #888;box-sizing:border-box;display:inline-block;outline:none;overflow:hidden;padding:4px;position:relative;text-overflow:ellipsis;vertical-align:middle;white-space:nowrap}.tabulator-row .tabulator-cell.tabulator-row-header{background:#333;border-bottom:1px solid #888;border-right:1px solid #333}.tabulator-row .tabulator-cell.tabulator-frozen{background-color:inherit;display:inline-block;left:0;position:sticky;z-index:11}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-right:2px solid #888}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-left:2px solid #888}.tabulator-row .tabulator-cell.tabulator-editing{border:1px solid #999;outline:none;padding:0}.tabulator-row .tabulator-cell.tabulator-editing input,.tabulator-row .tabulator-cell.tabulator-editing select{background:transparent;border:1px;outline:none}.tabulator-row .tabulator-cell.tabulator-validation-fail{border:1px solid #d00}.tabulator-row .tabulator-cell.tabulator-validation-fail input,.tabulator-row .tabulator-cell.tabulator-validation-fail select{background:transparent;border:1px;color:#d00}.tabulator-row .tabulator-cell.tabulator-row-handle{align-items:center;display:inline-flex;justify-content:center;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box{width:80%}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar{background:#666;height:3px;margin-top:2px;width:100%}.tabulator-row .tabulator-cell.tabulator-range-selected:not(.tabulator-range-only-cell-selected):not(.tabulator-range-row-header){background-color:#000}.tabulator-row .tabulator-cell .tabulator-data-tree-branch-empty{display:inline-block;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-branch{border-bottom:2px solid #888;border-bottom-left-radius:1px;border-left:2px solid #888;display:inline-block;height:9px;margin-right:5px;margin-top:-9px;vertical-align:middle;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-control{align-items:center;background:rgba(0,0,0,.1);border:1px solid #fff;border-radius:2px;display:inline-flex;height:11px;justify-content:center;margin-right:5px;overflow:hidden;vertical-align:middle;width:11px}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover{background:rgba(0,0,0,.2);cursor:pointer}}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:transparent;display:inline-block;height:7px;position:relative;width:1px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{background:#fff;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:#fff;display:inline-block;height:7px;position:relative;width:1px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:#fff;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle{align-items:center;background:#666;border-radius:20px;color:#666;display:inline-flex;font-size:1.1em;font-weight:700;height:15px;justify-content:center;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;width:15px}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover{cursor:pointer;opacity:.7}}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close{display:initial}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open{display:none}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle svg{stroke:#666}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close{display:none}.tabulator-row .tabulator-cell .tabulator-traffic-light{border-radius:14px;display:inline-block;height:14px;width:14px}.tabulator-row.tabulator-group{background:#ccc;border-bottom:1px solid #999;border-right:1px solid #888;border-top:1px solid #999;box-sizing:border-box;font-weight:700;padding:5px 5px 5px 10px}.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow{border-bottom:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #666;margin-right:10px}.tabulator-row.tabulator-group.tabulator-group-level-1{padding-left:30px}.tabulator-row.tabulator-group.tabulator-group-level-2{padding-left:50px}.tabulator-row.tabulator-group.tabulator-group-level-3{padding-left:70px}.tabulator-row.tabulator-group.tabulator-group-level-4{padding-left:90px}.tabulator-row.tabulator-group.tabulator-group-level-5{padding-left:110px}.tabulator-row.tabulator-group .tabulator-group-toggle{display:inline-block}.tabulator-row.tabulator-group .tabulator-arrow{border-bottom:6px solid transparent;border-left:6px solid #666;border-right:0;border-top:6px solid transparent;display:inline-block;height:0;margin-right:16px;vertical-align:middle;width:0}.tabulator-row.tabulator-group span{color:#d00;margin-left:10px}.tabulator-toggle{background:#dcdcdc;border:1px solid #ccc;box-sizing:border-box;display:flex;flex-direction:row}.tabulator-toggle.tabulator-toggle-on{background:#1c6cc2}.tabulator-toggle .tabulator-toggle-switch{background:#fff;border:1px solid #ccc;box-sizing:border-box}.tabulator-popup-container{-webkit-overflow-scrolling:touch;background:#666;border:1px solid #888;box-shadow:0 0 5px 0 rgba(0,0,0,.2);box-sizing:border-box;display:inline-block;font-size:14px;overflow-y:auto;position:absolute;z-index:10000}.tabulator-popup{border-radius:3px;padding:5px}.tabulator-tooltip{border-radius:2px;box-shadow:none;font-size:12px;max-width:Min(500px,100%);padding:3px 5px;pointer-events:none}.tabulator-menu .tabulator-menu-item{box-sizing:border-box;padding:5px 10px;position:relative;user-select:none}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator-menu .tabulator-menu-item:not(.tabulator-menu-item-disabled):hover{background:#444;cursor:pointer}}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu{padding-right:25px}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu:after{border-color:#888;border-style:solid;border-width:1px 1px 0 0;content:"";display:inline-block;height:7px;position:absolute;right:10px;top:calc(5px + .4em);transform:rotate(45deg);vertical-align:top;width:7px}.tabulator-menu .tabulator-menu-separator{border-top:1px solid #888}.tabulator-edit-list{-webkit-overflow-scrolling:touch;font-size:14px;max-height:200px;overflow-y:auto}.tabulator-edit-list .tabulator-edit-list-item{color:#fff;outline:none;padding:4px}.tabulator-edit-list .tabulator-edit-list-item.active{background:#999;color:#666}.tabulator-edit-list .tabulator-edit-list-item.active.focused{outline:1px solid hsla(0,0%,40%,.5)}.tabulator-edit-list .tabulator-edit-list-item.focused{outline:1px solid #999}@media (hover:hover) and (pointer:fine){.tabulator-edit-list .tabulator-edit-list-item:hover{background:#999;color:#666;cursor:pointer}}.tabulator-edit-list .tabulator-edit-list-placeholder{color:#fff;padding:4px;text-align:center}.tabulator-edit-list .tabulator-edit-list-group{border-bottom:1px solid #888;color:#fff;font-weight:700;padding:6px 4px 4px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-2,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-2{padding-left:12px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-3,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-3{padding-left:20px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-4,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-4{padding-left:28px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-5,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-5{padding-left:36px}.tabulator.tabulator-ltr{direction:ltr}.tabulator.tabulator-rtl{direction:rtl;text-align:initial}.tabulator.tabulator-rtl .tabulator-header .tabulator-col{border-left:1px solid #aaa;border-right:initial;text-align:initial}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{margin-left:-1px;margin-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-left:25px;padding-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{left:8px;right:auto}.tabulator.tabulator-rtl .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{background-color:#ccc;border-radius:999px;bottom:-3px;content:"";height:6px;left:-3px;position:absolute;right:auto;width:6px}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell{border-left:1px solid #888;border-right:initial}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-branch{border-bottom-left-radius:0;border-bottom-right-radius:1px;border-left:initial;border-right:2px solid #888;margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-control{margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-left:2px solid #888}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-right:2px solid #888}.tabulator.tabulator-rtl .tabulator-row .tabulator-col-resize-handle:last-of-type{margin-left:0;margin-right:-3px;width:3px}.tabulator.tabulator-rtl .tabulator-footer .tabulator-calcs-holder{text-align:initial}.tabulator-print-fullscreen{bottom:0;left:0;position:absolute;right:0;top:0;z-index:10000}body.tabulator-print-fullscreen-hide>:not(.tabulator-print-fullscreen){display:none!important}.tabulator-print-table{border-collapse:collapse}.tabulator-print-table .tabulator-data-tree-branch{border-bottom:2px solid #888;border-bottom-left-radius:1px;border-left:2px solid #888;display:inline-block;height:9px;margin-right:5px;margin-top:-9px;vertical-align:middle;width:7px}.tabulator-print-table .tabulator-print-table-group{background:#ccc;border-bottom:1px solid #999;border-right:1px solid #888;border-top:1px solid #999;box-sizing:border-box;font-weight:700;min-width:100%;padding:5px 5px 5px 10px}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-print-table-group:hover{background-color:rgba(0,0,0,.1);cursor:pointer}}.tabulator-print-table .tabulator-print-table-group.tabulator-group-visible .tabulator-arrow{border-bottom:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #666;margin-right:10px}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-1 td{padding-left:30px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-2 td{padding-left:50px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-3 td{padding-left:70px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-4 td{padding-left:90px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-5 td{padding-left:110px!important}.tabulator-print-table .tabulator-print-table-group .tabulator-group-toggle{display:inline-block}.tabulator-print-table .tabulator-print-table-group .tabulator-arrow{border-bottom:6px solid transparent;border-left:6px solid #666;border-right:0;border-top:6px solid transparent;display:inline-block;height:0;margin-right:16px;vertical-align:middle;width:0}.tabulator-print-table .tabulator-print-table-group span{color:#d00;margin-left:10px}.tabulator-print-table .tabulator-data-tree-control{align-items:center;background:rgba(0,0,0,.1);border:1px solid #fff;border-radius:2px;display:inline-flex;height:11px;justify-content:center;margin-right:5px;overflow:hidden;vertical-align:middle;width:11px}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-data-tree-control:hover{background:rgba(0,0,0,.2);cursor:pointer}}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:transparent;display:inline-block;height:7px;position:relative;width:1px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{background:#fff;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:#fff;display:inline-block;height:7px;position:relative;width:1px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:#fff;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator{background-color:#222}.tabulator .tabulator-header .tabulator-col{background-color:#333}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor{color:#fff}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input,.tabulator .tabulator-header .tabulator-col .tabulator-header-filter select{background:#444;border:1px solid #999;color:#fff}.tabulator .tabulator-header .tabulator-calcs-holder,.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row{background:#1a1a1a!important}.tabulator .tabulator-footer .tabulator-calcs-holder,.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row{background:#262626!important}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab{background:hsla(0,0%,100%,.2);border-color:#aaa}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active{background:rgba(0,0,0,.2);color:#fff}.tabulator .tabulator-footer .tabulator-page-counter,.tabulator .tabulator-footer .tabulator-paginator label{color:#fff}.tabulator .tabulator-footer .tabulator-page{color:#333;font-family:inherit;font-size:inherit;font-weight:inherit}.tabulator-row.tabulator-group{color:#333;min-width:100%}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-group:hover{background-color:rgba(0,0,0,.1);cursor:pointer}}.tabulator-row.tabulator-group span{color:#666}.tabulator-toggle{background:#333;border-color:#000}.tabulator-toggle .tabulator-toggle-switch{background:#232323;border-color:#000}.tabulator-edit-select-list{background:#fff}.tabulator-edit-select-list .tabulator-edit-select-list-item{color:#666}.tabulator-edit-select-list .tabulator-edit-select-list-item.active{background:#444;color:#999}.tabulator-edit-select-list .tabulator-edit-select-list-item.active.focused{outline:1px solid hsla(0,0%,60%,.5)}.tabulator-edit-select-list .tabulator-edit-select-list-item.focused{outline:1px solid #444}@media (hover:hover) and (pointer:fine){.tabulator-edit-select-list .tabulator-edit-select-list-item:hover{background:#666;color:#999}}.tabulator-print-table .tabulator-print-table-group{color:#333}
2 |
--------------------------------------------------------------------------------
/nicegui_tabulator/core/libs/tabulator_modern.min.css:
--------------------------------------------------------------------------------
1 | .tabulator{background-color:#fff;border:1px solid #fff;font-size:16px;overflow:hidden;position:relative;text-align:left;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}.tabulator[tabulator-layout=fitDataFill] .tabulator-tableholder .tabulator-table{min-width:100%}.tabulator[tabulator-layout=fitDataTable]{display:inline-block}.tabulator.tabulator-block-select,.tabulator.tabulator-ranges .tabulator-cell:not(.tabulator-editing){user-select:none}.tabulator .tabulator-header{background-color:#fff;border-bottom:1px solid #3759d7;box-sizing:border-box;color:#3759d7;font-weight:700;outline:none;overflow:hidden;position:relative;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;white-space:nowrap;width:100%}.tabulator .tabulator-header.tabulator-header-hidden{display:none}.tabulator .tabulator-header .tabulator-header-contents{overflow:hidden;position:relative}.tabulator .tabulator-header .tabulator-header-contents .tabulator-headers{display:inline-block}.tabulator .tabulator-header .tabulator-col{background:#fff;border-right:1px solid #fff;box-sizing:border-box;display:inline-flex;flex-direction:column;justify-content:flex-start;overflow:hidden;position:relative;text-align:left;vertical-align:bottom}.tabulator .tabulator-header .tabulator-col.tabulator-moving{background:#e6e6e6;border:1px solid #3759d7;pointer-events:none;position:absolute}.tabulator .tabulator-header .tabulator-col.tabulator-range-highlight{background-color:#3759d7;color:#fff}.tabulator .tabulator-header .tabulator-col.tabulator-range-selected{background-color:#2544b7;color:#fff}.tabulator .tabulator-header .tabulator-col .tabulator-col-content{box-sizing:border-box;padding:4px;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button{padding:0 8px}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button:hover{cursor:pointer;opacity:.6}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title-holder{position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title{box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title.tabulator-col-title-wrap{text-overflow:clip;white-space:normal}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor{background:#fff;border:1px solid #999;box-sizing:border-box;padding:1px;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-header-popup-button+.tabulator-title-editor{width:calc(100% - 22px)}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{align-items:center;bottom:0;display:flex;position:absolute;right:4px;top:0}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #b7c3f1;border-left:6px solid transparent;border-right:6px solid transparent;height:0;width:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{border-top:1px solid #fff;display:flex;margin-right:-1px;overflow:hidden;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter{box-sizing:border-box;margin-top:2px;position:relative;text-align:center;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea{height:auto!important}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg{margin-top:3px}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear{height:0;width:0}.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-right:25px}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable.tabulator-col-sorter-element:hover{background-color:#e6e6e6;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter{color:#b7c3f1}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-bottom:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #b7c3f1;border-top:none}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter{color:#3759d7}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-bottom:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #3759d7;border-top:none}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter{color:#3759d7}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-top:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:none;border-top:6px solid #3759d7;color:#3759d7}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title{align-items:center;display:flex;justify-content:center;text-orientation:mixed;writing-mode:vertical-rl}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title{transform:rotate(180deg)}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title{padding-right:0;padding-top:20px}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title{padding-bottom:20px;padding-right:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-sorter{bottom:auto;justify-content:center;left:0;right:0;top:4px}.tabulator .tabulator-header .tabulator-frozen{left:0;position:sticky;z-index:11}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left{border-right:2px solid #fff}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right{border-left:2px solid #fff}.tabulator .tabulator-header .tabulator-calcs-holder{background:#fff!important;border-bottom:1px solid #fff;border-top:1px solid #fff;box-sizing:border-box;display:inline-block}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row{background:#fff!important}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-header .tabulator-frozen-rows-holder{display:inline-block}.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty{display:none}.tabulator .tabulator-tableholder{-webkit-overflow-scrolling:touch;overflow:auto;position:relative;white-space:nowrap;width:100%}.tabulator .tabulator-tableholder:focus{outline:none}.tabulator .tabulator-tableholder .tabulator-placeholder{align-items:center;box-sizing:border-box;display:flex;justify-content:center;min-width:100%;width:100%}.tabulator .tabulator-tableholder .tabulator-placeholder[tabulator-render-mode=virtual]{min-height:100%}.tabulator .tabulator-tableholder .tabulator-placeholder .tabulator-placeholder-contents{color:#ccc;display:inline-block;font-size:20px;font-weight:700;padding:10px;text-align:center;white-space:normal}.tabulator .tabulator-tableholder .tabulator-table{background-color:#f3f3f3;color:#333;display:inline-block;overflow:visible;position:relative;white-space:nowrap}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs{background:#f2f2f2!important;font-weight:700}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top{border-bottom:2px solid #fff}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom{border-top:2px solid #fff}.tabulator .tabulator-tableholder .tabulator-range-overlay{inset:0;pointer-events:none;position:absolute;z-index:10}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range{border:1px solid #2544b7;box-sizing:border-box;position:absolute}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{background-color:#2544b7;border-radius:999px;bottom:-3px;content:"";height:6px;position:absolute;right:-3px;width:6px}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range-cell-active{border:2px solid #2544b7;box-sizing:border-box;position:absolute}.tabulator .tabulator-footer{background-color:#fff;border-top:1px solid #999;color:#3759d7;font-weight:700;user-select:none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;white-space:nowrap}.tabulator .tabulator-footer .tabulator-footer-contents{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:5px 10px}.tabulator .tabulator-footer .tabulator-footer-contents:empty{display:none}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs{margin-top:-5px;overflow-x:auto}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab{border:1px solid #fff;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top:none;display:inline-block;font-size:.9em;padding:5px}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab:hover{cursor:pointer;opacity:.7}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active{background:#fff}.tabulator .tabulator-footer .tabulator-calcs-holder{background:#fff!important;border-bottom:1px solid #fff;border-top:1px solid #fff;box-sizing:border-box;overflow:hidden;text-align:left;width:100%}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row{display:inline-block}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-footer .tabulator-calcs-holder:only-child{border-bottom:none;margin-bottom:-5px}.tabulator .tabulator-footer>*+.tabulator-page-counter{margin-left:10px}.tabulator .tabulator-footer .tabulator-page-counter{font-weight:400}.tabulator .tabulator-footer .tabulator-paginator{color:#3759d7;flex:1;font-family:inherit;font-size:inherit;font-weight:inherit;text-align:right}.tabulator .tabulator-footer .tabulator-page-size{border:1px solid #aaa;border-radius:3px;display:inline-block;margin:0 5px;padding:2px 5px}.tabulator .tabulator-footer .tabulator-pages{margin:0 7px}.tabulator .tabulator-footer .tabulator-page{background:hsla(0,0%,100%,.2);border:1px solid #aaa;border-radius:3px;display:inline-block;margin:0 2px;padding:2px 5px}.tabulator .tabulator-footer .tabulator-page.active{color:#3759d7}.tabulator .tabulator-footer .tabulator-page:disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-footer .tabulator-page:not(disabled):hover{background:rgba(0,0,0,.2);color:#fff;cursor:pointer}}.tabulator .tabulator-col-resize-handle{display:inline-block;margin-left:-3px;margin-right:-3px;position:relative;vertical-align:middle;width:6px;z-index:11}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-col-resize-handle:hover{cursor:ew-resize}}.tabulator .tabulator-col-resize-handle:last-of-type{margin-right:0;width:3px}.tabulator .tabulator-col-resize-guide{background-color:#999;height:100%;margin-left:-.5px;opacity:.5;position:absolute;top:0;width:4px}.tabulator .tabulator-row-resize-guide{background-color:#999;height:4px;left:0;margin-top:-.5px;opacity:.5;position:absolute;width:100%}.tabulator .tabulator-alert{align-items:center;background:rgba(0,0,0,.4);display:flex;height:100%;left:0;position:absolute;text-align:center;top:0;width:100%;z-index:100}.tabulator .tabulator-alert .tabulator-alert-msg{background:#fff;border-radius:10px;display:inline-block;font-size:16px;font-weight:700;margin:0 auto;padding:10px 20px}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-msg{border:4px solid #333;color:#000}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-error{border:4px solid #d00;color:#590000}.tabulator-row{background-color:#f3f3f3;box-sizing:border-box;min-height:24px;position:relative}.tabulator-row.tabulator-row-even{background-color:#fff}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selectable:hover{background-color:#bbb;cursor:pointer}}.tabulator-row.tabulator-selected{background-color:#9abcea}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selected:hover{background-color:#769bcc;cursor:pointer}}.tabulator-row.tabulator-row-moving{background:#fff;border:1px solid #000}.tabulator-row.tabulator-moving{border-bottom:1px solid #fff;border-top:1px solid #fff;pointer-events:none;position:absolute;z-index:15}.tabulator-row.tabulator-range-highlight .tabulator-cell.tabulator-range-row-header{background-color:#3759d7;color:#fff}.tabulator-row.tabulator-range-highlight.tabulator-range-selected .tabulator-cell.tabulator-range-row-header,.tabulator-row.tabulator-range-selected .tabulator-cell.tabulator-range-row-header{background-color:#2544b7;color:#fff}.tabulator-row .tabulator-row-resize-handle{bottom:0;height:5px;left:0;position:absolute;right:0}.tabulator-row .tabulator-row-resize-handle.prev{bottom:auto;top:0}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-row-resize-handle:hover{cursor:ns-resize}}.tabulator-row .tabulator-responsive-collapse{border-bottom:1px solid #fff;border-top:1px solid #fff;box-sizing:border-box;padding:5px}.tabulator-row .tabulator-responsive-collapse:empty{display:none}.tabulator-row .tabulator-responsive-collapse table{font-size:16px}.tabulator-row .tabulator-responsive-collapse table tr td{position:relative}.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type{padding-right:10px}.tabulator-row .tabulator-cell{border-right:1px solid #fff;box-sizing:border-box;display:inline-block;outline:none;overflow:hidden;padding:4px;position:relative;text-overflow:ellipsis;vertical-align:middle;white-space:nowrap}.tabulator-row .tabulator-cell.tabulator-row-header{background:#fff;border-bottom:1px solid #fff;border-right:1px solid #fff}.tabulator-row .tabulator-cell.tabulator-frozen{background-color:inherit;display:inline-block;left:0;position:sticky;z-index:11}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-right:2px solid #fff}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-left:2px solid #fff}.tabulator-row .tabulator-cell.tabulator-editing{border:1px solid #1d68cd;outline:none;padding:0}.tabulator-row .tabulator-cell.tabulator-editing input,.tabulator-row .tabulator-cell.tabulator-editing select{background:transparent;border:1px;outline:none}.tabulator-row .tabulator-cell.tabulator-validation-fail{border:1px solid #d00}.tabulator-row .tabulator-cell.tabulator-validation-fail input,.tabulator-row .tabulator-cell.tabulator-validation-fail select{background:transparent;border:1px;color:#d00}.tabulator-row .tabulator-cell.tabulator-row-handle{align-items:center;display:inline-flex;justify-content:center;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box{width:80%}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar{background:#666;height:3px;margin-top:2px;width:100%}.tabulator-row .tabulator-cell.tabulator-range-selected:not(.tabulator-range-only-cell-selected):not(.tabulator-range-row-header){background-color:#9abcea}.tabulator-row .tabulator-cell .tabulator-data-tree-branch-empty{display:inline-block;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-branch{border-bottom:2px solid #fff;border-bottom-left-radius:1px;border-left:2px solid #fff;display:inline-block;height:9px;margin-right:5px;margin-top:-9px;vertical-align:middle;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-control{align-items:center;background:rgba(0,0,0,.1);border:1px solid #333;border-radius:2px;display:inline-flex;height:11px;justify-content:center;margin-right:5px;overflow:hidden;vertical-align:middle;width:11px}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover{background:rgba(0,0,0,.2);cursor:pointer}}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:transparent;display:inline-block;height:7px;position:relative;width:1px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{background:#333;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:#333;display:inline-block;height:7px;position:relative;width:1px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:#333;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle{align-items:center;background:#666;border-radius:20px;color:#f3f3f3;display:inline-flex;font-size:1.1em;font-weight:700;height:15px;justify-content:center;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;width:15px}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover{cursor:pointer;opacity:.7}}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close{display:initial}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open{display:none}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle svg{stroke:#f3f3f3}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close{display:none}.tabulator-row .tabulator-cell .tabulator-traffic-light{border-radius:14px;display:inline-block;height:14px;width:14px}.tabulator-row.tabulator-group{background:#ccc;border-bottom:1px solid #999;border-right:1px solid #fff;border-top:1px solid #999;box-sizing:border-box;font-weight:700;padding:5px 5px 5px 10px}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-group:hover{background-color:rgba(0,0,0,.1);cursor:pointer}}.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow{border-bottom:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #3759d7;margin-right:10px}.tabulator-row.tabulator-group.tabulator-group-level-1{padding-left:30px}.tabulator-row.tabulator-group.tabulator-group-level-2{padding-left:50px}.tabulator-row.tabulator-group.tabulator-group-level-3{padding-left:70px}.tabulator-row.tabulator-group.tabulator-group-level-4{padding-left:90px}.tabulator-row.tabulator-group.tabulator-group-level-5{padding-left:110px}.tabulator-row.tabulator-group .tabulator-group-toggle{display:inline-block}.tabulator-row.tabulator-group .tabulator-arrow{border-bottom:6px solid transparent;border-left:6px solid #3759d7;border-right:0;border-top:6px solid transparent;display:inline-block;height:0;margin-right:16px;vertical-align:middle;width:0}.tabulator-row.tabulator-group span{color:#d00;margin-left:10px}.tabulator-toggle{background:#dcdcdc;border:1px solid #ccc;box-sizing:border-box;display:flex;flex-direction:row}.tabulator-toggle.tabulator-toggle-on{background:#1c6cc2}.tabulator-toggle .tabulator-toggle-switch{background:#fff;border:1px solid #ccc;box-sizing:border-box}.tabulator-popup-container{-webkit-overflow-scrolling:touch;background:#f3f3f3;border:1px solid #fff;box-shadow:0 0 5px 0 rgba(0,0,0,.2);box-sizing:border-box;display:inline-block;font-size:16px;overflow-y:auto;position:absolute;z-index:10000}.tabulator-popup{border-radius:3px;padding:5px}.tabulator-tooltip{border-radius:2px;box-shadow:none;font-size:12px;max-width:Min(500px,100%);padding:3px 5px;pointer-events:none}.tabulator-menu .tabulator-menu-item{box-sizing:border-box;padding:5px 10px;position:relative;user-select:none}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator-menu .tabulator-menu-item:not(.tabulator-menu-item-disabled):hover{background:#fff;cursor:pointer}}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu{padding-right:25px}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu:after{border-color:#fff;border-style:solid;border-width:1px 1px 0 0;content:"";display:inline-block;height:7px;position:absolute;right:10px;top:calc(5px + .4em);transform:rotate(45deg);vertical-align:top;width:7px}.tabulator-menu .tabulator-menu-separator{border-top:1px solid #fff}.tabulator-edit-list{-webkit-overflow-scrolling:touch;font-size:16px;max-height:200px;overflow-y:auto}.tabulator-edit-list .tabulator-edit-list-item{color:#333;outline:none;padding:4px}.tabulator-edit-list .tabulator-edit-list-item.active{background:#1d68cd;color:#f3f3f3}.tabulator-edit-list .tabulator-edit-list-item.active.focused{outline:1px solid hsla(0,0%,95%,.5)}.tabulator-edit-list .tabulator-edit-list-item.focused{outline:1px solid #1d68cd}@media (hover:hover) and (pointer:fine){.tabulator-edit-list .tabulator-edit-list-item:hover{background:#1d68cd;color:#f3f3f3;cursor:pointer}}.tabulator-edit-list .tabulator-edit-list-placeholder{color:#333;padding:4px;text-align:center}.tabulator-edit-list .tabulator-edit-list-group{border-bottom:1px solid #fff;color:#333;font-weight:700;padding:6px 4px 4px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-2,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-2{padding-left:12px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-3,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-3{padding-left:20px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-4,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-4{padding-left:28px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-5,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-5{padding-left:36px}.tabulator.tabulator-ltr{direction:ltr}.tabulator.tabulator-rtl{direction:rtl;text-align:initial}.tabulator.tabulator-rtl .tabulator-header .tabulator-col{border-left:1px solid #fff;border-right:initial;text-align:initial}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{margin-left:-1px;margin-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-left:25px;padding-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{left:8px;right:auto}.tabulator.tabulator-rtl .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{background-color:#2544b7;border-radius:999px;bottom:-3px;content:"";height:6px;left:-3px;position:absolute;right:auto;width:6px}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell{border-left:1px solid #fff;border-right:initial}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-branch{border-bottom-left-radius:0;border-bottom-right-radius:1px;border-left:initial;border-right:2px solid #fff;margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-control{margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-left:2px solid #fff}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-right:2px solid #fff}.tabulator.tabulator-rtl .tabulator-row .tabulator-col-resize-handle:last-of-type{margin-left:0;margin-right:-3px;width:3px}.tabulator.tabulator-rtl .tabulator-footer .tabulator-calcs-holder{text-align:initial}.tabulator-print-fullscreen{bottom:0;left:0;position:absolute;right:0;top:0;z-index:10000}body.tabulator-print-fullscreen-hide>:not(.tabulator-print-fullscreen){display:none!important}.tabulator-print-table{border-collapse:collapse}.tabulator-print-table .tabulator-data-tree-branch{border-bottom:2px solid #fff;border-bottom-left-radius:1px;border-left:2px solid #fff;display:inline-block;height:9px;margin-right:5px;margin-top:-9px;vertical-align:middle;width:7px}.tabulator-print-table .tabulator-print-table-group{background:#ccc;border-bottom:1px solid #999;border-right:1px solid #fff;border-top:1px solid #999;box-sizing:border-box;font-weight:700;min-width:100%;padding:5px 5px 5px 10px}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-print-table-group:hover{background-color:rgba(0,0,0,.1);cursor:pointer}}.tabulator-print-table .tabulator-print-table-group.tabulator-group-visible .tabulator-arrow{border-bottom:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #3759d7;margin-right:10px}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-1 td{padding-left:30px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-2 td{padding-left:50px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-3 td{padding-left:70px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-4 td{padding-left:90px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-5 td{padding-left:110px!important}.tabulator-print-table .tabulator-print-table-group .tabulator-group-toggle{display:inline-block}.tabulator-print-table .tabulator-print-table-group .tabulator-arrow{border-bottom:6px solid transparent;border-left:6px solid #3759d7;border-right:0;border-top:6px solid transparent;display:inline-block;height:0;margin-right:16px;vertical-align:middle;width:0}.tabulator-print-table .tabulator-print-table-group span{color:#d00;margin-left:10px}.tabulator-print-table .tabulator-data-tree-control{align-items:center;background:rgba(0,0,0,.1);border:1px solid #333;border-radius:2px;display:inline-flex;height:11px;justify-content:center;margin-right:5px;overflow:hidden;vertical-align:middle;width:11px}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-data-tree-control:hover{background:rgba(0,0,0,.2);cursor:pointer}}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:transparent;display:inline-block;height:7px;position:relative;width:1px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{background:#333;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:#333;display:inline-block;height:7px;position:relative;width:1px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:#333;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator .tabulator-header{border-bottom:3px solid #3759d7;font-size:1.1em;margin-bottom:4px;padding-left:10px}.tabulator .tabulator-header .tabulator-col{background-color:#fff;border-right:2px solid #fff}.tabulator .tabulator-header .tabulator-col:first-child{padding-left:10px}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor{border:1px solid #3759d7;color:#3759d7;font-size:1em}.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{border-top:2px solid #3759d7}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left{padding-left:10px}.tabulator .tabulator-header .tabulator-calcs-holder{border-top:2px solid #3759d7!important}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row{padding-left:0!important}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-cell{background:none}.tabulator .tabulator-tableholder .tabulator-placeholder span{color:#3759d7}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top{border-bottom:2px solid #3759d7}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom{border-top:2px solid #3759d7}.tabulator .tabulator-footer .tabulator-calcs-holder{border-bottom:2px solid #3759d7!important;border-top:3px solid #3759d7!important}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row{background:#fff!important}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-cell{background:none}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-cell:first-child{border-left:10px solid transparent}.tabulator .tabulator-footer .tabulator-calcs-holder:only-child{border-bottom:none!important}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab{border-color:#aaa;color:#333;font-weight:400}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active{color:#3759d7;font-weight:700}.tabulator-row{margin-bottom:2px}.tabulator-row .tabulator-cell:first-child{border-left:10px solid #3759d7}.tabulator-row .tabulator-cell.tabulator-row-header{background-color:#3759d7;color:#fff}.tabulator-row:nth-child(2n){background-color:#627ce0}.tabulator-row:nth-child(2n) .tabulator-cell{background-color:#fff}.tabulator-row:nth-child(2n) .tabulator-cell:first-child{border-left:10px solid #627ce0}.tabulator-row:nth-child(2n) .tabulator-cell.tabulator-row-header{background-color:#627ce0}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selectable:hover{cursor:pointer}.tabulator-row.tabulator-selectable:hover .tabulator-cell{background-color:#bbb}}.tabulator-row.tabulator-selected .tabulator-cell{background-color:#9abcea}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selected:hover .tabulator-cell{background-color:#769bcc;cursor:pointer}}.tabulator-row.tabulator-moving{pointer-events:none!important}.tabulator-row .tabulator-cell{background-color:#f3f3f3;border-right:2px solid #fff;padding:6px 4px}.tabulator-row.tabulator-group{background:#8ca0e8;border-bottom:2px solid #3759d7;border-right:none;border-top:2px solid #3759d7;margin-bottom:2px;min-width:100%}.tabulator-row.tabulator-group span{color:#3759d7}.tabulator-toggle.tabulator-toggle-on{background:#3759d7}.tabulator-edit-select-list{border:1px solid #1d68cd}.tabulator-print-table .tabulator-print-table-group{background:#8ca0e8;border-bottom:2px solid #3759d7;border-top:2px solid #3759d7;margin-bottom:2px}.tabulator-print-table .tabulator-print-table-group span{color:#3759d7}
2 |
--------------------------------------------------------------------------------
/nicegui_tabulator/core/libs/tabulator_simple.min.css:
--------------------------------------------------------------------------------
1 | .tabulator{border:1px solid #999;font-size:14px;overflow:hidden;position:relative;text-align:left;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}.tabulator[tabulator-layout=fitDataFill] .tabulator-tableholder .tabulator-table{min-width:100%}.tabulator[tabulator-layout=fitDataTable]{display:inline-block}.tabulator.tabulator-block-select,.tabulator.tabulator-ranges .tabulator-cell:not(.tabulator-editing){user-select:none}.tabulator .tabulator-header{background-color:#fff;border-bottom:1px solid #999;box-sizing:border-box;color:#555;font-weight:700;outline:none;overflow:hidden;position:relative;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;white-space:nowrap;width:100%}.tabulator .tabulator-header.tabulator-header-hidden{display:none}.tabulator .tabulator-header .tabulator-header-contents{overflow:hidden;position:relative}.tabulator .tabulator-header .tabulator-header-contents .tabulator-headers{display:inline-block}.tabulator .tabulator-header .tabulator-col{background:#fff;border-right:1px solid #ddd;box-sizing:border-box;display:inline-flex;flex-direction:column;justify-content:flex-start;overflow:hidden;position:relative;text-align:left;vertical-align:bottom}.tabulator .tabulator-header .tabulator-col.tabulator-moving{background:#e6e6e6;border:1px solid #999;pointer-events:none;position:absolute}.tabulator .tabulator-header .tabulator-col.tabulator-range-highlight{background-color:#d6d6d6;color:#000}.tabulator .tabulator-header .tabulator-col.tabulator-range-selected{background-color:#3876ca;color:#fff}.tabulator .tabulator-header .tabulator-col .tabulator-col-content{box-sizing:border-box;padding:4px;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button{padding:0 8px}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button:hover{cursor:pointer;opacity:.6}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title-holder{position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title{box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title.tabulator-col-title-wrap{text-overflow:clip;white-space:normal}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor{background:#fff;border:1px solid #999;box-sizing:border-box;padding:1px;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-header-popup-button+.tabulator-title-editor{width:calc(100% - 22px)}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{align-items:center;bottom:0;display:flex;position:absolute;right:4px;top:0}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #bbb;border-left:6px solid transparent;border-right:6px solid transparent;height:0;width:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{border-top:1px solid #ddd;display:flex;margin-right:-1px;overflow:hidden;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter{box-sizing:border-box;margin-top:2px;position:relative;text-align:center;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea{height:auto!important}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg{margin-top:3px}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear{height:0;width:0}.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-right:25px}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable.tabulator-col-sorter-element:hover{background-color:#e6e6e6;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter{color:#bbb}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-bottom:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #bbb;border-top:none}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter{color:#666}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-bottom:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #666;border-top:none}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter{color:#666}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-top:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:none;border-top:6px solid #666;color:#666}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title{align-items:center;display:flex;justify-content:center;text-orientation:mixed;writing-mode:vertical-rl}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title{transform:rotate(180deg)}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title{padding-right:0;padding-top:20px}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title{padding-bottom:20px;padding-right:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-sorter{bottom:auto;justify-content:center;left:0;right:0;top:4px}.tabulator .tabulator-header .tabulator-frozen{left:0;position:sticky;z-index:11}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left{border-right:2px solid #ddd}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right{border-left:2px solid #ddd}.tabulator .tabulator-header .tabulator-calcs-holder{background:#fff!important;border-bottom:1px solid #ddd;border-top:1px solid #ddd;box-sizing:border-box;display:inline-block}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row{background:#fff!important}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-header .tabulator-frozen-rows-holder{display:inline-block}.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty{display:none}.tabulator .tabulator-tableholder{-webkit-overflow-scrolling:touch;overflow:auto;position:relative;white-space:nowrap;width:100%}.tabulator .tabulator-tableholder:focus{outline:none}.tabulator .tabulator-tableholder .tabulator-placeholder{align-items:center;box-sizing:border-box;display:flex;justify-content:center;min-width:100%;width:100%}.tabulator .tabulator-tableholder .tabulator-placeholder[tabulator-render-mode=virtual]{min-height:100%}.tabulator .tabulator-tableholder .tabulator-placeholder .tabulator-placeholder-contents{color:#ccc;display:inline-block;font-size:20px;font-weight:700;padding:10px;text-align:center;white-space:normal}.tabulator .tabulator-tableholder .tabulator-table{background-color:#fff;color:#333;display:inline-block;overflow:visible;position:relative;white-space:nowrap}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs{background:#f2f2f2!important;font-weight:700}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top{border-bottom:2px solid #ddd}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom{border-top:2px solid #ddd}.tabulator .tabulator-tableholder .tabulator-range-overlay{inset:0;pointer-events:none;position:absolute;z-index:10}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range{border:1px solid #2975dd;box-sizing:border-box;position:absolute}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{background-color:#2975dd;border-radius:999px;bottom:-3px;content:"";height:6px;position:absolute;right:-3px;width:6px}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range-cell-active{border:2px solid #2975dd;box-sizing:border-box;position:absolute}.tabulator .tabulator-footer{background-color:#fff;border-top:1px solid #999;color:#555;font-weight:700;user-select:none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;white-space:nowrap}.tabulator .tabulator-footer .tabulator-footer-contents{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:5px 10px}.tabulator .tabulator-footer .tabulator-footer-contents:empty{display:none}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs{margin-top:-5px;overflow-x:auto}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab{border:1px solid #999;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top:none;display:inline-block;font-size:.9em;padding:5px}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab:hover{cursor:pointer;opacity:.7}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active{background:#fff}.tabulator .tabulator-footer .tabulator-calcs-holder{background:#fff!important;border-bottom:1px solid #ddd;border-top:1px solid #ddd;box-sizing:border-box;overflow:hidden;text-align:left;width:100%}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row{background:#fff!important;display:inline-block}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-footer .tabulator-calcs-holder:only-child{border-bottom:none;margin-bottom:-5px}.tabulator .tabulator-footer>*+.tabulator-page-counter{margin-left:10px}.tabulator .tabulator-footer .tabulator-page-counter{font-weight:400}.tabulator .tabulator-footer .tabulator-paginator{color:#555;flex:1;font-family:inherit;font-size:inherit;font-weight:inherit;text-align:right}.tabulator .tabulator-footer .tabulator-page-size{border:1px solid #aaa;border-radius:3px;display:inline-block;margin:0 5px;padding:2px 5px}.tabulator .tabulator-footer .tabulator-pages{margin:0 7px}.tabulator .tabulator-footer .tabulator-page{background:hsla(0,0%,100%,.2);border:1px solid #aaa;border-radius:3px;display:inline-block;margin:0 2px;padding:2px 5px}.tabulator .tabulator-footer .tabulator-page.active{color:#d00}.tabulator .tabulator-footer .tabulator-page:disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-footer .tabulator-page:not(disabled):hover{background:rgba(0,0,0,.2);color:#fff;cursor:pointer}}.tabulator .tabulator-col-resize-handle{display:inline-block;margin-left:-3px;margin-right:-3px;position:relative;vertical-align:middle;width:6px;z-index:11}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-col-resize-handle:hover{cursor:ew-resize}}.tabulator .tabulator-col-resize-handle:last-of-type{margin-right:0;width:3px}.tabulator .tabulator-col-resize-guide{background-color:#999;height:100%;margin-left:-.5px;opacity:.5;position:absolute;top:0;width:4px}.tabulator .tabulator-row-resize-guide{background-color:#999;height:4px;left:0;margin-top:-.5px;opacity:.5;position:absolute;width:100%}.tabulator .tabulator-alert{align-items:center;background:rgba(0,0,0,.4);display:flex;height:100%;left:0;position:absolute;text-align:center;top:0;width:100%;z-index:100}.tabulator .tabulator-alert .tabulator-alert-msg{background:#fff;border-radius:10px;display:inline-block;font-size:16px;font-weight:700;margin:0 auto;padding:10px 20px}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-msg{border:4px solid #333;color:#000}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-error{border:4px solid #d00;color:#590000}.tabulator-row{box-sizing:border-box;min-height:22px;position:relative}.tabulator-row,.tabulator-row.tabulator-row-even{background-color:#fff}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selectable:hover{background-color:#bbb;cursor:pointer}}.tabulator-row.tabulator-selected{background-color:#9abcea}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selected:hover{background-color:#769bcc;cursor:pointer}}.tabulator-row.tabulator-row-moving{background:#fff;border:1px solid #000}.tabulator-row.tabulator-moving{border-bottom:1px solid #ddd;border-top:1px solid #ddd;pointer-events:none;position:absolute;z-index:15}.tabulator-row.tabulator-range-highlight .tabulator-cell.tabulator-range-row-header{background-color:#d6d6d6;color:#000}.tabulator-row.tabulator-range-highlight.tabulator-range-selected .tabulator-cell.tabulator-range-row-header,.tabulator-row.tabulator-range-selected .tabulator-cell.tabulator-range-row-header{background-color:#3876ca;color:#fff}.tabulator-row .tabulator-row-resize-handle{bottom:0;height:5px;left:0;position:absolute;right:0}.tabulator-row .tabulator-row-resize-handle.prev{bottom:auto;top:0}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-row-resize-handle:hover{cursor:ns-resize}}.tabulator-row .tabulator-responsive-collapse{border-bottom:1px solid #ddd;border-top:1px solid #ddd;box-sizing:border-box;padding:5px}.tabulator-row .tabulator-responsive-collapse:empty{display:none}.tabulator-row .tabulator-responsive-collapse table{font-size:14px}.tabulator-row .tabulator-responsive-collapse table tr td{position:relative}.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type{padding-right:10px}.tabulator-row .tabulator-cell{border-right:1px solid #ddd;box-sizing:border-box;display:inline-block;outline:none;overflow:hidden;padding:4px;position:relative;text-overflow:ellipsis;vertical-align:middle;white-space:nowrap}.tabulator-row .tabulator-cell.tabulator-row-header{background:#fff;border-bottom:1px solid #ddd;border-right:1px solid #999}.tabulator-row .tabulator-cell.tabulator-frozen{background-color:inherit;display:inline-block;left:0;position:sticky;z-index:11}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-right:2px solid #ddd}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-left:2px solid #ddd}.tabulator-row .tabulator-cell.tabulator-editing{border:1px solid #1d68cd;outline:none;padding:0}.tabulator-row .tabulator-cell.tabulator-editing input,.tabulator-row .tabulator-cell.tabulator-editing select{background:transparent;border:1px;outline:none}.tabulator-row .tabulator-cell.tabulator-validation-fail{border:1px solid #d00}.tabulator-row .tabulator-cell.tabulator-validation-fail input,.tabulator-row .tabulator-cell.tabulator-validation-fail select{background:transparent;border:1px;color:#d00}.tabulator-row .tabulator-cell.tabulator-row-handle{align-items:center;display:inline-flex;justify-content:center;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box{width:80%}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar{background:#666;height:3px;margin-top:2px;width:100%}.tabulator-row .tabulator-cell.tabulator-range-selected:not(.tabulator-range-only-cell-selected):not(.tabulator-range-row-header){background-color:#9abcea}.tabulator-row .tabulator-cell .tabulator-data-tree-branch-empty{display:inline-block;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-branch{border-bottom:2px solid #ddd;border-bottom-left-radius:1px;border-left:2px solid #ddd;display:inline-block;height:9px;margin-right:5px;margin-top:-9px;vertical-align:middle;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-control{align-items:center;background:rgba(0,0,0,.1);border:1px solid #333;border-radius:2px;display:inline-flex;height:11px;justify-content:center;margin-right:5px;overflow:hidden;vertical-align:middle;width:11px}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover{background:rgba(0,0,0,.2);cursor:pointer}}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:transparent;display:inline-block;height:7px;position:relative;width:1px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{background:#333;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:#333;display:inline-block;height:7px;position:relative;width:1px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:#333;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle{align-items:center;background:#666;border-radius:20px;color:#fff;display:inline-flex;font-size:1.1em;font-weight:700;height:15px;justify-content:center;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;width:15px}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover{cursor:pointer;opacity:.7}}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close{display:initial}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open{display:none}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle svg{stroke:#fff}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close{display:none}.tabulator-row .tabulator-cell .tabulator-traffic-light{border-radius:14px;display:inline-block;height:14px;width:14px}.tabulator-row.tabulator-group{background:#ccc;border-bottom:1px solid #999;border-right:1px solid #ddd;border-top:1px solid #999;box-sizing:border-box;font-weight:700;min-width:100%;padding:5px 5px 5px 10px}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-group:hover{background-color:rgba(0,0,0,.1);cursor:pointer}}.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow{border-bottom:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #666;margin-right:10px}.tabulator-row.tabulator-group.tabulator-group-level-1{padding-left:30px}.tabulator-row.tabulator-group.tabulator-group-level-2{padding-left:50px}.tabulator-row.tabulator-group.tabulator-group-level-3{padding-left:70px}.tabulator-row.tabulator-group.tabulator-group-level-4{padding-left:90px}.tabulator-row.tabulator-group.tabulator-group-level-5{padding-left:110px}.tabulator-row.tabulator-group .tabulator-group-toggle{display:inline-block}.tabulator-row.tabulator-group .tabulator-arrow{border-bottom:6px solid transparent;border-left:6px solid #666;border-right:0;border-top:6px solid transparent;display:inline-block;height:0;margin-right:16px;vertical-align:middle;width:0}.tabulator-row.tabulator-group span{color:#d00;margin-left:10px}.tabulator-toggle{background:#dcdcdc;border:1px solid #ccc;box-sizing:border-box;display:flex;flex-direction:row}.tabulator-toggle.tabulator-toggle-on{background:#1c6cc2}.tabulator-toggle .tabulator-toggle-switch{background:#fff;border:1px solid #ccc;box-sizing:border-box}.tabulator-popup-container{-webkit-overflow-scrolling:touch;background:#fff;border:1px solid #ddd;box-shadow:0 0 5px 0 rgba(0,0,0,.2);box-sizing:border-box;display:inline-block;font-size:14px;overflow-y:auto;position:absolute;z-index:10000}.tabulator-popup{border-radius:3px;padding:5px}.tabulator-tooltip{border-radius:2px;box-shadow:none;font-size:12px;max-width:Min(500px,100%);padding:3px 5px;pointer-events:none}.tabulator-menu .tabulator-menu-item{box-sizing:border-box;padding:5px 10px;position:relative;user-select:none}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator-menu .tabulator-menu-item:not(.tabulator-menu-item-disabled):hover{background:#fff;cursor:pointer}}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu{padding-right:25px}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu:after{border-color:#ddd;border-style:solid;border-width:1px 1px 0 0;content:"";display:inline-block;height:7px;position:absolute;right:10px;top:calc(5px + .4em);transform:rotate(45deg);vertical-align:top;width:7px}.tabulator-menu .tabulator-menu-separator{border-top:1px solid #ddd}.tabulator-edit-list{-webkit-overflow-scrolling:touch;font-size:14px;max-height:200px;overflow-y:auto}.tabulator-edit-list .tabulator-edit-list-item{color:#333;outline:none;padding:4px}.tabulator-edit-list .tabulator-edit-list-item.active{background:#1d68cd;color:#fff}.tabulator-edit-list .tabulator-edit-list-item.active.focused{outline:1px solid hsla(0,0%,100%,.5)}.tabulator-edit-list .tabulator-edit-list-item.focused{outline:1px solid #1d68cd}@media (hover:hover) and (pointer:fine){.tabulator-edit-list .tabulator-edit-list-item:hover{background:#1d68cd;color:#fff;cursor:pointer}}.tabulator-edit-list .tabulator-edit-list-placeholder{color:#333;padding:4px;text-align:center}.tabulator-edit-list .tabulator-edit-list-group{border-bottom:1px solid #ddd;color:#333;font-weight:700;padding:6px 4px 4px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-2,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-2{padding-left:12px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-3,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-3{padding-left:20px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-4,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-4{padding-left:28px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-5,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-5{padding-left:36px}.tabulator.tabulator-ltr{direction:ltr}.tabulator.tabulator-rtl{direction:rtl;text-align:initial}.tabulator.tabulator-rtl .tabulator-header .tabulator-col{border-left:1px solid #ddd;border-right:initial;text-align:initial}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{margin-left:-1px;margin-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-left:25px;padding-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{left:8px;right:auto}.tabulator.tabulator-rtl .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{background-color:#2975dd;border-radius:999px;bottom:-3px;content:"";height:6px;left:-3px;position:absolute;right:auto;width:6px}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell{border-left:1px solid #ddd;border-right:initial}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-branch{border-bottom-left-radius:0;border-bottom-right-radius:1px;border-left:initial;border-right:2px solid #ddd;margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-control{margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-left:2px solid #ddd}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-right:2px solid #ddd}.tabulator.tabulator-rtl .tabulator-row .tabulator-col-resize-handle:last-of-type{margin-left:0;margin-right:-3px;width:3px}.tabulator.tabulator-rtl .tabulator-footer .tabulator-calcs-holder{text-align:initial}.tabulator-print-fullscreen{bottom:0;left:0;position:absolute;right:0;top:0;z-index:10000}body.tabulator-print-fullscreen-hide>:not(.tabulator-print-fullscreen){display:none!important}.tabulator-print-table{border-collapse:collapse}.tabulator-print-table .tabulator-data-tree-branch{border-bottom:2px solid #ddd;border-bottom-left-radius:1px;border-left:2px solid #ddd;display:inline-block;height:9px;margin-right:5px;margin-top:-9px;vertical-align:middle;width:7px}.tabulator-print-table .tabulator-print-table-group{background:#ccc;border-bottom:1px solid #999;border-right:1px solid #ddd;border-top:1px solid #999;box-sizing:border-box;font-weight:700;min-width:100%;padding:5px 5px 5px 10px}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-print-table-group:hover{background-color:rgba(0,0,0,.1);cursor:pointer}}.tabulator-print-table .tabulator-print-table-group.tabulator-group-visible .tabulator-arrow{border-bottom:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #666;margin-right:10px}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-1 td{padding-left:30px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-2 td{padding-left:50px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-3 td{padding-left:70px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-4 td{padding-left:90px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-5 td{padding-left:110px!important}.tabulator-print-table .tabulator-print-table-group .tabulator-group-toggle{display:inline-block}.tabulator-print-table .tabulator-print-table-group .tabulator-arrow{border-bottom:6px solid transparent;border-left:6px solid #666;border-right:0;border-top:6px solid transparent;display:inline-block;height:0;margin-right:16px;vertical-align:middle;width:0}.tabulator-print-table .tabulator-print-table-group span{color:#d00}.tabulator-print-table .tabulator-data-tree-control{align-items:center;background:rgba(0,0,0,.1);border:1px solid #333;border-radius:2px;display:inline-flex;height:11px;justify-content:center;margin-right:5px;overflow:hidden;vertical-align:middle;width:11px}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-data-tree-control:hover{background:rgba(0,0,0,.2);cursor:pointer}}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:transparent;display:inline-block;height:7px;position:relative;width:1px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{background:#333;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:#333;display:inline-block;height:7px;position:relative;width:1px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:#333;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator{background-color:#fff;border:none}.tabulator .tabulator-header .tabulator-calcs-holder{background:#f2f2f2!important;border-bottom:1px solid #999}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row{background:#f2f2f2!important}.tabulator .tabulator-tableholder .tabulator-placeholder span{color:#000}.tabulator .tabulator-footer .tabulator-calcs-holder{background:#f2f2f2!important;border-bottom:1px solid #fff}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row{background:#f2f2f2!important}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab{font-weight:400}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active{color:#d00;font-weight:700}.tabulator-row{border-bottom:1px solid #ddd}.tabulator-row .tabulator-cell:last-of-type{border-right:none}.tabulator-row .tabulator-cell.tabulator-row-header{border-bottom:none}.tabulator-row.tabulator-group span{color:#666}.tabulator-print-table .tabulator-print-table-group span{color:#666;margin-left:10px}
2 |
--------------------------------------------------------------------------------
/nicegui_tabulator/core/libs/tabulator_site.min.css:
--------------------------------------------------------------------------------
1 | .tabulator{background-color:#fff;border:1px solid #222;font-size:14px;overflow:hidden;position:relative;text-align:left;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}.tabulator[tabulator-layout=fitDataFill] .tabulator-tableholder .tabulator-table{min-width:100%}.tabulator[tabulator-layout=fitDataTable]{display:inline-block}.tabulator.tabulator-block-select,.tabulator.tabulator-ranges .tabulator-cell:not(.tabulator-editing){user-select:none}.tabulator .tabulator-header{background-color:#222;border-bottom:1px solid #3fb449;box-sizing:border-box;color:#fff;font-weight:700;outline:none;overflow:hidden;position:relative;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;white-space:nowrap;width:100%}.tabulator .tabulator-header.tabulator-header-hidden{display:none}.tabulator .tabulator-header .tabulator-header-contents{overflow:hidden;position:relative}.tabulator .tabulator-header .tabulator-header-contents .tabulator-headers{display:inline-block}.tabulator .tabulator-header .tabulator-col{background:#222;border-right:1px solid #aaa;box-sizing:border-box;display:inline-flex;flex-direction:column;justify-content:flex-start;overflow:hidden;position:relative;text-align:left;vertical-align:bottom}.tabulator .tabulator-header .tabulator-col.tabulator-moving{background:#090909;border:1px solid #3fb449;pointer-events:none;position:absolute}.tabulator .tabulator-header .tabulator-col.tabulator-range-highlight{background-color:#70c28e;color:#000}.tabulator .tabulator-header .tabulator-col.tabulator-range-selected{background-color:#269b51;color:#fff}.tabulator .tabulator-header .tabulator-col .tabulator-col-content{box-sizing:border-box;padding:4px;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button{padding:0 8px}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button:hover{cursor:pointer;opacity:.6}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title-holder{position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title{box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title.tabulator-col-title-wrap{text-overflow:clip;white-space:normal}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor{background:#fff;border:1px solid #999;box-sizing:border-box;padding:1px;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-header-popup-button+.tabulator-title-editor{width:calc(100% - 22px)}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{align-items:center;bottom:0;display:flex;position:absolute;right:4px;top:0}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #bbb;border-left:6px solid transparent;border-right:6px solid transparent;height:0;width:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{border-top:1px solid #aaa;display:flex;margin-right:-1px;overflow:hidden;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter{box-sizing:border-box;margin-top:2px;position:relative;text-align:center;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea{height:auto!important}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg{margin-top:3px}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear{height:0;width:0}.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-right:25px}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable.tabulator-col-sorter-element:hover{background-color:#090909;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter{color:#bbb}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-bottom:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #bbb;border-top:none}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter{color:#3fb449}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-bottom:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #3fb449;border-top:none}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter{color:#3fb449}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-top:6px solid #555;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:none;border-top:6px solid #3fb449;color:#3fb449}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title{align-items:center;display:flex;justify-content:center;text-orientation:mixed;writing-mode:vertical-rl}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title{transform:rotate(180deg)}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title{padding-right:0;padding-top:20px}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title{padding-bottom:20px;padding-right:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-sorter{bottom:auto;justify-content:center;left:0;right:0;top:4px}.tabulator .tabulator-header .tabulator-frozen{left:0;position:sticky;z-index:11}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left{border-right:2px solid #aaa}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right{border-left:2px solid #aaa}.tabulator .tabulator-header .tabulator-calcs-holder{background:#2f2f2f!important;border-bottom:1px solid #aaa;box-sizing:border-box;display:inline-block}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row{background:#2f2f2f!important}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-header .tabulator-frozen-rows-holder{display:inline-block}.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty{display:none}.tabulator .tabulator-tableholder{-webkit-overflow-scrolling:touch;overflow:auto;position:relative;white-space:nowrap;width:100%}.tabulator .tabulator-tableholder:focus{outline:none}.tabulator .tabulator-tableholder .tabulator-placeholder{align-items:center;box-sizing:border-box;display:flex;justify-content:center;min-width:100%;width:100%}.tabulator .tabulator-tableholder .tabulator-placeholder[tabulator-render-mode=virtual]{min-height:100%}.tabulator .tabulator-tableholder .tabulator-placeholder .tabulator-placeholder-contents{color:#ccc;display:inline-block;font-size:20px;font-weight:700;padding:10px;text-align:center;white-space:normal}.tabulator .tabulator-tableholder .tabulator-table{background-color:#fff;color:#333;display:inline-block;overflow:visible;position:relative;white-space:nowrap}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs{background:#e2e2e2!important}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top{border-bottom:2px solid #aaa}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom{border-top:2px solid #aaa}.tabulator .tabulator-tableholder .tabulator-range-overlay{inset:0;pointer-events:none;position:absolute;z-index:10}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range{border:1px solid #269b51;box-sizing:border-box;position:absolute}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{background-color:#269b51;border-radius:999px;bottom:-3px;content:"";height:6px;position:absolute;right:-3px;width:6px}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range-cell-active{border:2px solid #269b51;box-sizing:border-box;position:absolute}.tabulator .tabulator-footer{background-color:#222;border-top:1px solid #3fb449;color:#222;font-weight:700;user-select:none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;white-space:nowrap}.tabulator .tabulator-footer .tabulator-footer-contents{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:5px 10px}.tabulator .tabulator-footer .tabulator-footer-contents:empty{display:none}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs{margin-top:-5px;overflow-x:auto}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab{border:1px solid #222;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top:none;display:inline-block;font-size:.9em;padding:5px}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab:hover{cursor:pointer;opacity:.7}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active{background:#fff}.tabulator .tabulator-footer .tabulator-calcs-holder{background:#2f2f2f!important;border-top:1px solid #aaa;box-sizing:border-box;overflow:hidden;text-align:left;width:100%}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row{background:#2f2f2f!important;display:inline-block}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-footer .tabulator-calcs-holder:only-child{border-bottom:none;margin-bottom:-5px}.tabulator .tabulator-footer>*+.tabulator-page-counter{margin-left:10px}.tabulator .tabulator-footer .tabulator-page-counter{font-weight:400}.tabulator .tabulator-footer .tabulator-paginator{color:#222;flex:1;font-family:inherit;font-size:inherit;font-weight:inherit;text-align:right}.tabulator .tabulator-footer .tabulator-page-size{border:1px solid #aaa;border-radius:3px;display:inline-block;margin:0 5px;padding:2px 5px}.tabulator .tabulator-footer .tabulator-pages{margin:0 7px}.tabulator .tabulator-footer .tabulator-page{background:hsla(0,0%,100%,.2);border:1px solid #aaa;border-radius:3px;display:inline-block;margin:0 2px;padding:2px 5px}.tabulator .tabulator-footer .tabulator-page.active{color:#3fb449}.tabulator .tabulator-footer .tabulator-page:disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-footer .tabulator-page:not(disabled):hover{background:rgba(0,0,0,.2);color:#fff;cursor:pointer}}.tabulator .tabulator-col-resize-handle{display:inline-block;margin-left:-3px;margin-right:-3px;position:relative;vertical-align:middle;width:6px;z-index:11}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-col-resize-handle:hover{cursor:ew-resize}}.tabulator .tabulator-col-resize-handle:last-of-type{margin-right:0;width:3px}.tabulator .tabulator-col-resize-guide{background-color:#999;height:100%;margin-left:-.5px;opacity:.5;position:absolute;top:0;width:4px}.tabulator .tabulator-row-resize-guide{background-color:#999;height:4px;left:0;margin-top:-.5px;opacity:.5;position:absolute;width:100%}.tabulator .tabulator-alert{align-items:center;background:rgba(0,0,0,.4);display:flex;height:100%;left:0;position:absolute;text-align:center;top:0;width:100%;z-index:100}.tabulator .tabulator-alert .tabulator-alert-msg{background:#fff;border-radius:10px;display:inline-block;font-size:16px;font-weight:700;margin:0 auto;padding:10px 20px}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-msg{border:4px solid #333;color:#000}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-error{border:4px solid #d00;color:#590000}.tabulator-row{background-color:#fff;box-sizing:border-box;min-height:22px;position:relative}.tabulator-row.tabulator-row-even{background-color:#efefef}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selectable:hover{background-color:#bbb;cursor:pointer}}.tabulator-row.tabulator-selected{background-color:#70c28e}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selected:hover{background-color:#269b51;cursor:pointer}}.tabulator-row.tabulator-row-moving{background:#fff;border:1px solid #000}.tabulator-row.tabulator-moving{border-bottom:1px solid #aaa;border-top:1px solid #aaa;pointer-events:none;position:absolute;z-index:15}.tabulator-row.tabulator-range-highlight .tabulator-cell.tabulator-range-row-header{background-color:#70c28e;color:#000}.tabulator-row.tabulator-range-highlight.tabulator-range-selected .tabulator-cell.tabulator-range-row-header,.tabulator-row.tabulator-range-selected .tabulator-cell.tabulator-range-row-header{background-color:#269b51;color:#fff}.tabulator-row .tabulator-row-resize-handle{bottom:0;height:5px;left:0;position:absolute;right:0}.tabulator-row .tabulator-row-resize-handle.prev{bottom:auto;top:0}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-row-resize-handle:hover{cursor:ns-resize}}.tabulator-row .tabulator-responsive-collapse{border-bottom:1px solid #aaa;border-top:1px solid #aaa;box-sizing:border-box;padding:5px}.tabulator-row .tabulator-responsive-collapse:empty{display:none}.tabulator-row .tabulator-responsive-collapse table{font-size:14px}.tabulator-row .tabulator-responsive-collapse table tr td{position:relative}.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type{padding-right:10px}.tabulator-row .tabulator-cell{border-right:1px solid #aaa;box-sizing:border-box;display:inline-block;outline:none;overflow:hidden;padding:4px;position:relative;text-overflow:ellipsis;vertical-align:middle;white-space:nowrap}.tabulator-row .tabulator-cell.tabulator-row-header{background:#222;border-bottom:1px solid #aaa;border-right:1px solid #222}.tabulator-row .tabulator-cell.tabulator-frozen{background-color:inherit;display:inline-block;left:0;position:sticky;z-index:11}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-right:2px solid #aaa}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-left:2px solid #aaa}.tabulator-row .tabulator-cell.tabulator-editing{border:1px solid #1d68cd;outline:none;padding:0}.tabulator-row .tabulator-cell.tabulator-editing input,.tabulator-row .tabulator-cell.tabulator-editing select{background:transparent;border:1px;outline:none}.tabulator-row .tabulator-cell.tabulator-validation-fail{border:1px solid #d00}.tabulator-row .tabulator-cell.tabulator-validation-fail input,.tabulator-row .tabulator-cell.tabulator-validation-fail select{background:transparent;border:1px;color:#d00}.tabulator-row .tabulator-cell.tabulator-row-handle{align-items:center;display:inline-flex;justify-content:center;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box{width:80%}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar{background:#666;height:3px;margin-top:2px;width:100%}.tabulator-row .tabulator-cell.tabulator-range-selected:not(.tabulator-range-only-cell-selected):not(.tabulator-range-row-header){background-color:#70c28e}.tabulator-row .tabulator-cell .tabulator-data-tree-branch-empty{display:inline-block;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-branch{border-bottom:2px solid #aaa;border-bottom-left-radius:1px;border-left:2px solid #aaa;display:inline-block;height:9px;margin-right:5px;margin-top:-9px;vertical-align:middle;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-control{align-items:center;background:rgba(0,0,0,.1);border:1px solid #333;border-radius:2px;display:inline-flex;height:11px;justify-content:center;margin-right:5px;overflow:hidden;vertical-align:middle;width:11px}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover{background:rgba(0,0,0,.2);cursor:pointer}}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:transparent;display:inline-block;height:7px;position:relative;width:1px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{background:#333;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:#333;display:inline-block;height:7px;position:relative;width:1px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:#333;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle{align-items:center;background:#666;border-radius:20px;color:#fff;display:inline-flex;font-size:1.1em;font-weight:700;height:15px;justify-content:center;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;width:15px}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover{cursor:pointer;opacity:.7}}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close{display:initial}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open{display:none}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle svg{stroke:#fff}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close{display:none}.tabulator-row .tabulator-cell .tabulator-traffic-light{border-radius:14px;display:inline-block;height:14px;width:14px}.tabulator-row.tabulator-group{background:#ccc;border-bottom:1px solid #999;border-top:1px solid #999;box-sizing:border-box;font-weight:700;min-width:100%;padding:5px 5px 5px 10px}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-group:hover{background-color:rgba(0,0,0,.1);cursor:pointer}}.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow{border-bottom:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #3fb449;margin-right:10px}.tabulator-row.tabulator-group.tabulator-group-level-1{padding-left:30px}.tabulator-row.tabulator-group.tabulator-group-level-2{padding-left:50px}.tabulator-row.tabulator-group.tabulator-group-level-3{padding-left:70px}.tabulator-row.tabulator-group.tabulator-group-level-4{padding-left:90px}.tabulator-row.tabulator-group.tabulator-group-level-5{padding-left:110px}.tabulator-row.tabulator-group .tabulator-group-toggle{display:inline-block}.tabulator-row.tabulator-group .tabulator-arrow{border-bottom:6px solid transparent;border-left:6px solid #3fb449;border-right:0;border-top:6px solid transparent;display:inline-block;height:0;margin-right:16px;vertical-align:middle;width:0}.tabulator-row.tabulator-group span{color:#d00;margin-left:10px}.tabulator-toggle{background:#dcdcdc;border:1px solid #ccc;box-sizing:border-box;display:flex;flex-direction:row}.tabulator-toggle.tabulator-toggle-on{background:#1c6cc2}.tabulator-toggle .tabulator-toggle-switch{background:#fff;border:1px solid #ccc;box-sizing:border-box}.tabulator-popup-container{-webkit-overflow-scrolling:touch;background:#fff;border:1px solid #aaa;box-shadow:0 0 5px 0 rgba(0,0,0,.2);box-sizing:border-box;display:inline-block;font-size:14px;overflow-y:auto;position:absolute;z-index:10000}.tabulator-popup{border-radius:3px;padding:5px}.tabulator-tooltip{border-radius:2px;box-shadow:none;font-size:12px;max-width:Min(500px,100%);padding:3px 5px;pointer-events:none}.tabulator-menu .tabulator-menu-item{box-sizing:border-box;padding:5px 10px;position:relative;user-select:none}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator-menu .tabulator-menu-item:not(.tabulator-menu-item-disabled):hover{background:#efefef;cursor:pointer}}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu{padding-right:25px}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu:after{border-color:#aaa;border-style:solid;border-width:1px 1px 0 0;content:"";display:inline-block;height:7px;position:absolute;right:10px;top:calc(5px + .4em);transform:rotate(45deg);vertical-align:top;width:7px}.tabulator-menu .tabulator-menu-separator{border-top:1px solid #aaa}.tabulator-edit-list{-webkit-overflow-scrolling:touch;font-size:14px;max-height:200px;overflow-y:auto}.tabulator-edit-list .tabulator-edit-list-item{color:#333;outline:none;padding:4px}.tabulator-edit-list .tabulator-edit-list-item.active{background:#1d68cd;color:#fff}.tabulator-edit-list .tabulator-edit-list-item.active.focused{outline:1px solid hsla(0,0%,100%,.5)}.tabulator-edit-list .tabulator-edit-list-item.focused{outline:1px solid #1d68cd}@media (hover:hover) and (pointer:fine){.tabulator-edit-list .tabulator-edit-list-item:hover{background:#1d68cd;color:#fff;cursor:pointer}}.tabulator-edit-list .tabulator-edit-list-placeholder{color:#333;padding:4px;text-align:center}.tabulator-edit-list .tabulator-edit-list-group{border-bottom:1px solid #aaa;color:#333;font-weight:700;padding:6px 4px 4px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-2,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-2{padding-left:12px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-3,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-3{padding-left:20px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-4,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-4{padding-left:28px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-5,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-5{padding-left:36px}.tabulator.tabulator-ltr{direction:ltr}.tabulator.tabulator-rtl{direction:rtl;text-align:initial}.tabulator.tabulator-rtl .tabulator-header .tabulator-col{border-left:1px solid #aaa;border-right:initial;text-align:initial}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{margin-left:-1px;margin-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-left:25px;padding-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{left:8px;right:auto}.tabulator.tabulator-rtl .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{background-color:#269b51;border-radius:999px;bottom:-3px;content:"";height:6px;left:-3px;position:absolute;right:auto;width:6px}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell{border-left:1px solid #aaa;border-right:initial}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-branch{border-bottom-left-radius:0;border-bottom-right-radius:1px;border-left:initial;border-right:2px solid #aaa;margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-control{margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-left:2px solid #aaa}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-right:2px solid #aaa}.tabulator.tabulator-rtl .tabulator-row .tabulator-col-resize-handle:last-of-type{margin-left:0;margin-right:-3px;width:3px}.tabulator.tabulator-rtl .tabulator-footer .tabulator-calcs-holder{text-align:initial}.tabulator-print-fullscreen{bottom:0;left:0;position:absolute;right:0;top:0;z-index:10000}body.tabulator-print-fullscreen-hide>:not(.tabulator-print-fullscreen){display:none!important}.tabulator-print-table .tabulator-data-tree-branch{border-bottom:2px solid #aaa;border-bottom-left-radius:1px;border-left:2px solid #aaa;display:inline-block;height:9px;margin-right:5px;margin-top:-9px;vertical-align:middle;width:7px}.tabulator-print-table .tabulator-print-table-group{background:#ccc;border-bottom:1px solid #999;border-right:1px solid #aaa;border-top:1px solid #999;box-sizing:border-box;font-weight:700;min-width:100%;padding:5px 5px 5px 10px}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-print-table-group:hover{background-color:rgba(0,0,0,.1);cursor:pointer}}.tabulator-print-table .tabulator-print-table-group.tabulator-group-visible .tabulator-arrow{border-bottom:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #3fb449;margin-right:10px}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-1 td{padding-left:30px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-2 td{padding-left:50px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-3 td{padding-left:70px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-4 td{padding-left:90px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-5 td{padding-left:110px!important}.tabulator-print-table .tabulator-print-table-group .tabulator-group-toggle{display:inline-block}.tabulator-print-table .tabulator-print-table-group .tabulator-arrow{border-bottom:6px solid transparent;border-left:6px solid #3fb449;border-right:0;border-top:6px solid transparent;display:inline-block;height:0;margin-right:16px;vertical-align:middle;width:0}.tabulator-print-table .tabulator-print-table-group span{color:#d00;margin-left:10px}.tabulator-print-table .tabulator-data-tree-control{align-items:center;background:rgba(0,0,0,.1);border:1px solid #333;border-radius:2px;display:inline-flex;height:11px;justify-content:center;margin-right:5px;overflow:hidden;vertical-align:middle;width:11px}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-data-tree-control:hover{background:rgba(0,0,0,.2);cursor:pointer}}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:transparent;display:inline-block;height:7px;position:relative;width:1px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{background:#333;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:#333;display:inline-block;height:7px;position:relative;width:1px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:#333;content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator{border:none;border-bottom:5px solid #222}.tabulator[tabulator-layout=fitColumns] .tabulator-row .tabulator-cell:last-of-type{border-right:none}.tabulator .tabulator-header{border-bottom:3px solid #3fb449}.tabulator .tabulator-header .tabulator-col{background-color:#222}.tabulator .tabulator-header .tabulator-col .tabulator-col-content{padding:8px}.tabulator .tabulator-header .tabulator-calcs-holder{background:#3c3c3c!important;border-bottom:none;border-top:1px solid #aaa}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row{background:#3c3c3c!important}.tabulator .tabulator-tableholder .tabulator-placeholder span{color:#3fb449}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs{background:#484848!important;color:#fff;font-weight:700}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs-top{border-bottom:none}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs-bottom{border-top:none}.tabulator .tabulator-footer{border-top:3px solid #3fb449;padding:8px 10px 5px}.tabulator .tabulator-footer .tabulator-calcs-holder{background:#3c3c3c!important;border-bottom:1px solid #aaa;border-top:none;margin:-8px -10px 8px}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row{background:#3c3c3c!important;color:#fff!important}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs{margin-bottom:-8px;margin-top:-13px}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab{background-color:#333;border-color:#3fb449;border-width:0 2px 2px;color:#fff;margin:0 2px;padding:8px}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active{background-color:#3fb449;color:#000}.tabulator .tabulator-footer .tabulator-page-counter,.tabulator .tabulator-footer .tabulator-paginator label{color:#fff}.tabulator .tabulator-footer .tabulator-page{background-color:#fff;color:#222;font-family:inherit;font-size:inherit;font-weight:inherit}.tabulator-toggle.tabulator-toggle-on{background:#3fb449}.tabulator-row .tabulator-cell{padding:6px}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar{background:#3fb449}.tabulator-row .tabulator-cell.tabulator-row-header{color:#fff}.tabulator-row.tabulator-group{background:#222;border-bottom:2px solid #3fb449;border-right:1px solid #aaa;border-top:1px solid #000;color:#fff}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-group:hover{background-color:#090909}}.tabulator-row.tabulator-group span{color:#3fb449}.tabulator-print-table{border-collapse:collapse}.tabulator-print-table .tabulator-print-table-group{background:#222;border-bottom:2px solid #3fb449;color:#fff}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-print-table-group:hover{background-color:#090909}}.tabulator-print-table .tabulator-print-table-group span{color:#3fb449}
2 |
--------------------------------------------------------------------------------
/nicegui_tabulator/core/tabulator.js:
--------------------------------------------------------------------------------
1 | import { loadResource } from "../../static/utils/resources.js";
2 | import { convertDynamicProperties } from "../../static/utils/dynamic_properties.js";
3 | import 'tabulator'
4 |
5 | const completedEvents = new Set([
6 | 'tableBuilding',
7 | 'tableBuilt',
8 | ]);
9 |
10 | const eventArgsExtractor = new Map([
11 | ['dataFiltering', filters => ({ filters })],
12 | ['dataFiltered', (filters, rows) => ({ filters, rows: rows.map(row => row.getData()) })],
13 |
14 | ['dataSorting', sorters => ({ sorters })],
15 | ['dataSorted', (sorters, rows) => ({ sorters, rows: rows.map(row => row.getData()) })],
16 |
17 | ['pageLoaded', pageno => ({ pageno })],
18 | ['pageSizeChanged', pagesize => ({ pagesize })],
19 | ])
20 |
21 |
22 | function extractEventArg(eventName, argsObject) {
23 | const result = {};
24 |
25 | if (eventArgsExtractor.has(eventName)) {
26 | return eventArgsExtractor.get(eventName)(...argsObject);
27 | }
28 |
29 |
30 | Object.keys(argsObject).forEach(key => {
31 | const obj = argsObject[key];
32 | if (obj.constructor.name === 'm') {
33 | // row
34 | result['row'] = obj.getData();
35 | } else if (obj.constructor.name === 'i') {
36 | // column
37 | result['column'] = obj.getDefinition();
38 | } else if (obj.constructor.name === 'o') {
39 | // cell
40 | result['cell'] = {
41 | row: obj.getData(),
42 | column: obj.getColumn().getDefinition(),
43 | value: obj.getValue(),
44 | oldValue: obj.getOldValue(),
45 | };
46 | }
47 |
48 |
49 | });
50 |
51 | return result;
52 | }
53 |
54 | function onSocketConnect(fn) {
55 | window.Vue.nextTick(() => {
56 | const socket = window.socket;
57 | socket.on("connect", fn);
58 | });
59 | }
60 |
61 | export default {
62 | template: ``,
63 | props: {
64 | options: Object,
65 | resource_path: String,
66 | },
67 | async mounted() {
68 | await new Promise((resolve) => setTimeout(resolve, 0)); // NOTE: wait for window.path_prefix to be set
69 | const hasNiceGuiTabulatorTheme = document.querySelector('link.nicegui-tabulator-theme') !== null;
70 | if (!hasNiceGuiTabulatorTheme) {
71 | await Promise.all([
72 | loadResource(window.path_prefix + `${this.resource_path}/tabulator.min.css`),
73 | ]);
74 | }
75 |
76 | convertDynamicProperties(this.options, true);
77 | this.table = new Tabulator(this.$el, this.options);
78 |
79 | this.table.on('tableBuilt', () => {
80 | setTimeout(() => {
81 | this.table.redraw();
82 | }, 800);
83 | });
84 |
85 | // here we need to wait for socket connection before emitting events, because some events may not be triggered at page load
86 | onSocketConnect(() => {
87 | this.$emit('connected');
88 | })
89 |
90 | this.$emit('connected');
91 |
92 | },
93 |
94 | methods: {
95 | onEvent(eventName) {
96 | const orgEventName = eventName.replace(/^table:/, '');
97 |
98 | // These events have already been completed at this moment
99 | if (completedEvents.has(orgEventName)) {
100 | this.$emit(eventName);
101 | return;
102 | }
103 |
104 | this.table.on(orgEventName, (...args) => {
105 | const eventArgs = extractEventArg(eventName, args);
106 | this.$emit(eventName, eventArgs);
107 |
108 | if (eventName === 'rowContext' || eventName === 'groupContext') {
109 | args[0].preventDefault();
110 | }
111 | });
112 | },
113 | run_table_method(name, ...args) {
114 | if (name.startsWith(":")) {
115 | name = name.slice(1);
116 | args = args.map((arg) => new Function(`return (${arg})`)());
117 | }
118 | return runMethod(this.table, name, args);
119 | },
120 |
121 | setColumns(columns) {
122 | convertDynamicProperties(columns, true);
123 | this.table.setColumns(columns);
124 | },
125 |
126 | updateColumnDefinition(field, definition) {
127 | convertDynamicProperties(definition, true);
128 | this.table.updateColumnDefinition(field, definition);
129 | },
130 |
131 | updateCellSlot(field, rowNumber, rowIndex) {
132 | this.$emit('updateCellSlot', { field, rowNumber, rowIndex })
133 | },
134 |
135 | resetRowFormat(position) {
136 | this.table.getRowFromPosition(position).normalizeHeight();
137 | }
138 | },
139 | };
--------------------------------------------------------------------------------
/nicegui_tabulator/core/tabulator.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | from typing import Callable, Dict, List, Optional, Tuple, Union
3 | from nicegui.element import Element
4 | from nicegui.awaitable_response import AwaitableResponse
5 | from warnings import warn
6 | from .utils import DeferredTask
7 | from nicegui.elements.teleport import Teleport as teleport
8 | from .types import CellSlotProps, T_Row_Range_Lookup
9 | from . import utils
10 |
11 | try:
12 | import pandas as pd
13 | except ImportError:
14 | pass
15 |
16 |
17 | class Tabulator(
18 | Element, component="tabulator.js", dependencies=["libs/tabulator.min.js"]
19 | ):
20 | def __init__(
21 | self,
22 | options: Dict,
23 | row_key: Optional[str] = "id",
24 | ) -> None:
25 | """Create a new tabulator table.
26 |
27 | Args:
28 | options (Dict): The options for the tabulator table.
29 | row_key (str, optional): The field to be used as the unique index for each row. Defaults to "id".
30 | """
31 | super().__init__()
32 | self.__deferred_task = DeferredTask()
33 |
34 | if row_key:
35 | options.update(index=row_key)
36 |
37 | self._props["options"] = options
38 | self.add_resource(Path(__file__).parent / "libs")
39 |
40 | self._cell_slot_map: Dict[str, Callable] = {}
41 | self._teleport_slots_cache: Dict[Tuple[str, int], teleport] = {}
42 |
43 | def on_update_cell_slot(e):
44 | field = e.args["field"]
45 | row_number = e.args["rowNumber"]
46 | row_index = e.args["rowIndex"]
47 | key = (field, row_index)
48 |
49 | if field not in self._cell_slot_map:
50 | return
51 |
52 | if key in self._teleport_slots_cache:
53 | # TODO:how reuse the teleport instead of creating a new one?
54 | tp = self._teleport_slots_cache[key]
55 | tp.delete()
56 |
57 | fn = self._cell_slot_map[field]
58 | tp = fn(row_number, row_index)
59 | if tp:
60 | self._teleport_slots_cache[key] = tp
61 |
62 | self.run_method("resetRowFormat", row_number)
63 |
64 | self.on("updateCellSlot", on_update_cell_slot)
65 |
66 | def on_connected():
67 | self.__deferred_task.flush()
68 | self.__deferred_task.component_connected = True
69 |
70 | self.on("connected", on_connected)
71 |
72 | @property
73 | def index_field(self):
74 | """Get the index field for the tabulator table.By default Tabulator will look for this value in the id field for the data."""
75 | return self._props["options"].get("index", "id")
76 |
77 | @property
78 | def data(self):
79 | """Get or set the data for the tabulator table."""
80 | if "data" not in self._props["options"]:
81 | self._props["options"]["data"] = []
82 | return self._props["options"]["data"]
83 |
84 | def delete(self) -> None:
85 | for tp in self._teleport_slots_cache.values():
86 | tp.delete()
87 | return super().delete()
88 |
89 | def on_event(
90 | self,
91 | event: str,
92 | callback: Callable[..., None],
93 | ):
94 | """
95 | Register an event listener for the tabulator table.
96 |
97 | Args:
98 | event (str): The name of the event to listen for.
99 | callback (Callable[..., None]): The function to call when the event is triggered.
100 |
101 | """
102 |
103 | if event.endswith("tableBuilding"):
104 | warn("The 'tableBuilding' event cannot be triggered.")
105 | return self
106 |
107 | if not event.startswith("table:"):
108 | event = f"table:{event}"
109 |
110 | @self.__deferred_task.register
111 | def _():
112 | self.run_method("onEvent", event)
113 |
114 | self.on(event, callback)
115 |
116 | return self
117 |
118 | def run_table_method(
119 | self, name: str, *args, timeout: float = 1, check_interval: float = 0.01
120 | ) -> AwaitableResponse:
121 | """
122 | Run a method on the tabulator table.
123 |
124 | Args:
125 | name (str): The name of the method to run.
126 | *args: The arguments to pass to the method.
127 | timeout (float, optional): The maximum time to wait for the method to complete. Defaults to 1.
128 | check_interval (float, optional): The interval at which to check if the method has completed. Defaults to 0.01.
129 |
130 | """
131 | return self.run_method("run_table_method", name, *args, timeout=timeout)
132 |
133 | def set_columns(self, columns: List[Dict]) -> None:
134 | """
135 | To replace the current column definitions for all columns in a table.
136 |
137 | @see https://tabulator.info/docs/6.2/columns#replace
138 |
139 | Args:
140 | columns (List[Dict]): The list of column definition objects for the table.
141 |
142 | ## Example Usage
143 |
144 | .. code-block:: python
145 | table = Tabulator({...})
146 |
147 | new_columns = [
148 | {'title':"Name", 'field':"name"},
149 | {'title':"Age", 'field':"age"},
150 | ]
151 |
152 | table.set_columns(new_columns)
153 |
154 | """
155 |
156 | @self.__deferred_task.register
157 | def _():
158 | self.run_method("setColumns", columns)
159 |
160 | def update_column_definition(self, field: str, definition: Dict) -> None:
161 | """
162 | Update an existing column definition.
163 |
164 | @see https://tabulator.info/docs/6.2/columns#update
165 |
166 | Args:
167 | field (str): The field name of the column you want to update.
168 | definition (Dict): The new column definition object for the column.
169 |
170 | ## Example Usage
171 |
172 | .. code-block:: python
173 | table = Tabulator({...})
174 | table.update_column_definition("name", {'title':"Updated Title"})
175 |
176 | """
177 |
178 | @self.__deferred_task.register
179 | def _():
180 | self.run_method("updateColumnDefinition", field, definition)
181 |
182 | def add_column(
183 | self,
184 | definition: Dict,
185 | before: Optional[bool] = None,
186 | position: Optional[str] = None,
187 | ) -> None:
188 | """
189 | Add a column to the table.
190 |
191 | @see https://tabulator.info/docs/6.2/columns#add
192 |
193 |
194 | Args:
195 | definition (Dict): The column definition object for the column you want to add.
196 | before (Optional[bool], optional): Determines how to position the new column. A value of true will insert the column to the left of existing columns, a value of false will insert it to the right. If a Position argument is supplied then this will determine whether the new colum is inserted before or after this column.
197 | position (Optional[str], optional): The field to insert the new column next to, this can be any of the standard column component look up options.
198 |
199 | ## Example Usage
200 |
201 | .. code-block:: python
202 | table = Tabulator({...})
203 | table.add_column({'title':"Age", 'field':"age"}, True, "name")
204 |
205 | """
206 |
207 | @self.__deferred_task.register
208 | def _():
209 | self.run_table_method("addColumn", definition, before, position)
210 |
211 | @classmethod
212 | def from_pandas(
213 | cls,
214 | df: "pd.DataFrame",
215 | *,
216 | index: Optional[str] = None,
217 | auto_index=False,
218 | options: Optional[Dict] = None,
219 | column_definition: Optional[Callable[[str], Dict]] = None,
220 | ):
221 | """Create a table from a Pandas DataFrame.
222 |
223 | Note:
224 | If the DataFrame contains non-serializable columns of type `datetime64[ns]`, `timedelta64[ns]`, `complex128` or `period[M]`,
225 | they will be converted to strings.
226 |
227 | Args:
228 | df (pd.DataFrame): The DataFrame to create the table from.
229 | index (str, optional): The field to be used as the unique index for each row.
230 | auto_index (bool, optional): If `True` and the `index` parameter is `None`, a sequence number column will be automatically generated as the index.
231 | options (Dict, optional): The options for the tabulator table.
232 | column_definition (Callable[[str], Dict], optional): A function that takes a column name and returns a column definition object for that column.
233 | """
234 |
235 | def is_special_dtype(dtype):
236 | return (
237 | pd.api.types.is_datetime64_any_dtype(dtype)
238 | or pd.api.types.is_timedelta64_dtype(dtype)
239 | or pd.api.types.is_complex_dtype(dtype)
240 | or isinstance(dtype, pd.PeriodDtype)
241 | )
242 |
243 | special_cols = df.columns[df.dtypes.apply(is_special_dtype)]
244 | if not special_cols.empty:
245 | df = df.copy()
246 | df[special_cols] = df[special_cols].astype(str)
247 |
248 | if isinstance(df.columns, pd.MultiIndex):
249 | raise ValueError(
250 | "MultiIndex columns are not supported. "
251 | "You can convert them to strings using something like "
252 | '`df.columns = ["_".join(col) for col in df.columns.values]`.'
253 | )
254 |
255 | columns: List[Dict] = [
256 | {"title": col, "field": col}
257 | if column_definition is None
258 | else {"field": col, **column_definition(col)}
259 | for col in df.columns
260 | ]
261 |
262 | options = options or {}
263 |
264 | if index is not None:
265 | options["index"] = index
266 | elif auto_index:
267 | col_name = utils.generate_dataframe_unique_id_column_name()
268 | df = df.assign(**{col_name: range(len(df))})
269 | columns.insert(0, {"title": col_name, "field": col_name, "visible": False})
270 | options["index"] = col_name
271 |
272 | options.update({"data": df.to_dict(orient="records"), "columns": columns})
273 |
274 | return cls(options, row_key=None)
275 |
276 | def add_cell_slot(
277 | self,
278 | field: str,
279 | ):
280 | """
281 | Add a cell slot to the table.
282 |
283 | @see https://github.com/CrystalWindSnake/nicegui-tabulator?tab=readme-ov-file#cell-slots
284 |
285 |
286 | Args:
287 | field (str): The field name of the column you want to add a cell slot to.
288 |
289 |
290 | ## Example Usage
291 |
292 | .. code-block:: python
293 | from nicegui import ui
294 | from nicegui_tabulator import tabulator,CellSlotProps
295 |
296 | table = tabulator({...})
297 |
298 | @table.add_cell_slot("name")
299 | def name_cell(props: CellSlotProps):
300 | ui.input(value=props.value, placeholder="Enter name")
301 |
302 | """
303 | id = f"c{self.id}"
304 |
305 | def wrapper(build_fn: Callable[[CellSlotProps], None]):
306 | def fn(row_number: int, row_index: int):
307 | options = self._props["options"]
308 | data = options.get("data", [])
309 | if not data:
310 | return
311 | row = data[row_index]
312 |
313 | class_name = f"ng-cell-slot-{field}-{row_index}"
314 | with teleport(f"#{id} .{class_name}") as tp:
315 | cell_slot = CellSlotProps(
316 | field=field,
317 | value=row[field],
318 | row=row,
319 | row_number=row_number,
320 | row_index=row_index,
321 | table=self,
322 | )
323 | build_fn(cell_slot)
324 |
325 | return tp
326 |
327 | self.update_column_definition(
328 | field,
329 | {
330 | ":formatter": rf"""
331 | function(cell, formatterParams, onRendered){{
332 |
333 | const row = cell.getRow();
334 | const table = row.getTable();
335 | const field = cell.getField();
336 |
337 | onRendered(function(){{
338 | const rowNumber = row.getPosition();
339 | const rowIndexValue = row.getIndex();
340 | const indexField = table.options.index;
341 | const rowIndex = table.options.data.findIndex(r => r[indexField] === rowIndexValue);
342 | const target = cell.getElement();
343 | target.innerHTML = ``
344 | const tableObject = getElement({self.id});
345 | runMethod(tableObject, 'updateCellSlot',[field,rowNumber,rowIndex]);
346 | }});
347 | }}
348 | """
349 | },
350 | )
351 | self._cell_slot_map[field] = fn
352 |
353 | return wrapper
354 |
355 | def set_data(self, data: List[Dict]):
356 | """set the data of the table.
357 |
358 | @see https://tabulator.info/docs/6.2/data#array
359 |
360 | Args:
361 | data (List[Dict]): The data to set for the table.
362 |
363 |
364 | """
365 | self._set_data_on_server(data)
366 | self.run_table_method("setData", data)
367 | return self
368 |
369 | def replace_data(self, data: List[Dict]):
370 | """replace the data of the table.
371 |
372 | @see https://tabulator.info/docs/6.2/update#alter-replace
373 |
374 | Args:
375 | data (List[Dict]): The data to replace the current data with.
376 |
377 | """
378 | self.set_data(data)
379 | return self
380 |
381 | def update_data(self, data: List[Dict]):
382 | """update the data of the table.
383 |
384 | @see https://tabulator.info/docs/6.2/update#alter-update
385 |
386 | Args:
387 | data (List[Dict]): The data to update the current data with.
388 |
389 | """
390 | self._update_data_on_server(data)
391 | self.run_table_method("updateData", data)
392 | return self
393 |
394 | def add_data(
395 | self,
396 | data: List[Dict],
397 | at_top: Optional[bool] = None,
398 | index: Optional[Union[int, str]] = None,
399 | ):
400 | """add data to the table.
401 |
402 | @see https://tabulator.info/docs/6.2/update#alter-add
403 |
404 | Args:
405 | data (List[Dict]): The data to add to the current data.
406 | at_top (Optional[bool], optional): determines whether the data is added to the top or bottom of the table. A value of true will add the data to the top of the table, a value of false will add the data to the bottom of the table. If the parameter is not set the data will be placed according to the addRowPos global option.
407 | index (Optional[Union[int, str]], optional): table row index. position the new rows next to the specified row (above or below based on the value of the second argument). This argument will take any of the standard row component look up options
408 |
409 | """
410 | self._add_data_on_server(data, at_top, index)
411 | self.run_table_method("addData", data, at_top, index)
412 | return self
413 |
414 | def update_or_add_data(self, data: List[Dict]):
415 | """update or add data to the table.
416 | If the data you are passing to the table contains a mix of existing rows to be updated and new rows to be added then you can call the updateOrAddData function. This will check each row object provided and update the existing row if available, or else create a new row with the data.
417 |
418 | @see https://tabulator.info/docs/6.2/update#alter-add
419 |
420 | Args:
421 | data (List[Dict]): The data to update or add to the current data.
422 |
423 | """
424 | self._update_or_add_data_on_server(data)
425 | self.run_table_method("updateOrAddData", data)
426 | return self
427 |
428 | def clear_data(self):
429 | """clear the data of the table.
430 |
431 | @see https://tabulator.info/docs/6.2/update#alter-empty
432 |
433 | """
434 | self._set_data_on_server([])
435 | self.run_table_method("clearData")
436 | return self
437 |
438 | def sync_data_to_client(self):
439 | """sync server data to the client.
440 |
441 | @see https://github.com/CrystalWindSnake/nicegui-tabulator/tree/main?tab=readme-ov-file##cell-slot
442 | """
443 | self.set_data(self._props["options"]["data"])
444 | return self
445 |
446 | def _add_data_on_server(
447 | self,
448 | data: List[Dict],
449 | at_top: Optional[bool] = None,
450 | index: Optional[Union[int, str]] = None,
451 | ):
452 | at_top = (
453 | at_top
454 | if at_top is not None
455 | else self._props["options"].get("addRowPos", "bottom") == "top"
456 | )
457 |
458 | if index is None:
459 | row_index = 0 if at_top else len(self.data)
460 | else:
461 | index_field = self.index_field
462 | indices = [
463 | i for i, row in enumerate(self.data) if row[index_field] == index
464 | ]
465 | if not indices:
466 | row_index = 0 if at_top else len(self.data)
467 | else:
468 | row_index = indices[0] + (0 if at_top else 1)
469 |
470 | self._set_data_on_server(self.data[:row_index] + data + self.data[row_index:])
471 |
472 | def _set_data_on_server(self, data: List[Dict]):
473 | if "data" not in self._props["options"]:
474 | self._props["options"]["data"] = None
475 | self._props["options"]["data"] = data[:]
476 |
477 | def _update_data_on_server(self, data: List[Dict]):
478 | index_field = self.index_field
479 | update_dict = {record[index_field]: record for record in data}
480 |
481 | for row in self.data:
482 | update_id = row.get(index_field, None)
483 | if not update_id:
484 | continue
485 |
486 | update_record = update_dict.get(update_id, None)
487 |
488 | if update_record:
489 | row.update(update_record)
490 |
491 | def _update_or_add_data_on_server(self, data: List[Dict]):
492 | index_field = self.index_field
493 | update_dict = {item[index_field]: item for item in data}
494 |
495 | for item in self.data:
496 | if item[index_field] in update_dict:
497 | item.update(update_dict.pop(item[index_field]))
498 |
499 | self._set_data_on_server([*self.data, *update_dict.values()])
500 |
501 | def print(
502 | self,
503 | *,
504 | row_range_lookup: Optional[T_Row_Range_Lookup] = None,
505 | style: Optional[bool] = True,
506 | config: Optional[Dict] = None,
507 | ):
508 | """A full page printing of the contents of the table without any other elements from the page.
509 |
510 | Args:
511 | row_range_lookup (Optional[T_Row_Range_Lookup], optional): Determins which rows are shown in the printed table, if no value is set it will use the value set in the printRowRange option.
512 | style (Optional[bool], optional): Determines if the output of the function should be styled to match the table (true) or be a blank html table (false), if you leave this argument out it will take the value of the printStyled option. Defaults to True.
513 | config (Optional[Dict], optional): An object that can be used to override the object set on the printConfig option. Defaults to None.
514 | """
515 | self.sync_data_to_client()
516 | self.run_table_method("print", row_range_lookup, style, config)
517 |
518 | async def get_selected_data(self) -> List[Dict]:
519 | """Get the selected data from the table."""
520 | return await self.run_table_method("getSelectedData")
521 |
--------------------------------------------------------------------------------
/nicegui_tabulator/core/themes.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 | from pathlib import Path
3 | from typing import Literal, Optional
4 | from nicegui import ui, app
5 |
6 | _ASSETS_DIR = Path(__file__).parent / "libs"
7 |
8 | _T_THEME_NAME = Literal[
9 | "default",
10 | "bootstrap3",
11 | "bootstrap4",
12 | "bootstrap5",
13 | "bulma",
14 | "materialize",
15 | "midnight",
16 | "modern",
17 | "semanticui",
18 | "simple",
19 | "site",
20 | "site_dark",
21 | ]
22 |
23 |
24 | def use_theme(theme_name: _T_THEME_NAME, shared: Optional[bool] = None) -> None:
25 | """Use a tabulator theme.
26 |
27 | Args:
28 | theme_name (_T_THEME_NAME): name of the theme to use.
29 | shared (Optional[bool], optional): Whether to use the theme for all clients or only the current client.
30 | `None`(default): use the theme for all clients if the current client is an auto-index client, otherwise use it only for the current client.
31 | `True`: use the theme for all clients.
32 | `False`: use the theme only for the current client.
33 |
34 | ## Example
35 |
36 | ```python
37 | from nicegui_tabulator import tabulator, use_theme
38 |
39 | # use the theme for all clients
40 | use_theme('bootstrap4')
41 |
42 | # use the theme only for the current client
43 | use_theme('bootstrap4', shared=False)
44 |
45 | @ui.page('/')
46 | def my_page():
47 | # use the theme only for this page
48 | use_theme('bootstrap4')
49 | ```
50 | """
51 | if shared is None:
52 | shared = ui.context.client.is_auto_index_client
53 |
54 | css_name = (
55 | "tabulator.min.css"
56 | if theme_name == "default"
57 | else f"tabulator_{theme_name}.min.css"
58 | )
59 | css_path = _ASSETS_DIR / css_name
60 |
61 | if not css_path.exists():
62 | raise ValueError(f"theme '{css_path.resolve()}' not found")
63 |
64 | app.add_static_file(local_file=css_path, url_path="/" + css_name)
65 |
66 | if ui.context.client.has_socket_connection:
67 | ui.run_javascript(
68 | """
69 | const linkElements = document.querySelectorAll('link.nicegui-tabulator-theme');
70 | linkElements.forEach(linkElement => {
71 | linkElement.parentNode.removeChild(linkElement);
72 | });
73 | """
74 | )
75 |
76 | ui.add_head_html(
77 | rf'',
78 | shared=shared,
79 | )
80 |
--------------------------------------------------------------------------------
/nicegui_tabulator/core/types.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 | from dataclasses import dataclass, field as dc_field
3 | from typing import Any, Dict, Literal
4 |
5 | from typing import TYPE_CHECKING
6 |
7 | if TYPE_CHECKING:
8 | from .tabulator import Tabulator
9 |
10 |
11 | @dataclass
12 | class CellSlotProps:
13 | field: str
14 | """The name of the field in the row data."""
15 | value: Any
16 | """The value of the field in the row data."""
17 | row: Dict
18 | """The row data."""
19 | row_number: int
20 | """The position(starting from 1) of the row in the table data."""
21 | row_index: int
22 | """The index of the row in the table data."""
23 | table: Tabulator = dc_field(init=True, repr=False)
24 | """The parent Tabulator instance."""
25 |
26 | def update_value(self, value):
27 | """Updates the value of the field in the row data only on the server side."""
28 | index_field = self.table.index_field
29 | data = [{index_field: self.row[index_field], self.field: value}]
30 | self.table._update_data_on_server(data)
31 |
32 | def update_to_client(self):
33 | """Updates the value of the field in the row data on the client side."""
34 |
35 | index_field = self.table.index_field
36 | data = [{index_field: self.row[index_field], self.field: self.row[self.field]}]
37 | self.table.run_table_method(
38 | "updateData",
39 | data,
40 | )
41 |
42 |
43 | T_Row_Range_Lookup = Literal["visible", "active", "selected", "range", "all"]
44 | """Functions that export rows from the table, like print and clipboard require a range of rows to be specified to be included in the export.
45 |
46 | - "visible": The rows that are currently visible in the table viewport.
47 | - "active": The row that is currently in the table (rows that pass current filters etc).
48 | - "selected": The rows that are currently selected rows by the selection module (this includes not currently active rows).
49 | - "range": Any currently selected ranges from the range selection module.
50 | - "all": All rows in the table regardless of filters.
51 | """
52 |
--------------------------------------------------------------------------------
/nicegui_tabulator/core/utils.py:
--------------------------------------------------------------------------------
1 | from typing import Callable
2 | from nicegui import ui, Client as ng_client
3 | import uuid
4 |
5 |
6 | class DeferredTask:
7 | def __init__(self):
8 | self._tasks = []
9 | self.component_connected = False
10 |
11 | async def on_client_connect(
12 | client: ng_client,
13 | ):
14 | await client.connected()
15 |
16 | self.flush()
17 |
18 | # Avoid events becoming ineffective due to page refresh when sharing the client.
19 | if not client.shared:
20 | client.connect_handlers.remove(on_client_connect) # type: ignore
21 |
22 | ui.context.client.on_connect(on_client_connect)
23 |
24 | def register(self, task: Callable[..., None]):
25 | if ui.context.client.has_socket_connection and self.component_connected:
26 | task()
27 | else:
28 | self._tasks.append(task)
29 |
30 | def flush(self):
31 | for task in self._tasks:
32 | task()
33 |
34 | self._tasks.clear()
35 |
36 |
37 | def generate_dataframe_unique_id_column_name():
38 | return f"__{uuid.uuid4().hex}"
39 |
--------------------------------------------------------------------------------
/nicegui_tabulator/version.py:
--------------------------------------------------------------------------------
1 | import importlib.metadata
2 |
3 | __version__: str = importlib.metadata.version("nicegui-tabulator")
4 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.poetry]
2 | name = "nicegui-tabulator"
3 | version = "0.2.2"
4 | description = "This is a Python package that provides a simple way to create tables using the Tabulator library. It is built on top of the NiceGUI library."
5 | authors = ["CrystalWindSnake <568166495@qq.com>"]
6 | readme = "README.md"
7 |
8 | [tool.poetry.dependencies]
9 | python = "^3.8"
10 | nicegui = "^2.0.0"
11 |
12 |
13 | [tool.poetry.group.dev.dependencies]
14 | pytest = "^8.2.0"
15 | playwright = "^1.43.0"
16 | pytest-playwright = "^0.5.0"
17 | pandas = [
18 | {version = "^1.0.0", python = "~3.8"},
19 | {version = "^2.0.0", python = ">=3.9,<3.13"}
20 | ]
21 | numpy = [
22 | {version = "^1.24.0", python = "~3.8"},
23 | {version = "^1.26.0", python = ">=3.9,<3.13"}
24 | ]
25 |
26 |
27 | [build-system]
28 | requires = ["poetry-core"]
29 | build-backend = "poetry.core.masonry.api"
30 |
--------------------------------------------------------------------------------
/scripts/css_processor.py:
--------------------------------------------------------------------------------
1 | import os
2 | from pathlib import Path
3 |
4 |
5 | def remove_sourcemap_comment_from_css(directory_path: Path):
6 | for css_file in directory_path.glob("*.css"):
7 | with open(css_file, "r", encoding="utf-8") as file:
8 | lines = file.readlines()
9 |
10 | if lines and lines[-1].strip().startswith("/*# sourceMappingURL="):
11 | lines.pop()
12 |
13 | with open(css_file, "w", encoding="utf-8") as file:
14 | file.writelines(lines)
15 |
16 | print(f"Removed sourceMappingURL from {css_file}")
17 |
18 |
19 | if __name__ == "__main__":
20 | directory_path = Path(__file__).parent.parent.joinpath(
21 | "nicegui_tabulator/core/libs"
22 | )
23 | remove_sourcemap_comment_from_css(directory_path)
24 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CrystalWindSnake/nicegui-tabulator/44812946fe2ca382e025a4cd0c3b53d79ebf181a/tests/__init__.py
--------------------------------------------------------------------------------
/tests/conftest.py:
--------------------------------------------------------------------------------
1 | import importlib
2 | import pytest
3 | from playwright.sync_api import Playwright
4 | from .screen import ServerManager
5 | from nicegui.page import page as ui_page
6 | from nicegui import Client, binding, app
7 | from nicegui.elements import plotly, pyplot
8 | import os
9 |
10 | HEADLESS = "GITHUB_ACTION" in os.environ
11 |
12 |
13 | @pytest.fixture(autouse=True)
14 | def reset_globals(request: pytest.FixtureRequest):
15 | if "noautofixt" in request.keywords:
16 | return
17 |
18 | for path in {"/"}.union(Client.page_routes.values()):
19 | app.remove_route(path)
20 | app.openapi_schema = None
21 | app.middleware_stack = None
22 | app.user_middleware.clear()
23 | # NOTE favicon routes must be removed separately because they are not "pages"
24 | for route in app.routes:
25 | if route.path.endswith("/favicon.ico"): # type: ignore
26 | app.routes.remove(route)
27 | # importlib.reload(globals)
28 | # # repopulate globals.optional_features
29 | importlib.reload(plotly)
30 | importlib.reload(pyplot)
31 | app.storage.clear()
32 | Client.auto_index_client = Client(ui_page("/"), request=None).__enter__() # pylint: disable=unnecessary-dunder-call
33 | app.get("/")(Client.auto_index_client.build_response)
34 | binding.reset()
35 |
36 |
37 | @pytest.fixture(scope="session")
38 | def server(playwright: Playwright, request: pytest.FixtureRequest):
39 | if "noautofixt" in request.keywords:
40 | return
41 | browser = playwright.chromium.launch(headless=HEADLESS)
42 | server = ServerManager(browser)
43 |
44 | yield server
45 |
46 | server.stop_server()
47 |
48 |
49 | @pytest.fixture(scope="module")
50 | def browser(server: ServerManager, request: pytest.FixtureRequest):
51 | if "noautofixt" in request.keywords:
52 | return
53 | browser = server.new_page()
54 |
55 | yield browser
56 |
57 | browser.close()
58 |
59 |
60 | URL_COUNTER = 0
61 |
62 |
63 | @pytest.fixture
64 | def page_path(request: pytest.FixtureRequest):
65 | if "noautofixt" in request.keywords:
66 | return
67 | global URL_COUNTER
68 | URL_COUNTER += 1
69 |
70 | return f"/{URL_COUNTER}"
71 |
--------------------------------------------------------------------------------
/tests/pytest.ini:
--------------------------------------------------------------------------------
1 | [pytest]
2 | markers =
3 | noautofixt: not use auto fixt.
4 |
5 | log_cli=true
6 | log_cli_level = INFO
--------------------------------------------------------------------------------
/tests/screen.py:
--------------------------------------------------------------------------------
1 | import threading
2 | from playwright.sync_api import Browser
3 | from nicegui import ui, app
4 | from nicegui.server import Server
5 |
6 | PORT = 3392
7 |
8 |
9 | class ServerManager:
10 | def __init__(self, browser: Browser) -> None:
11 | self.server_thread = None
12 | self.browser = browser
13 |
14 | self._context = browser.new_context()
15 | self._context.set_default_timeout(10000)
16 | self.ui_run_kwargs = {"port": PORT, "show": False, "reload": False}
17 | self.connected = threading.Event()
18 |
19 | app.on_startup(self.connected.set)
20 |
21 | def start_server(self) -> None:
22 | """Start the webserver in a separate thread. This is the equivalent of `ui.run()` in a normal script."""
23 | self.server_thread = threading.Thread(target=ui.run, kwargs=self.ui_run_kwargs)
24 | self.server_thread.start()
25 |
26 | def stop_server(self) -> None:
27 | """Stop the webserver."""
28 | self.browser.close()
29 | Server.instance.should_exit = True
30 |
31 | if self.server_thread:
32 | self.server_thread.join()
33 |
34 | def new_page(self):
35 | if self.server_thread is None:
36 | self.start_server()
37 |
38 | self.connected.clear()
39 |
40 | return BrowserManager(self, self.connected)
41 |
42 |
43 | class BrowserManager:
44 | def __init__(self, server: ServerManager, connect_event: threading.Event) -> None:
45 | self.__server = server
46 | self._page = self.__server._context.new_page()
47 | self.connected = connect_event
48 |
49 | def open(self, path: str):
50 | # self._page.wait_for_selector("body", timeout=10000)
51 |
52 | # wait for server to be ready
53 | is_connected = self.connected.wait(5)
54 | if not is_connected:
55 | raise TimeoutError("Failed to connect to server")
56 |
57 | self._page.goto(
58 | f"http://localhost:{PORT}{path}",
59 | timeout=5000,
60 | wait_until="domcontentloaded",
61 | )
62 |
63 | self._page.wait_for_timeout(600)
64 | return self._page
65 |
66 | def close(self):
67 | self._page.close()
68 |
69 | @property
70 | def pw_page(self):
71 | return self._page
72 |
--------------------------------------------------------------------------------