instaui 0.1.5__py3-none-any.whl → 0.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- instaui/arco/__init__.py +191 -0
- instaui/arco/_settings.py +25 -0
- instaui/arco/_use_tools/locale.py +50 -0
- instaui/arco/component_types.py +1019 -0
- instaui/arco/components/_utils.py +22 -0
- instaui/arco/components/affix.py +29 -0
- instaui/arco/components/alert.py +42 -0
- instaui/arco/components/anchor.py +42 -0
- instaui/arco/components/auto_complete.py +96 -0
- instaui/arco/components/avatar.py +55 -0
- instaui/arco/components/back_top.py +14 -0
- instaui/arco/components/badge.py +14 -0
- instaui/arco/components/breadcrumb.py +14 -0
- instaui/arco/components/button.py +43 -0
- instaui/arco/components/calendar.py +47 -0
- instaui/arco/components/card.py +14 -0
- instaui/arco/components/carousel.py +33 -0
- instaui/arco/components/cascader.py +111 -0
- instaui/arco/components/checkbox.py +32 -0
- instaui/arco/components/collapse.py +31 -0
- instaui/arco/components/color_picker.py +45 -0
- instaui/arco/components/comment.py +14 -0
- instaui/arco/components/config_provider.py +13 -0
- instaui/arco/components/date_picker.py +111 -0
- instaui/arco/components/descriptions.py +14 -0
- instaui/arco/components/divider.py +13 -0
- instaui/arco/components/drawer.py +98 -0
- instaui/arco/components/dropdown.py +45 -0
- instaui/arco/components/empty.py +14 -0
- instaui/arco/components/form.py +55 -0
- instaui/arco/components/icon.py +17 -0
- instaui/arco/components/image.py +33 -0
- instaui/arco/components/input.py +102 -0
- instaui/arco/components/input_number.py +97 -0
- instaui/arco/components/input_password.py +38 -0
- instaui/arco/components/input_search.py +37 -0
- instaui/arco/components/input_tag.py +110 -0
- instaui/arco/components/layout.py +13 -0
- instaui/arco/components/layout_content.py +6 -0
- instaui/arco/components/layout_footer.py +6 -0
- instaui/arco/components/layout_header.py +6 -0
- instaui/arco/components/layout_sider.py +53 -0
- instaui/arco/components/link.py +36 -0
- instaui/arco/components/list.py +68 -0
- instaui/arco/components/mention.py +97 -0
- instaui/arco/components/menu.py +88 -0
- instaui/arco/components/modal.py +97 -0
- instaui/arco/components/overflow_list.py +29 -0
- instaui/arco/components/page_header.py +29 -0
- instaui/arco/components/pagination.py +45 -0
- instaui/arco/components/pop_confirm.py +58 -0
- instaui/arco/components/popover.py +32 -0
- instaui/arco/components/progress.py +14 -0
- instaui/arco/components/radio.py +40 -0
- instaui/arco/components/radio_group.py +42 -0
- instaui/arco/components/rate.py +45 -0
- instaui/arco/components/resize_box.py +62 -0
- instaui/arco/components/result.py +14 -0
- instaui/arco/components/select.py +179 -0
- instaui/arco/components/skeleton.py +14 -0
- instaui/arco/components/slider.py +38 -0
- instaui/arco/components/space.py +14 -0
- instaui/arco/components/spin.py +14 -0
- instaui/arco/components/split.py +76 -0
- instaui/arco/components/statistic.py +14 -0
- instaui/arco/components/steps.py +32 -0
- instaui/arco/components/switch.py +57 -0
- instaui/arco/components/tab_pane.py +12 -0
- instaui/arco/components/table.py +276 -0
- instaui/arco/components/tabs.py +101 -0
- instaui/arco/components/tag.py +42 -0
- instaui/arco/components/textarea.py +84 -0
- instaui/arco/components/time_picker.py +76 -0
- instaui/arco/components/timeline.py +14 -0
- instaui/arco/components/tooltip.py +29 -0
- instaui/arco/components/transfer.py +58 -0
- instaui/arco/components/tree.py +120 -0
- instaui/arco/components/tree_select.py +86 -0
- instaui/arco/components/trigger.py +58 -0
- instaui/arco/components/typography.py +142 -0
- instaui/arco/components/upload.py +71 -0
- instaui/arco/components/verification_code.py +58 -0
- instaui/arco/components/watermark.py +14 -0
- instaui/arco/locales/__init__.py +4 -0
- instaui/arco/locales/_index.py +31 -0
- instaui/arco/locales/en_us.py +227 -0
- instaui/arco/locales/zh_cn.py +224 -0
- instaui/arco/setup.py +36 -0
- instaui/arco/static/instaui-arco.css +1 -0
- instaui/arco/static/instaui-arco.js +55771 -0
- instaui/arco/types.py +24 -0
- instaui/components/column.py +10 -2
- instaui/components/element.py +0 -2
- instaui/components/grid.py +81 -0
- instaui/components/markdown/static/github-markdown.css +1 -1
- instaui/components/row.py +8 -7
- instaui/components/shiki_code/static/shiki-style.css +179 -175
- instaui/experimental/link_sql/__init__.py +3 -0
- instaui/experimental/link_sql/_base.py +23 -0
- instaui/experimental/link_sql/_duckdb.py +221 -0
- instaui/experimental/link_sql/_types.py +15 -0
- instaui/experimental/link_sql/data_source.js +50 -0
- instaui/fastapi_server/debug_mode_router.py +1 -1
- instaui/html_tools.py +2 -3
- instaui/runtime/scope.py +28 -7
- instaui/static/insta-ui.css +1 -1
- instaui/static/insta-ui.esm-browser.prod.js +3663 -3719
- instaui/static/insta-ui.js.map +1 -1
- instaui/static/templates/debug/sse.html +1 -1
- instaui/tailwind/_index.py +2 -2
- instaui/ui_functions/ui_page.py +1 -1
- instaui/vars/data.py +7 -7
- instaui/vars/element_ref.py +2 -4
- instaui/vars/js_computed.py +6 -8
- instaui/vars/ref.py +6 -6
- instaui/vars/vue_computed.py +6 -7
- instaui/vars/web_computed.py +2 -3
- instaui/watch/vue_watch.py +23 -7
- instaui/zero/scope.py +3 -20
- {instaui-0.1.5.dist-info → instaui-0.1.6.dist-info}/METADATA +5 -4
- {instaui-0.1.5.dist-info → instaui-0.1.6.dist-info}/RECORD +123 -36
- instaui/daisyui/__init__.py +0 -26
- instaui/daisyui/_index.py +0 -20
- instaui/daisyui/button.py +0 -38
- instaui/daisyui/checkbox.py +0 -17
- instaui/daisyui/static/daisyui.css +0 -1
- instaui/daisyui/static/themes.css +0 -1
- instaui/daisyui/table.py +0 -35
- instaui/ui/__build_init.py +0 -73
- instaui/vars/_utils.py +0 -12
- {instaui-0.1.5.dist-info → instaui-0.1.6.dist-info}/LICENSE +0 -0
- {instaui-0.1.5.dist-info → instaui-0.1.6.dist-info}/WHEEL +0 -0
@@ -1,175 +1,179 @@
|
|
1
|
-
:root {
|
2
|
-
--shiki-font-family-mono: ui-monospace, "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;
|
3
|
-
--shiki-code-line-height: 1.5;
|
4
|
-
--shiki-code-font-size: 0.875em;
|
5
|
-
--shiki-code-block-color: #67676c;
|
6
|
-
--shiki-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");
|
7
|
-
--shiki-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E");
|
8
|
-
--shiki-code-copy-code-border-color: #e2e2e3;
|
9
|
-
--shiki-code-copy-code-bg: #f6f6f7;
|
10
|
-
--shiki-code-copy-code-hover-border-color: #e2e2e3;
|
11
|
-
--shiki-code-copy-code-hover-bg: #ffffff;
|
12
|
-
--shiki-code-copy-code-active-text: #67676c;
|
13
|
-
--shiki-code-copy-copied-text-content: "Copied";
|
14
|
-
--shiki-code-lang-color: #929295;
|
15
|
-
}
|
16
|
-
@media (min-width: 640px) {
|
17
|
-
.shiki-code[class*=language-] {
|
18
|
-
border-radius: 8px;
|
19
|
-
margin: 15px 0;
|
20
|
-
}
|
21
|
-
}
|
22
|
-
.shiki-code[class*=language-] {
|
23
|
-
position: relative;
|
24
|
-
margin: 16px 0;
|
25
|
-
background-color: #f9f9f9;
|
26
|
-
overflow-x: auto;
|
27
|
-
transition: background-color 0.5s;
|
28
|
-
/* line numbers */
|
29
|
-
}
|
30
|
-
.shiki-code[class*=language-] pre,
|
31
|
-
.shiki-code[class*=language-] code {
|
32
|
-
font-family: var(--shiki-font-family-mono);
|
33
|
-
}
|
34
|
-
.shiki-code[class*=language-] pre {
|
35
|
-
position: relative;
|
36
|
-
z-index: 1;
|
37
|
-
margin: 0;
|
38
|
-
padding: 20px 0;
|
39
|
-
background: transparent;
|
40
|
-
overflow-x: auto;
|
41
|
-
}
|
42
|
-
.shiki-code[class*=language-] code {
|
43
|
-
display: block;
|
44
|
-
padding: 0 24px 0 0;
|
45
|
-
width: fit-content;
|
46
|
-
min-width: 100%;
|
47
|
-
line-height: var(--shiki-code-line-height);
|
48
|
-
font-size: var(--shiki-code-font-size);
|
49
|
-
color: var(--shiki-code-block-color);
|
50
|
-
transition: color 0.5s;
|
51
|
-
}
|
52
|
-
.shiki-code[class*=language-] code > .line:before {
|
53
|
-
content: ' ';
|
54
|
-
padding: 0 5px;
|
55
|
-
}
|
56
|
-
.shiki-code[class*=language-] > button.copy {
|
57
|
-
direction: ltr;
|
58
|
-
position: absolute;
|
59
|
-
top: 12px;
|
60
|
-
right: 12px;
|
61
|
-
z-index: 3;
|
62
|
-
border: 1px solid var(--shiki-code-copy-code-border-color);
|
63
|
-
border-radius: 4px;
|
64
|
-
width: 40px;
|
65
|
-
height: 40px;
|
66
|
-
background-color: var(--shiki-code-copy-code-bg);
|
67
|
-
opacity: 0;
|
68
|
-
cursor: pointer;
|
69
|
-
background-image: var(--shiki-icon-copy);
|
70
|
-
background-position: 50%;
|
71
|
-
background-size: 20px;
|
72
|
-
background-repeat: no-repeat;
|
73
|
-
transition: border-color 0.25s, background-color 0.25s, opacity 0.25s;
|
74
|
-
}
|
75
|
-
.shiki-code[class*=language-]:hover > button.copy,
|
76
|
-
.shiki-code[class*=language-] > button.copy:focus {
|
77
|
-
opacity: 1;
|
78
|
-
}
|
79
|
-
.shiki-code[class*=language-] > button.copy:hover,
|
80
|
-
.shiki-code[class*=language-] > button.copy.copied {
|
81
|
-
border-color: var(--shiki-code-copy-code-hover-border-color);
|
82
|
-
background-color: var(--shiki-code-copy-code-hover-bg);
|
83
|
-
}
|
84
|
-
.shiki-code[class*=language-] > button.copy.copied,
|
85
|
-
.shiki-code[class*=language-] > button.copy:hover.copied {
|
86
|
-
border-radius: 0 4px 4px 0;
|
87
|
-
background-color: var(--shiki-code-copy-code-hover-bg);
|
88
|
-
background-image: var(--shiki-icon-copied);
|
89
|
-
}
|
90
|
-
.shiki-code[class*=language-] > button.copy.copied:before,
|
91
|
-
.shiki-code[class*=language-] > button.copy:hover.copied:before {
|
92
|
-
position: relative;
|
93
|
-
top: -1px;
|
94
|
-
display: flex;
|
95
|
-
justify-content: center;
|
96
|
-
align-items: center;
|
97
|
-
border: 1px solid var(--shiki-code-copy-code-hover-border-color);
|
98
|
-
border-right: 0;
|
99
|
-
border-radius: 4px 0 0 4px;
|
100
|
-
padding: 0 10px;
|
101
|
-
width: fit-content;
|
102
|
-
height: 40px;
|
103
|
-
text-align: center;
|
104
|
-
font-size: 12px;
|
105
|
-
font-weight: 500;
|
106
|
-
color: var(--shiki-code-copy-code-active-text);
|
107
|
-
background-color: var(--shiki-code-copy-code-hover-bg);
|
108
|
-
white-space: nowrap;
|
109
|
-
content: var(--shiki-code-copy-copied-text-content);
|
110
|
-
transform: translate(calc(-100% - 1px));
|
111
|
-
}
|
112
|
-
.shiki-code[class*=language-] > span.lang {
|
113
|
-
position: absolute;
|
114
|
-
top: 2px;
|
115
|
-
right: 8px;
|
116
|
-
z-index: 2;
|
117
|
-
font-size: 12px;
|
118
|
-
font-weight: 500;
|
119
|
-
-webkit-user-select: none;
|
120
|
-
user-select: none;
|
121
|
-
color: var(--shiki-code-lang-color);
|
122
|
-
transition: color 0.4s, opacity 0.4s;
|
123
|
-
}
|
124
|
-
.shiki-code[class*=language-]:hover > button.copy + span.lang,
|
125
|
-
.shiki-code[class*=language-] > button.copy:focus + span.lang {
|
126
|
-
opacity: 0;
|
127
|
-
}
|
128
|
-
.shiki-code[class*=language-].theme-dark {
|
129
|
-
--shiki-code-line-diff-add-color: #3dd68c;
|
130
|
-
--shiki-code-line-diff-add-symbol-color: #3dd68c;
|
131
|
-
--shiki-code-line-diff-remove-color: hsla(349.72, 89.16%, 60.2%, 0.16);
|
132
|
-
--shiki-code-line-diff-remove-symbol-color: hsl(357.62, 39.92%, 50.39%);
|
133
|
-
--shiki-code-line-line-number-color: hsla(198.18, 13.36%, 80%, 0.7);
|
134
|
-
}
|
135
|
-
.shiki-code[class*=language-] pre.shiki .diff {
|
136
|
-
all: unset;
|
137
|
-
}
|
138
|
-
.shiki-code[class*=language-] pre.shiki code .diff.remove {
|
139
|
-
background-color: var(--shiki-code-line-diff-remove-color, rgba(244, 63, 94, 0.14));
|
140
|
-
opacity: 0.7;
|
141
|
-
}
|
142
|
-
.shiki-code[class*=language-] pre.shiki code .diff.add {
|
143
|
-
background-color: rgba(16, 185, 129, 0.14);
|
144
|
-
}
|
145
|
-
.shiki-code[class*=language-] pre.shiki code .diff.add:before {
|
146
|
-
content: "+";
|
147
|
-
color: var(--shiki-code-line-diff-add-symbol-color, #18794e);
|
148
|
-
}
|
149
|
-
.shiki-code[class*=language-] pre.shiki code .diff.remove:before {
|
150
|
-
content: "-";
|
151
|
-
color: var(--shiki-code-line-diff-remove-symbol-color, hsl(357.62, 39.92%, 50.39%));
|
152
|
-
}
|
153
|
-
.shiki-code[class*=language-] pre.shiki code .diff:before {
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
1
|
+
:root {
|
2
|
+
--shiki-font-family-mono: ui-monospace, "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;
|
3
|
+
--shiki-code-line-height: 1.5;
|
4
|
+
--shiki-code-font-size: 0.875em;
|
5
|
+
--shiki-code-block-color: #67676c;
|
6
|
+
--shiki-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");
|
7
|
+
--shiki-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E");
|
8
|
+
--shiki-code-copy-code-border-color: #e2e2e3;
|
9
|
+
--shiki-code-copy-code-bg: #f6f6f7;
|
10
|
+
--shiki-code-copy-code-hover-border-color: #e2e2e3;
|
11
|
+
--shiki-code-copy-code-hover-bg: #ffffff;
|
12
|
+
--shiki-code-copy-code-active-text: #67676c;
|
13
|
+
--shiki-code-copy-copied-text-content: "Copied";
|
14
|
+
--shiki-code-lang-color: #929295;
|
15
|
+
}
|
16
|
+
@media (min-width: 640px) {
|
17
|
+
.shiki-code[class*=language-] {
|
18
|
+
border-radius: 8px;
|
19
|
+
margin: 15px 0;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
.shiki-code[class*=language-] {
|
23
|
+
position: relative;
|
24
|
+
margin: 16px 0;
|
25
|
+
background-color: #f9f9f9;
|
26
|
+
overflow-x: auto;
|
27
|
+
transition: background-color 0.5s;
|
28
|
+
/* line numbers */
|
29
|
+
}
|
30
|
+
.shiki-code[class*=language-] pre,
|
31
|
+
.shiki-code[class*=language-] code {
|
32
|
+
font-family: var(--shiki-font-family-mono);
|
33
|
+
}
|
34
|
+
.shiki-code[class*=language-] pre {
|
35
|
+
position: relative;
|
36
|
+
z-index: 1;
|
37
|
+
margin: 0;
|
38
|
+
padding: 20px 0;
|
39
|
+
background: transparent;
|
40
|
+
overflow-x: auto;
|
41
|
+
}
|
42
|
+
.shiki-code[class*=language-] code {
|
43
|
+
display: block;
|
44
|
+
padding: 0 24px 0 0;
|
45
|
+
width: fit-content;
|
46
|
+
min-width: 100%;
|
47
|
+
line-height: var(--shiki-code-line-height);
|
48
|
+
font-size: var(--shiki-code-font-size);
|
49
|
+
color: var(--shiki-code-block-color);
|
50
|
+
transition: color 0.5s;
|
51
|
+
}
|
52
|
+
.shiki-code[class*=language-] code > .line:before {
|
53
|
+
content: ' ';
|
54
|
+
padding: 0 5px;
|
55
|
+
}
|
56
|
+
.shiki-code[class*=language-] > button.copy {
|
57
|
+
direction: ltr;
|
58
|
+
position: absolute;
|
59
|
+
top: 12px;
|
60
|
+
right: 12px;
|
61
|
+
z-index: 3;
|
62
|
+
border: 1px solid var(--shiki-code-copy-code-border-color);
|
63
|
+
border-radius: 4px;
|
64
|
+
width: 40px;
|
65
|
+
height: 40px;
|
66
|
+
background-color: var(--shiki-code-copy-code-bg);
|
67
|
+
opacity: 0;
|
68
|
+
cursor: pointer;
|
69
|
+
background-image: var(--shiki-icon-copy);
|
70
|
+
background-position: 50%;
|
71
|
+
background-size: 20px;
|
72
|
+
background-repeat: no-repeat;
|
73
|
+
transition: border-color 0.25s, background-color 0.25s, opacity 0.25s;
|
74
|
+
}
|
75
|
+
.shiki-code[class*=language-]:hover > button.copy,
|
76
|
+
.shiki-code[class*=language-] > button.copy:focus {
|
77
|
+
opacity: 1;
|
78
|
+
}
|
79
|
+
.shiki-code[class*=language-] > button.copy:hover,
|
80
|
+
.shiki-code[class*=language-] > button.copy.copied {
|
81
|
+
border-color: var(--shiki-code-copy-code-hover-border-color);
|
82
|
+
background-color: var(--shiki-code-copy-code-hover-bg);
|
83
|
+
}
|
84
|
+
.shiki-code[class*=language-] > button.copy.copied,
|
85
|
+
.shiki-code[class*=language-] > button.copy:hover.copied {
|
86
|
+
border-radius: 0 4px 4px 0;
|
87
|
+
background-color: var(--shiki-code-copy-code-hover-bg);
|
88
|
+
background-image: var(--shiki-icon-copied);
|
89
|
+
}
|
90
|
+
.shiki-code[class*=language-] > button.copy.copied:before,
|
91
|
+
.shiki-code[class*=language-] > button.copy:hover.copied:before {
|
92
|
+
position: relative;
|
93
|
+
top: -1px;
|
94
|
+
display: flex;
|
95
|
+
justify-content: center;
|
96
|
+
align-items: center;
|
97
|
+
border: 1px solid var(--shiki-code-copy-code-hover-border-color);
|
98
|
+
border-right: 0;
|
99
|
+
border-radius: 4px 0 0 4px;
|
100
|
+
padding: 0 10px;
|
101
|
+
width: fit-content;
|
102
|
+
height: 40px;
|
103
|
+
text-align: center;
|
104
|
+
font-size: 12px;
|
105
|
+
font-weight: 500;
|
106
|
+
color: var(--shiki-code-copy-code-active-text);
|
107
|
+
background-color: var(--shiki-code-copy-code-hover-bg);
|
108
|
+
white-space: nowrap;
|
109
|
+
content: var(--shiki-code-copy-copied-text-content);
|
110
|
+
transform: translate(calc(-100% - 1px));
|
111
|
+
}
|
112
|
+
.shiki-code[class*=language-] > span.lang {
|
113
|
+
position: absolute;
|
114
|
+
top: 2px;
|
115
|
+
right: 8px;
|
116
|
+
z-index: 2;
|
117
|
+
font-size: 12px;
|
118
|
+
font-weight: 500;
|
119
|
+
-webkit-user-select: none;
|
120
|
+
user-select: none;
|
121
|
+
color: var(--shiki-code-lang-color);
|
122
|
+
transition: color 0.4s, opacity 0.4s;
|
123
|
+
}
|
124
|
+
.shiki-code[class*=language-]:hover > button.copy + span.lang,
|
125
|
+
.shiki-code[class*=language-] > button.copy:focus + span.lang {
|
126
|
+
opacity: 0;
|
127
|
+
}
|
128
|
+
.shiki-code[class*=language-].theme-dark {
|
129
|
+
--shiki-code-line-diff-add-color: #3dd68c;
|
130
|
+
--shiki-code-line-diff-add-symbol-color: #3dd68c;
|
131
|
+
--shiki-code-line-diff-remove-color: hsla(349.72, 89.16%, 60.2%, 0.16);
|
132
|
+
--shiki-code-line-diff-remove-symbol-color: hsl(357.62, 39.92%, 50.39%);
|
133
|
+
--shiki-code-line-line-number-color: hsla(198.18, 13.36%, 80%, 0.7);
|
134
|
+
}
|
135
|
+
.shiki-code[class*=language-] pre.shiki .diff {
|
136
|
+
all: unset;
|
137
|
+
}
|
138
|
+
.shiki-code[class*=language-] pre.shiki code .diff.remove {
|
139
|
+
background-color: var(--shiki-code-line-diff-remove-color, rgba(244, 63, 94, 0.14));
|
140
|
+
opacity: 0.7;
|
141
|
+
}
|
142
|
+
.shiki-code[class*=language-] pre.shiki code .diff.add {
|
143
|
+
background-color: rgba(16, 185, 129, 0.14);
|
144
|
+
}
|
145
|
+
.shiki-code[class*=language-] pre.shiki code .diff.add:before {
|
146
|
+
content: "+";
|
147
|
+
color: var(--shiki-code-line-diff-add-symbol-color, #18794e);
|
148
|
+
}
|
149
|
+
.shiki-code[class*=language-] pre.shiki code .diff.remove:before {
|
150
|
+
content: "-";
|
151
|
+
color: var(--shiki-code-line-diff-remove-symbol-color, hsl(357.62, 39.92%, 50.39%));
|
152
|
+
}
|
153
|
+
.shiki-code[class*=language-] pre.shiki code .diff:before {
|
154
|
+
width: 2.5em;
|
155
|
+
text-align: left;
|
156
|
+
padding-left: 10px;
|
157
|
+
}
|
158
|
+
.shiki-code[class*=language-] pre.shiki code .diff {
|
159
|
+
box-sizing: border-box;
|
160
|
+
transition: background-color 0.5s;
|
161
|
+
margin: 0 -24px;
|
162
|
+
padding: 0 24px;
|
163
|
+
width: calc(100% + 48px);
|
164
|
+
display: inline-block;
|
165
|
+
}
|
166
|
+
.shiki-code[class*=language-].line-numbers code {
|
167
|
+
counter-reset: step;
|
168
|
+
counter-increment: step 0;
|
169
|
+
}
|
170
|
+
.shiki-code[class*=language-].line-numbers code .line::before {
|
171
|
+
content: counter(step);
|
172
|
+
counter-increment: step;
|
173
|
+
display: inline-block;
|
174
|
+
text-align: right;
|
175
|
+
color: var(--shiki-code-line-line-number-color, hsla(198.18, 13.36%, 51.57%, 0.7));
|
176
|
+
width: 2.5em;
|
177
|
+
text-align: left;
|
178
|
+
padding-left: 10px;
|
179
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
from instaui import ui
|
2
|
+
from ._types import TFilters
|
3
|
+
|
4
|
+
|
5
|
+
class DataSourceElement(ui.element, esm="./data_source.js"):
|
6
|
+
def __init__(
|
7
|
+
self,
|
8
|
+
):
|
9
|
+
super().__init__()
|
10
|
+
|
11
|
+
self._ele_ref = ui.element_ref()
|
12
|
+
self.element_ref(self._ele_ref)
|
13
|
+
|
14
|
+
self.filters: TFilters = ui.state({})
|
15
|
+
|
16
|
+
self.on(
|
17
|
+
"filter-changed",
|
18
|
+
ui.js_event(
|
19
|
+
inputs=[ui.event_context.e()],
|
20
|
+
outputs=[self.filters],
|
21
|
+
code="v=> v.filters",
|
22
|
+
),
|
23
|
+
)
|
@@ -0,0 +1,221 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
from typing import Dict, TypeVar
|
3
|
+
import itertools
|
4
|
+
from instaui import ui, arco
|
5
|
+
from ._base import DataSourceElement
|
6
|
+
from ._types import TFilters, TQueryStrInfo
|
7
|
+
|
8
|
+
try:
|
9
|
+
import pandas
|
10
|
+
import duckdb
|
11
|
+
except ImportError as e:
|
12
|
+
raise e
|
13
|
+
|
14
|
+
|
15
|
+
TElementClass = TypeVar("TElementClass", bound=ui.element)
|
16
|
+
|
17
|
+
|
18
|
+
class DuckdbDataFrameSource:
|
19
|
+
QUERY_ID: int = 0
|
20
|
+
|
21
|
+
def __init__(
|
22
|
+
self,
|
23
|
+
table_name: str,
|
24
|
+
):
|
25
|
+
super().__init__()
|
26
|
+
|
27
|
+
self._element = DataSourceElement()
|
28
|
+
self._conn = duckdb.connect(":default:", read_only=False)
|
29
|
+
self._table_name = table_name
|
30
|
+
|
31
|
+
def _generate_query_id(self):
|
32
|
+
self.QUERY_ID += 1
|
33
|
+
return self.QUERY_ID
|
34
|
+
|
35
|
+
def __getitem__(self, field: str):
|
36
|
+
def use_fn(cls: type[TElementClass]) -> TElementClass:
|
37
|
+
if issubclass(cls, arco.select):
|
38
|
+
return self.__apply_select(field)(cls)
|
39
|
+
|
40
|
+
if issubclass(cls, arco.input):
|
41
|
+
return self.__apply_input(field)(cls)
|
42
|
+
|
43
|
+
raise NotImplementedError(f"Not supported component:{cls.__name__}")
|
44
|
+
|
45
|
+
return use_fn
|
46
|
+
|
47
|
+
def __query_distinct_field_values(
|
48
|
+
self, field: str, query_id: int, order_sql: str = ""
|
49
|
+
):
|
50
|
+
@ui.computed(inputs=[self.__query_str_info(field, query_id), field, order_sql])
|
51
|
+
def query_distinct_field_values_computed(
|
52
|
+
with_filters_info: TQueryStrInfo, field: str, order_sql: str
|
53
|
+
):
|
54
|
+
sql = f"with cte as ({with_filters_info['sql']}) select distinct {field} from cte {order_sql}"
|
55
|
+
|
56
|
+
local_con = self._conn.cursor()
|
57
|
+
|
58
|
+
query = local_con.sql(sql, params=with_filters_info["params"])
|
59
|
+
return list(itertools.chain(*query.fetchall()))
|
60
|
+
|
61
|
+
return query_distinct_field_values_computed
|
62
|
+
|
63
|
+
def __apply_select(self, field: str):
|
64
|
+
def use_fn(cls: type[arco.select]) -> arco.select:
|
65
|
+
query_id = self._generate_query_id()
|
66
|
+
element = cls(
|
67
|
+
self.__query_distinct_field_values(
|
68
|
+
field=field, query_id=query_id, order_sql=f"order by {field}"
|
69
|
+
)
|
70
|
+
)
|
71
|
+
|
72
|
+
on_change = ui.js_event(
|
73
|
+
inputs=[ui.event_context.e(), field, query_id],
|
74
|
+
outputs=[self._element._ele_ref],
|
75
|
+
code=r"""(value,field,query_id) => {
|
76
|
+
if (value) {
|
77
|
+
return {method: 'addFilter', args:[{field, expr: `${field}= ?`,value,query_id}]};
|
78
|
+
}
|
79
|
+
|
80
|
+
return {method:'removeFilter', args:[{field,query_id}]};
|
81
|
+
}""",
|
82
|
+
)
|
83
|
+
|
84
|
+
element.on_change(on_change)
|
85
|
+
|
86
|
+
return element
|
87
|
+
|
88
|
+
return use_fn
|
89
|
+
|
90
|
+
def __apply_input(self, field: str):
|
91
|
+
def use_fn(cls: type[arco.input]) -> arco.input:
|
92
|
+
query_id = self._generate_query_id()
|
93
|
+
element = cls()
|
94
|
+
|
95
|
+
on_change = ui.js_event(
|
96
|
+
inputs=[ui.event_context.e(), field, query_id],
|
97
|
+
outputs=[self._element._ele_ref],
|
98
|
+
code=r"""(value,field,query_id) => {
|
99
|
+
if (value) {
|
100
|
+
value = `%${value.trim()}%`
|
101
|
+
return {method: 'addFilter', args:[{field, expr: `${field} like ?`,value,replace:true,query_id}]};
|
102
|
+
}
|
103
|
+
|
104
|
+
return {method:'removeFilter', args:[{field,query_id}]};
|
105
|
+
}""",
|
106
|
+
)
|
107
|
+
|
108
|
+
element.on_input(on_change)
|
109
|
+
|
110
|
+
return element
|
111
|
+
|
112
|
+
return use_fn
|
113
|
+
|
114
|
+
def __query_str_info(self, target_field: str = "", query_id: int = -1):
|
115
|
+
@ui.computed(inputs=[self._element.filters, target_field, query_id])
|
116
|
+
def query_str_computed(filters: TFilters, target_field: str, query_id: int):
|
117
|
+
if not filters:
|
118
|
+
return {
|
119
|
+
"sql": f"select * from {self._table_name}",
|
120
|
+
"params": [],
|
121
|
+
}
|
122
|
+
else:
|
123
|
+
filter_exprs = []
|
124
|
+
|
125
|
+
if target_field:
|
126
|
+
target_key = f"{target_field}-{query_id}"
|
127
|
+
without_target_exprs = (
|
128
|
+
exprs for key, exprs in filters.items() if key != target_key
|
129
|
+
)
|
130
|
+
filter_exprs = list(itertools.chain(*without_target_exprs))
|
131
|
+
else:
|
132
|
+
filter_exprs = list(itertools.chain(*filters.values()))
|
133
|
+
|
134
|
+
where_stem = " and ".join(info["expr"] for info in filter_exprs)
|
135
|
+
if where_stem:
|
136
|
+
where_stem = f" where {where_stem}"
|
137
|
+
return {
|
138
|
+
"sql": f"select * from {self._table_name}{where_stem}",
|
139
|
+
"params": [info["value"] for info in filter_exprs],
|
140
|
+
}
|
141
|
+
|
142
|
+
return query_str_computed
|
143
|
+
|
144
|
+
def query_str(self):
|
145
|
+
return ui.js_computed(
|
146
|
+
inputs=[self.__query_str_info()],
|
147
|
+
code=r"""info=>{
|
148
|
+
const {sql,params} = info;
|
149
|
+
let currentIndex = 0;
|
150
|
+
return sql.replace(/\?/g, function () {
|
151
|
+
if (currentIndex >= params.length) {
|
152
|
+
throw new Error('Not enough parameters provided for the SQL statement.');
|
153
|
+
}
|
154
|
+
return JSON.stringify(params[currentIndex++]);
|
155
|
+
});
|
156
|
+
}""",
|
157
|
+
)
|
158
|
+
|
159
|
+
def filters(self):
|
160
|
+
return self._element.filters
|
161
|
+
|
162
|
+
def __apply_table(self, *, sql: str):
|
163
|
+
def use_fn(cls: type[arco.table]) -> arco.table:
|
164
|
+
@ui.computed(inputs=[self.__query_str_info(), sql])
|
165
|
+
def table_query(with_filters_into: TQueryStrInfo, sql: str):
|
166
|
+
sql = f"with cte as ({with_filters_into['sql']}) {sql}"
|
167
|
+
|
168
|
+
local_con = self._conn.cursor()
|
169
|
+
|
170
|
+
query = local_con.sql(sql, params=with_filters_into["params"])
|
171
|
+
columns = query.columns
|
172
|
+
values = query.fetchall()
|
173
|
+
|
174
|
+
real_cols = [{"title": col, "dataIndex": col} for col in columns]
|
175
|
+
|
176
|
+
real_values = [
|
177
|
+
{col: val for col, val in zip(columns, row)} for row in values
|
178
|
+
]
|
179
|
+
|
180
|
+
return {
|
181
|
+
"columns": real_cols,
|
182
|
+
"data": real_values,
|
183
|
+
}
|
184
|
+
|
185
|
+
element = cls(
|
186
|
+
data=ui.js_computed(inputs=[table_query], code=r"v=> v ? v.data : []"),
|
187
|
+
columns=ui.js_computed(
|
188
|
+
inputs=[table_query], code=r"v=> v ? v.columns : []"
|
189
|
+
),
|
190
|
+
)
|
191
|
+
|
192
|
+
return element
|
193
|
+
|
194
|
+
return use_fn
|
195
|
+
|
196
|
+
def __call__(self, cls: type[arco.table], *, sql: str = "select * from cte"):
|
197
|
+
return self.__apply_table(sql=sql)(cls)
|
198
|
+
|
199
|
+
def query_table(self, *, sql: str):
|
200
|
+
return self.__apply_table(sql=sql)
|
201
|
+
|
202
|
+
|
203
|
+
class Facade:
|
204
|
+
def __call__(self, db: Path):
|
205
|
+
self.db = db
|
206
|
+
raise NotImplementedError()
|
207
|
+
|
208
|
+
@classmethod
|
209
|
+
def from_pandas(
|
210
|
+
cls, dataframe: "pandas.DataFrame", *, table_name: str = "df"
|
211
|
+
) -> DuckdbDataFrameSource:
|
212
|
+
ds = DuckdbDataFrameSource(table_name)
|
213
|
+
|
214
|
+
cursor = ds._conn.cursor()
|
215
|
+
cursor.execute(
|
216
|
+
f"create table if not exists {table_name} as select * from dataframe"
|
217
|
+
)
|
218
|
+
return ds
|
219
|
+
|
220
|
+
|
221
|
+
_facade = Facade()
|
@@ -0,0 +1,15 @@
|
|
1
|
+
from typing import Any, Dict, List
|
2
|
+
from typing_extensions import TypedDict
|
3
|
+
|
4
|
+
|
5
|
+
class TFilterInfo(TypedDict):
|
6
|
+
expr: str
|
7
|
+
value: Any
|
8
|
+
|
9
|
+
|
10
|
+
TFilters = Dict[str, List[TFilterInfo]]
|
11
|
+
|
12
|
+
|
13
|
+
class TQueryStrInfo(TypedDict):
|
14
|
+
sql: str
|
15
|
+
params: List[Any]
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
export default {
|
3
|
+
props: [],
|
4
|
+
|
5
|
+
setup(props, { emit, expose }) {
|
6
|
+
const filters = new Map()
|
7
|
+
|
8
|
+
function addFilter(filter) {
|
9
|
+
const { field, expr, value, replace = true, query_id } = filter
|
10
|
+
const key = `${field}-${query_id}`
|
11
|
+
|
12
|
+
if (!filters.has(key)) {
|
13
|
+
filters.set(key, [])
|
14
|
+
}
|
15
|
+
|
16
|
+
const info = { expr, value }
|
17
|
+
|
18
|
+
if (replace) {
|
19
|
+
filters.set(key, [info])
|
20
|
+
} else {
|
21
|
+
filters.get(key).push(info)
|
22
|
+
}
|
23
|
+
emit("filter-changed", { filters: Object.fromEntries(filters.entries()), target: field, query_id })
|
24
|
+
}
|
25
|
+
|
26
|
+
function removeFilter(info) {
|
27
|
+
const { field, query_id } = info
|
28
|
+
const key = `${field}-${query_id}`
|
29
|
+
|
30
|
+
filters.delete(key)
|
31
|
+
emit("filter-changed", { filters: Object.fromEntries(filters.entries()), target: field, query_id })
|
32
|
+
}
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
function test(count) {
|
37
|
+
console.log('test', count)
|
38
|
+
}
|
39
|
+
|
40
|
+
expose({
|
41
|
+
test,
|
42
|
+
addFilter,
|
43
|
+
removeFilter,
|
44
|
+
})
|
45
|
+
|
46
|
+
|
47
|
+
},
|
48
|
+
|
49
|
+
|
50
|
+
}
|
@@ -18,7 +18,7 @@ def create_router(app: FastAPI):
|
|
18
18
|
|
19
19
|
|
20
20
|
async def event_generator(
|
21
|
-
request: Request, connection_id: str, interval_heart_beat_sec:
|
21
|
+
request: Request, connection_id: str, interval_heart_beat_sec: float = 0.8
|
22
22
|
):
|
23
23
|
logger.debug("debug sse started")
|
24
24
|
task_event = asyncio.Event()
|