@zeroman.yang/react-auto-components 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +260 -0
  3. package/dist/adapters/xlsx.d.ts +7 -0
  4. package/dist/components/AutoChat/VirtualChatMessages.d.ts +16 -0
  5. package/dist/components/AutoChat/index.d.ts +4 -0
  6. package/dist/components/AutoChat/types.d.ts +89 -0
  7. package/dist/components/AutoChat/useChatScroll.d.ts +10 -0
  8. package/dist/components/AutoDialog/index.d.ts +46 -0
  9. package/dist/components/AutoForm/AutoForm.d.ts +2 -0
  10. package/dist/components/AutoForm/ChoiceField.d.ts +16 -0
  11. package/dist/components/AutoForm/FormField.d.ts +8 -0
  12. package/dist/components/AutoForm/index.d.ts +2 -0
  13. package/dist/components/AutoForm/types.d.ts +28 -0
  14. package/dist/components/AutoMenu/index.d.ts +35 -0
  15. package/dist/components/AutoSearchPanel/index.d.ts +21 -0
  16. package/dist/components/AutoTable/AutoTable.d.ts +2 -0
  17. package/dist/components/AutoTable/FilterEditor.d.ts +7 -0
  18. package/dist/components/AutoTable/SettingsPanel.d.ts +7 -0
  19. package/dist/components/AutoTable/TableHeader.d.ts +18 -0
  20. package/dist/components/AutoTable/export.d.ts +11 -0
  21. package/dist/components/AutoTable/features.d.ts +9 -0
  22. package/dist/components/AutoTable/index.d.ts +4 -0
  23. package/dist/components/AutoTable/settings.d.ts +34 -0
  24. package/dist/components/AutoTable/types.d.ts +107 -0
  25. package/dist/components/AutoTable/useTableData.d.ts +9 -0
  26. package/dist/components/AutoTable/useTableSettings.d.ts +7 -0
  27. package/dist/components/AutoTabs/index.d.ts +29 -0
  28. package/dist/core/AutoConfigProvider.d.ts +34 -0
  29. package/dist/core/config.d.ts +10 -0
  30. package/dist/core/i18n.d.ts +2 -0
  31. package/dist/core/query.d.ts +24 -0
  32. package/dist/core/types.d.ts +93 -0
  33. package/dist/index.d.ts +11 -0
  34. package/dist/index.js +3246 -0
  35. package/dist/internal/Popover.d.ts +16 -0
  36. package/dist/style.css +2 -0
  37. package/dist/xlsx.js +9 -0
  38. package/docs/auto-chat.md +89 -0
  39. package/docs/i18n/de/README.md +203 -0
  40. package/docs/i18n/de/auto-chat.md +82 -0
  41. package/docs/i18n/de/migration.md +71 -0
  42. package/docs/i18n/es/README.md +203 -0
  43. package/docs/i18n/es/auto-chat.md +82 -0
  44. package/docs/i18n/es/migration.md +71 -0
  45. package/docs/i18n/fr/README.md +203 -0
  46. package/docs/i18n/fr/auto-chat.md +82 -0
  47. package/docs/i18n/fr/migration.md +71 -0
  48. package/docs/i18n/ja/README.md +203 -0
  49. package/docs/i18n/ja/auto-chat.md +82 -0
  50. package/docs/i18n/ja/migration.md +71 -0
  51. package/docs/i18n/ko/README.md +203 -0
  52. package/docs/i18n/ko/auto-chat.md +82 -0
  53. package/docs/i18n/ko/migration.md +71 -0
  54. package/docs/i18n/pt-BR/README.md +203 -0
  55. package/docs/i18n/pt-BR/auto-chat.md +82 -0
  56. package/docs/i18n/pt-BR/migration.md +71 -0
  57. package/docs/i18n/ru/README.md +203 -0
  58. package/docs/i18n/ru/auto-chat.md +82 -0
  59. package/docs/i18n/ru/migration.md +71 -0
  60. package/docs/i18n/zh-CN/README.md +217 -0
  61. package/docs/i18n/zh-CN/auto-chat.md +82 -0
  62. package/docs/i18n/zh-CN/migration.md +71 -0
  63. package/docs/i18n/zh-TW/README.md +217 -0
  64. package/docs/i18n/zh-TW/auto-chat.md +82 -0
  65. package/docs/i18n/zh-TW/migration.md +71 -0
  66. package/docs/migration.md +71 -0
  67. package/package.json +111 -0
@@ -0,0 +1,16 @@
1
+ import { type Placement } from "@floating-ui/react";
2
+ import { type HTMLAttributes, type ReactElement, type ReactNode, type Ref } from "react";
3
+ import "./popover.css";
4
+ interface PopoverProps {
5
+ children: ReactElement<HTMLAttributes<HTMLElement> & {
6
+ ref?: Ref<HTMLElement>;
7
+ disabled?: boolean;
8
+ }>;
9
+ content: ReactNode;
10
+ placement?: Placement;
11
+ open?: boolean;
12
+ onOpenChange?: (open: boolean) => void;
13
+ }
14
+ /** Internal positioning primitive for menu flyouts and table filters. */
15
+ export declare function Popover({ children, content, placement, open: controlled, onOpenChange, }: PopoverProps): import("react").JSX.Element;
16
+ export {};
package/dist/style.css ADDED
@@ -0,0 +1,2 @@
1
+ :root{--auto-accent:#176b54;--auto-accent-soft:#e8f4ee;--auto-bg:#fff;--auto-muted:#f4f6f5;--auto-text:#202e29;--auto-secondary:#65746d;--auto-border:#dce4df;--auto-danger:#bd3545;--auto-radius:8px;--auto-font:Inter, ui-sans-serif, system-ui, sans-serif}.auto-root,.auto-overlay,.auto-popover{font-family:var(--auto-font);color:var(--auto-text);box-sizing:border-box;font-size:14px}.auto-root *,.auto-overlay *,.auto-popover *{box-sizing:border-box}.auto-root button,.auto-overlay button,.auto-popover button{font:inherit;cursor:pointer;border:1px solid var(--auto-border);background:var(--auto-bg);color:inherit;border-radius:6px;padding:7px 12px}.auto-root button:hover,.auto-overlay button:hover{background:var(--auto-muted)}.auto-root button:disabled,.auto-overlay button:disabled{opacity:.45;cursor:not-allowed}.auto-root .auto-primary,.auto-overlay .auto-primary{background:var(--auto-accent);color:var(--auto-primary-text,white);border-color:var(--auto-accent)}.auto-root input,.auto-root select,.auto-root textarea,.auto-overlay input,.auto-overlay select{font:inherit;border:1px solid var(--auto-border);background:var(--auto-bg);color:inherit;border-radius:6px;max-width:100%;padding:8px 10px}.auto-root input[aria-invalid=true],.auto-root select[aria-invalid=true],.auto-root textarea[aria-invalid=true],.auto-overlay input[aria-invalid=true],.auto-overlay select[aria-invalid=true]{border-color:var(--auto-danger)}.auto-root input[aria-invalid=true]:focus-visible,.auto-root select[aria-invalid=true]:focus-visible,.auto-root textarea[aria-invalid=true]:focus-visible,.auto-overlay input[aria-invalid=true]:focus-visible,.auto-overlay select[aria-invalid=true]:focus-visible{outline-color:var(--auto-danger)}.auto-root :focus-visible,.auto-overlay :focus-visible,.auto-popover :focus-visible{outline:2px solid var(--auto-accent);outline-offset:2px}.auto-actions{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.auto-error{color:var(--auto-danger);font-size:13px}.auto-muted{color:var(--auto-secondary)}.auto-empty{text-align:center;color:var(--auto-secondary);padding:40px}.auto-badge{background:var(--auto-accent-soft);color:var(--auto-accent);border-radius:20px;padding:3px 8px;font-size:12px;display:inline-flex}.auto-form-grid{grid-template-columns:repeat(var(--auto-columns,2), minmax(0, 1fr));gap:var(--auto-field-gap,18px);display:grid}.auto-field{flex-direction:column;gap:7px;min-width:0;display:flex}.auto-field>label{font-size:13px;font-weight:550}.auto-field>label span{color:var(--auto-danger)}.auto-field input:not([type=checkbox]):not([type=radio]),.auto-field select,.auto-field textarea{width:100%}.auto-form-actions{margin-top:22px}.auto-select-menu{border:1px solid var(--auto-border);background:var(--auto-bg);border-radius:8px;padding:8px}.auto-select-menu input{margin-bottom:8px}@media (width<=600px){.auto-form-grid{grid-template-columns:1fr}.auto-field{grid-column:1/-1!important}}.auto-search{border-bottom:1px solid var(--auto-border);padding:18px}.auto-overlay-backdrop{-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);z-index:1000;background:#13271e66;position:fixed;inset:0}.auto-overlay{background:var(--auto-bg);border:1px solid var(--auto-border);z-index:1001;border-radius:12px;flex-direction:column;max-width:calc(100vw - 32px);max-height:90vh;display:flex;position:fixed;top:50%;left:50%;box-shadow:0 24px 80px #0b261e40}.auto-dialog-header{border-bottom:1px solid var(--auto-border);touch-action:none;justify-content:space-between;align-items:center;padding:18px 22px;display:flex}.auto-dialog-header h2{margin:0;font-size:18px}.auto-dialog-body{padding:24px;overflow:auto}.auto-dialog-footer{border-top:1px solid var(--auto-border);justify-content:flex-end;padding:16px 22px}.auto-dialog-full{max-width:none;max-height:none;inset:16px;transform:none}.auto-tabs-heading{border-bottom:1px solid var(--auto-border);justify-content:space-between;gap:12px;display:flex}.auto-tab-list{gap:4px;display:flex;overflow:auto}.auto-tab-list button{white-space:nowrap;background:0 0;border:0;border-bottom:2px solid #0000;border-radius:0;padding:12px 18px}.auto-tab-list button[data-state=active]{color:var(--auto-accent);border-bottom-color:var(--auto-accent);background:var(--auto-accent-soft)}.auto-tab-badge{background:var(--auto-accent-soft);color:var(--auto-accent);border-radius:10px;justify-content:center;align-items:center;margin-left:6px;padding:1px 6px;font-size:11px;font-weight:600;line-height:16px;display:inline-flex}.auto-tab-content{min-width:0;padding:20px 0}.auto-tab-content[hidden]{display:none}.auto-tabs-vertical{grid-template-columns:170px minmax(0,1fr);gap:20px;display:grid}.auto-tabs-vertical>.auto-tabs-heading{border:0}.auto-tabs-vertical>.auto-tabs-heading .auto-tab-list{flex-direction:column;width:100%}.auto-table{border:1px solid var(--auto-border);background:var(--auto-bg);border-radius:10px;overflow:hidden}.auto-toolbar{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:16px;padding:16px 18px;display:flex}.auto-toolbar strong{font-size:16px}.auto-table table{border-spacing:0;border-collapse:separate}.auto-table th,.auto-table td{border-bottom:1px solid var(--auto-border);text-overflow:ellipsis;white-space:nowrap;padding:8px 12px;overflow:hidden}.auto-table th{height:42px;font-size:12px;font-weight:550;top:0;background:var(--auto-muted)!important;z-index:4!important;position:sticky!important}.auto-table tbody tr:hover td{background:var(--auto-accent-soft)!important}.auto-table tbody tr.auto-current td{background:var(--auto-accent-soft)}.auto-table tfoot td{font-weight:600;position:sticky;bottom:0;background:var(--auto-muted)!important}.auto-table th.auto-table-cell-selection,.auto-table td.auto-table-cell-selection,.auto-table th:first-child,.auto-table tbody>tr>td:first-child:not([colspan]){text-align:center;width:44px;min-width:44px;max-width:44px;padding-left:0!important;padding-right:0!important}.auto-table tfoot td:first-child{text-align:center;white-space:nowrap;padding:8px 4px;overflow:visible}.auto-table progress{accent-color:var(--auto-accent);border-radius:4px;width:100%;min-width:60px;height:6px}.auto-column-heading{align-items:center;gap:2px;display:flex;position:relative}.auto-column-heading button{text-align:left;background:0 0;border:0;padding:0;font-size:12px}.auto-column-heading button:disabled{opacity:1;color:inherit;cursor:default}.auto-column-heading button.auto-filter-active{color:var(--auto-accent);background:var(--auto-accent-soft);border-radius:4px;padding:1px 4px;font-weight:700}.auto-resize{cursor:col-resize;touch-action:none;border-right:2px solid #0000;width:6px;position:absolute;top:-10px;bottom:-10px;right:-10px}.auto-resize:hover{border-color:var(--auto-accent)}.auto-cell{align-items:center;gap:6px;min-height:22px;display:flex}.auto-expand{padding:0 5px!important}.auto-pagination{border-top:1px solid var(--auto-border);justify-content:space-between;align-items:center;padding:12px 18px;font-size:12px;display:flex}.auto-sort-tags{padding:0 18px 12px}.auto-sort-tags button{background:var(--auto-accent-soft);border:0;font-size:12px}.auto-json{max-height:500px;padding:18px;overflow:auto}.auto-json pre{font-size:12px}.auto-notice{background:var(--auto-accent-soft);justify-content:space-between;padding:8px 18px;display:flex}.auto-filter-options{flex-direction:column;min-width:150px;max-height:300px;display:flex;overflow:auto}.auto-filter-options button{justify-content:space-between;gap:12px;display:flex}.auto-settings{min-width:0}.auto-preset{border-bottom:1px solid var(--auto-border);margin:18px 0;padding-bottom:18px}.auto-setting-row{border-bottom:1px solid var(--auto-border);align-items:center;gap:8px;padding:8px 0;display:flex}.auto-setting-row>label{flex:1}.auto-setting-row>input[type=number]{width:80px}.auto-settings textarea{font-family:monospace}.auto-context-menu [role=menuitem]{cursor:pointer;border-radius:4px;padding:8px 16px}.auto-context-menu [data-highlighted]{background:var(--auto-accent-soft)}.auto-context-menu [data-disabled]{opacity:.4}.auto-skeleton{color:var(--auto-secondary);animation:1s infinite auto-pulse}@keyframes auto-pulse{50%{opacity:.3}}.auto-table[data-height=auto]{flex-direction:column;flex:1;min-width:0;height:100%;min-height:0;display:flex}.auto-table[data-height=auto]>*{flex-shrink:0}.auto-table[data-height=auto]>.auto-table-scroll,.auto-table[data-height=auto]>.auto-json{flex:1;min-height:0;max-height:none;overflow:auto}.auto-field-control{flex-direction:column;gap:4px;min-width:0;display:flex}.auto-field-control>input[type=checkbox],.auto-field-control>input[type=radio]{align-self:flex-start}.auto-form[data-label-position=left]>.auto-form-grid>.auto-field[data-field]{grid-template-columns:var(--auto-label-width,96px) minmax(0, 1fr);align-items:start;column-gap:8px;display:grid}.auto-form[data-label-position=left]>.auto-form-grid>.auto-field>label{text-align:right;overflow-wrap:anywhere;padding-top:8px;line-height:20px}.auto-form[data-label-position=left][data-label-width=auto]>.auto-form-grid>.auto-field[data-field]{grid-template-columns:minmax(0, min(var(--auto-label-width,96px), 45%)) minmax(0, 1fr)}.auto-form[data-density=compact]{--auto-field-gap:10px 16px}.auto-form[data-density=compact]>.auto-form-grid>.auto-field{gap:4px 8px}.auto-form[data-density=compact][data-label-position=left]>.auto-form-grid>.auto-field>label{padding-top:6px}.auto-form[data-density=compact] .auto-field input:not([type=checkbox]):not([type=radio]),.auto-form[data-density=compact] .auto-field select,.auto-form[data-density=compact] .auto-field textarea{min-height:var(--auto-compact-control-height,32px);padding:var(--auto-compact-control-padding,5px 8px);font-size:var(--auto-compact-control-font,13px);line-height:20px}.auto-form[data-density=compact]>.auto-form-actions{margin-top:12px}.auto-search[data-density=compact]{padding:12px 16px}.auto-search[data-density=compact]>.auto-form{flex-wrap:wrap;align-items:flex-start;gap:10px 16px;display:flex}.auto-search[data-density=compact]>.auto-form>.auto-form-grid{flex:540px;min-width:0}.auto-search[data-density=compact]>.auto-form>.auto-form-actions{flex:none;margin-top:0}.auto-search[data-density=compact]>.auto-form>.auto-form-actions>button{min-height:var(--auto-compact-control-height,32px);padding:var(--auto-compact-control-padding,5px 10px);font-size:var(--auto-compact-control-font,13px);line-height:20px}.auto-form[data-label-align=left]>.auto-form-grid>.auto-field>label{text-align:left}.auto-form[data-label-align=right]>.auto-form-grid>.auto-field>label{text-align:right}.auto-search[data-label-width=auto]>.auto-form[data-label-position=left]>.auto-form-grid>.auto-field[data-field]{grid-template-columns:fit-content(45%) minmax(0,1fr)}.auto-root[data-size],.auto-overlay[data-size]{--auto-control-font:14px;--auto-control-height:0px;--auto-control-radius:6px;--auto-button-padding:7px 12px;--auto-input-padding:8px 10px;--auto-compact-control-height:32px;--auto-compact-control-padding:5px 8px;--auto-compact-control-font:13px}.auto-root[data-size=small],.auto-overlay[data-size=small]{--auto-control-font:12px;--auto-control-height:26px;--auto-control-radius:4px;--auto-button-padding:4px 8px;--auto-input-padding:4px 8px;--auto-compact-control-height:26px;--auto-compact-control-padding:4px 8px;--auto-compact-control-font:12px}.auto-root[data-size=large],.auto-overlay[data-size=large]{--auto-control-font:15px;--auto-control-height:42px;--auto-control-radius:8px;--auto-button-padding:10px 18px;--auto-input-padding:10px 14px;--auto-compact-control-height:42px;--auto-compact-control-padding:10px 14px;--auto-compact-control-font:15px}.auto-root[data-size] button:where(:not(.auto-tab-list button,.auto-menu button,.auto-column-heading button)),.auto-overlay[data-size] button:where(:not(.auto-tab-list button,.auto-menu button,.auto-column-heading button)){padding:var(--auto-button-padding);font-size:var(--auto-control-font);min-height:var(--auto-control-height);border-radius:var(--auto-control-radius)}.auto-root[data-size] input:not([type=checkbox]):not([type=radio]),.auto-root[data-size] select,.auto-root[data-size] textarea,.auto-overlay[data-size] input:not([type=checkbox]):not([type=radio]),.auto-overlay[data-size] select{padding:var(--auto-input-padding);font-size:var(--auto-control-font);min-height:var(--auto-control-height);border-radius:var(--auto-control-radius)}[data-size=small],.auto-form[data-size=small]>.auto-form-grid>.auto-field>label{font-size:12px}.auto-tabs[data-size=small]>.auto-tabs-heading>.auto-tab-list button{padding:6px 12px;font-size:12px}.auto-tabs[data-size=small]>.auto-tabs-heading>.auto-tab-list .auto-tab-badge{padding:0 4px;font-size:10px;line-height:14px}.auto-tabs[data-size=small]>.auto-tab-content{padding:12px 0}.auto-table[data-size=small]{font-size:12px}.auto-table[data-size=small]>.auto-table-scroll>table>:is(thead,tbody,tfoot)>tr>th{height:32px;font-size:11px}.auto-table[data-size=small]>.auto-table-scroll>table>:is(thead,tbody,tfoot)>tr>th,.auto-table[data-size=small]>.auto-table-scroll>table>:is(thead,tbody,tfoot)>tr>td{padding:4px 8px}.auto-table[data-size=small]>.auto-toolbar{gap:8px;padding:8px 12px}.auto-table[data-size=small]>.auto-toolbar strong{font-size:14px}.auto-table[data-size=small]>.auto-pagination{padding:8px 12px;font-size:11px}.auto-overlay[data-size=small] .auto-dialog-header{padding:12px 16px}.auto-overlay[data-size=small] .auto-dialog-header h2{font-size:15px}.auto-overlay[data-size=small] .auto-dialog-body{padding:16px}.auto-overlay[data-size=small] .auto-dialog-footer{padding:10px 16px}[data-size=large]{font-size:15px}.auto-form[data-size=large]>.auto-form-grid>.auto-field>label{font-size:14px}.auto-tabs[data-size=large]>.auto-tabs-heading>.auto-tab-list button{padding:15px 24px;font-size:15px}.auto-tabs[data-size=large]>.auto-tabs-heading>.auto-tab-list .auto-tab-badge{padding:2px 8px;font-size:12px;line-height:18px}.auto-tabs[data-size=large]>.auto-tab-content{padding:24px 0}.auto-table[data-size=large]{font-size:14px}.auto-table[data-size=large]>.auto-table-scroll>table>:is(thead,tbody,tfoot)>tr>th{height:48px;font-size:13px}.auto-table[data-size=large]>.auto-table-scroll>table>:is(thead,tbody,tfoot)>tr>th,.auto-table[data-size=large]>.auto-table-scroll>table>:is(thead,tbody,tfoot)>tr>td{padding:12px 16px}.auto-table[data-size=large]>.auto-toolbar{gap:16px;padding:18px 22px}.auto-table[data-size=large]>.auto-toolbar strong{font-size:18px}.auto-table[data-size=large]>.auto-pagination{padding:16px 22px;font-size:13px}.auto-overlay[data-size=large] .auto-dialog-header{padding:20px 24px}.auto-overlay[data-size=large] .auto-dialog-header h2{font-size:20px}.auto-overlay[data-size=large] .auto-dialog-body{padding:28px}.auto-overlay[data-size=large] .auto-dialog-footer{padding:18px 24px}.auto-tabs[data-density=compact]>.auto-tabs-heading>.auto-tab-list button{padding-top:6px;padding-bottom:6px}.auto-tabs[data-density=compact]>.auto-tab-content{padding:10px 0}.auto-table[data-density=compact]>.auto-table-scroll>table>:is(thead,tbody,tfoot)>tr>th{height:32px}.auto-table[data-density=compact]>.auto-table-scroll>table>:is(thead,tbody,tfoot)>tr>th,.auto-table[data-density=compact]>.auto-table-scroll>table>:is(thead,tbody,tfoot)>tr>td{padding-top:4px;padding-bottom:4px}.auto-table[data-density=compact]>.auto-toolbar{padding-top:10px;padding-bottom:10px}.auto-table[data-density=compact]>.auto-pagination{padding-top:8px;padding-bottom:8px}.auto-table[data-density=comfortable]>.auto-table-scroll>table>:is(thead,tbody,tfoot)>tr>th{height:48px}.auto-table[data-density=comfortable]>.auto-table-scroll>table>:is(thead,tbody,tfoot)>tr>th,.auto-table[data-density=comfortable]>.auto-table-scroll>table>:is(thead,tbody,tfoot)>tr>td{padding-top:12px;padding-bottom:12px}.auto-table[data-density=comfortable]>.auto-toolbar{padding-top:18px;padding-bottom:18px}.auto-table[data-density=comfortable]>.auto-pagination{padding-top:14px;padding-bottom:14px}.auto-table input[type=checkbox],.auto-table input[type=radio]{vertical-align:middle;margin:0}.auto-table[data-density=compact]>.auto-table-scroll>table>tbody>tr>td>.auto-cell{min-height:0}.auto-row-actions{flex-wrap:nowrap}.auto-menu{min-width:0;height:100%;min-height:0;color:var(--auto-text);box-sizing:border-box;flex-direction:column;gap:4px;display:flex}.auto-menu-header,.auto-menu-label,.auto-menu-footer,.auto-menu-collapse-btn{flex-shrink:0}.auto-menu-label{letter-spacing:1.5px;text-transform:uppercase;color:var(--auto-secondary);opacity:.85;-webkit-user-select:none;user-select:none;margin:14px 10px 6px;font-size:10px;font-weight:600}.auto-menu-list{scrollbar-width:thin;scrollbar-color:var(--auto-border) transparent;-webkit-overflow-scrolling:touch;flex-direction:column;flex:auto;gap:4px;min-height:0;margin:0;padding:0;list-style:none;display:flex;overflow:hidden auto}.auto-menu-item{flex-direction:column;min-width:0;display:flex}.auto-menu [data-auto-menu-item]{text-align:left;width:100%;min-width:0;min-height:40px;color:var(--auto-secondary);border-radius:var(--auto-radius,8px);font-size:var(--auto-control-font,14px);cursor:pointer;box-sizing:border-box;background:0 0;border:0;align-items:center;gap:12px;padding:9px 12px;line-height:1.3;text-decoration:none;transition:background-color .12s,color .12s;display:flex;position:relative}.auto-menu [data-auto-menu-item]:hover:not(:disabled){background:var(--auto-muted);color:var(--auto-text)}.auto-menu [data-auto-menu-item].active,.auto-menu [data-auto-menu-item][aria-current=page]{background:var(--auto-accent-soft);color:var(--auto-accent);font-weight:600}.auto-menu [data-auto-menu-item].active .auto-menu-icon,.auto-menu [data-auto-menu-item][aria-current=page] .auto-menu-icon{color:var(--auto-accent)}.auto-menu [data-auto-menu-item].active .auto-menu-text small,.auto-menu [data-auto-menu-item][aria-current=page] .auto-menu-text small{color:var(--auto-accent);opacity:.85}.auto-menu [data-auto-menu-item][data-active-branch=true]:not(.active):not([aria-current=page]){color:var(--auto-text);font-weight:550}.auto-menu [data-auto-menu-item][data-active-branch=true] .auto-menu-icon,.auto-menu [data-auto-menu-item][data-active-branch=true] .auto-menu-arrow{color:var(--auto-accent)}.auto-menu [data-auto-menu-item]:focus-visible,.auto-menu-collapse-btn:focus-visible{outline:2px solid var(--auto-accent);outline-offset:-2px;box-shadow:0 0 0 2px var(--auto-accent-soft)}.auto-menu [data-auto-menu-item]:disabled{opacity:.42;cursor:not-allowed}.auto-menu [data-auto-menu-item]:disabled:hover{color:var(--auto-secondary);background:0 0}.auto-menu-icon{flex-shrink:0;place-items:center;width:22px;height:22px;font-size:19px;line-height:1;display:grid}.auto-menu-text{overflow-wrap:break-word;word-break:break-word;flex-direction:column;flex:auto;min-width:0;font-size:13px;font-weight:600;line-height:1.3;display:flex}.auto-menu-text small{color:inherit;opacity:.72;overflow-wrap:break-word;word-break:break-word;margin-top:2px;font-size:11px;font-weight:400;line-height:1.25;display:block}.auto-menu-badge{background:var(--auto-accent-soft);color:var(--auto-accent);border-radius:10px;flex-shrink:0;justify-content:center;align-items:center;min-width:18px;height:18px;padding:1px 6px;font-size:11px;font-weight:600;line-height:1.3;display:inline-flex}.auto-menu [data-auto-menu-item].active .auto-menu-badge,.auto-menu [data-auto-menu-item][aria-current=page] .auto-menu-badge{background:var(--auto-accent);color:#fff}.auto-menu-arrow{color:var(--auto-secondary);flex-shrink:0;margin-left:auto;font-size:.75em;line-height:1;transition:transform .15s}.auto-menu-arrow-open{transform:rotate(180deg)}.auto-menu:not(.auto-menu-flyout) .auto-menu-list .auto-menu-list{border-left:1px solid var(--auto-border);flex:none;gap:3px;margin:3px 0 4px 18px;padding-left:12px;overflow:visible}.auto-menu:not(.auto-menu-flyout) .auto-menu-list .auto-menu-list [data-auto-menu-item]{font-size:calc(var(--auto-control-font,14px) * .93);gap:10px;min-height:34px;padding:6px 10px}.auto-menu:not(.auto-menu-flyout) .auto-menu-list .auto-menu-list [data-auto-menu-item] .auto-menu-text{font-size:12px;font-weight:500}.auto-menu-footer{border-top:1px solid var(--auto-border);flex-shrink:0;margin-top:auto;padding:14px 10px 4px}.auto-menu-footer>.sidebar-footer{border-top:none;margin-top:0;padding:0}.auto-menu-collapse-btn{border-radius:var(--auto-radius,8px);width:32px;height:32px;min-height:32px;color:var(--auto-secondary);border:1px solid var(--auto-border);cursor:pointer;box-sizing:border-box;background:0 0;flex-shrink:0;justify-content:center;align-self:flex-end;align-items:center;margin:4px 6px;padding:0;font-size:13px;line-height:1;transition:background-color .12s,color .12s,border-color .12s;display:inline-flex}.auto-menu-collapse-btn:hover:not(:disabled){background:var(--auto-muted);color:var(--auto-text);border-color:var(--auto-secondary)}.auto-menu[data-collapsed=true]{align-items:center;gap:6px}.auto-menu[data-collapsed=true] .auto-menu-list{align-items:center;gap:4px;width:100%}.auto-menu[data-collapsed=true] .auto-menu-item{align-items:center;width:100%}.auto-menu[data-collapsed=true] [data-auto-menu-item]{border-radius:var(--auto-radius,8px);justify-content:center;width:42px;height:42px;min-height:42px;margin:0 auto;padding:0}.auto-menu[data-collapsed=true] [data-auto-menu-item] .auto-menu-icon{width:auto;height:auto;font-size:15px;font-weight:600}.auto-menu[data-collapsed=true] [data-auto-menu-item][data-active-branch=true]{background:var(--auto-accent-soft);color:var(--auto-accent);font-weight:600}.auto-menu[data-collapsed=true] .auto-menu-label{visibility:hidden;height:0;margin:0;overflow:hidden}.auto-menu[data-collapsed=true] .auto-menu-collapse-btn{align-self:center;width:36px;height:36px;min-height:36px;margin:6px auto}.auto-menu[data-collapsed=true] .auto-menu-footer{text-align:center;width:100%;padding:8px 4px}.auto-menu[data-size=small] [data-auto-menu-item]{gap:10px;min-height:34px;padding:6px 10px;font-size:12px}.auto-menu[data-size=small] .auto-menu-icon{width:18px;height:18px;font-size:16px}.auto-menu[data-size=small] .auto-menu-text{font-size:12px}.auto-menu[data-size=small] .auto-menu-text small{font-size:10.5px}.auto-menu[data-size=small] .auto-menu-list .auto-menu-list{margin-left:14px;padding-left:10px}.auto-menu[data-size=large] [data-auto-menu-item]{gap:14px;min-height:48px;padding:11px 16px;font-size:15px}.auto-menu[data-size=large] .auto-menu-icon{width:24px;height:24px;font-size:21px}.auto-menu[data-size=large] .auto-menu-text{font-size:14.5px}.auto-menu[data-size=large] .auto-menu-text small{font-size:12px}.auto-menu[data-size=small][data-collapsed=true] [data-auto-menu-item]{width:34px;height:34px;min-height:34px}.auto-menu[data-size=large][data-collapsed=true] [data-auto-menu-item]{width:46px;height:46px;min-height:46px}.auto-menu[data-density=compact],.auto-menu[data-density=compact] .auto-menu-list{gap:2px}.auto-menu[data-density=compact] [data-auto-menu-item]{gap:10px;min-height:34px;padding-top:5px;padding-bottom:5px}.auto-menu[data-density=compact][data-collapsed=true] [data-auto-menu-item]{width:36px;height:36px;min-height:36px}.auto-popover:has(.auto-menu-flyout){border-radius:var(--auto-radius,8px);padding:4px}.auto-menu.auto-menu-flyout{gap:2px;width:220px;min-width:190px;max-width:min(300px,100vw - 24px);height:auto;max-height:min(440px,100dvh - 32px,100vh - 32px);overflow:hidden}.auto-menu-flyout .auto-menu-label{letter-spacing:.06em;text-transform:uppercase;color:var(--auto-secondary);margin:6px 10px 4px;font-size:11px;font-weight:600}.auto-menu-flyout>.auto-menu-list{border-left:none;flex:auto;min-height:0;margin:0;padding:0;overflow:hidden auto}.auto-menu-flyout>.auto-menu-list>.auto-menu-item>[data-auto-menu-item]{font-size:var(--auto-control-font,14px);min-height:34px;padding:7px 10px}.auto-menu-flyout .auto-menu-list .auto-menu-list{border-left:1px solid var(--auto-border);flex:none;gap:2px;margin:2px 0 3px 14px;padding-left:10px;overflow:visible}.auto-menu-flyout .auto-menu-list .auto-menu-list [data-auto-menu-item]{font-size:calc(var(--auto-control-font,14px) * .93);min-height:32px;padding:5px 8px}.auto-popover .auto-menu-flyout [data-auto-menu-item]{color:var(--auto-secondary);border-radius:var(--auto-radius,8px);background:0 0;border:0}.auto-popover .auto-menu-flyout [data-auto-menu-item]:hover:not(:disabled){background:var(--auto-muted);color:var(--auto-text)}.auto-popover .auto-menu-flyout [data-auto-menu-item].active,.auto-popover .auto-menu-flyout [data-auto-menu-item][aria-current=page]{background:var(--auto-accent-soft);color:var(--auto-accent);font-weight:600}@media (prefers-reduced-motion:reduce){.auto-menu-arrow,.auto-menu [data-auto-menu-item],.auto-menu-collapse-btn{transition:none!important}}.auto-popover{z-index:1100;box-sizing:border-box;background:var(--auto-bg);width:max-content;color:var(--auto-text);border:1px solid var(--auto-border);max-width:min(420px, calc(100vw - 16px), var(--auto-popover-available-width,420px));max-height:var(--auto-popover-available-height,calc(100vh - 24px));border-radius:8px;flex-direction:column;padding:14px;display:flex;box-shadow:0 4px 16px #0000001f}.auto-popover-body{overflow-wrap:anywhere;flex:auto;min-width:0;min-height:0;overflow:auto}.auto-chat{--auto-chat-avatar:2rem;--auto-chat-pad:.75rem 1rem;--auto-chat-gap:1rem;background:var(--auto-bg);height:100%;min-height:0;color:var(--auto-text);border:1px solid var(--auto-border);box-sizing:border-box;border-radius:.5rem;flex-direction:column;display:flex;position:relative}.auto-chat,.auto-chat *{box-sizing:border-box}.auto-chat[data-size=small]{--auto-chat-avatar:1.5rem;font-size:.8125rem}.auto-chat[data-size=large]{--auto-chat-avatar:2.5rem;font-size:1.0625rem}.auto-chat[data-density=compact]{--auto-chat-pad:.5rem .75rem;--auto-chat-gap:.5rem}.auto-chat .auto-chat-header{padding:var(--auto-chat-pad);border-bottom:1px solid var(--auto-border);flex-shrink:0;justify-content:space-between;align-items:center;display:flex}.auto-chat .auto-chat-history-shell{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.auto-chat .auto-chat-history{overflow-anchor:none;min-height:0;padding:var(--auto-chat-pad);gap:var(--auto-chat-gap);flex-direction:column;flex:1;display:flex;overflow:hidden auto}.auto-chat .auto-chat-history-start{flex-shrink:0;justify-content:center;display:flex}.auto-root.auto-chat .auto-chat-history-start button{background:var(--auto-muted);color:var(--auto-secondary);border:1px solid var(--auto-border);cursor:pointer;border-radius:.25rem;padding:.25rem .75rem}.auto-root.auto-chat .auto-chat-history-start button:hover{background:var(--auto-accent-soft);color:var(--auto-accent);border-color:var(--auto-accent)}.auto-chat .auto-chat-empty{color:var(--auto-secondary);text-align:center;margin:auto;padding:2rem 1rem}.auto-chat .auto-chat-messages{gap:var(--auto-chat-gap);flex-direction:column;flex-shrink:0;margin:0;padding:0;list-style:none;display:flex}.auto-root.auto-chat button.auto-chat-latest{z-index:5;background:var(--auto-bg);color:var(--auto-text);border:1px solid var(--auto-border);box-shadow:0 2px 8px color-mix(in srgb, var(--auto-text) 12%, transparent);cursor:pointer;border-radius:9999px;align-items:center;gap:.375rem;padding:.35rem .75rem;display:inline-flex;position:absolute;bottom:.75rem;right:1rem}.auto-root.auto-chat button.auto-chat-latest:hover{background:var(--auto-accent-soft);color:var(--auto-accent);border-color:var(--auto-accent)}.auto-chat .auto-chat-message{align-items:flex-start;gap:.625rem;min-width:0;max-width:100%;display:flex}.auto-chat .auto-chat-avatar{width:var(--auto-chat-avatar);height:var(--auto-chat-avatar);background:var(--auto-muted);color:var(--auto-secondary);font-size:calc(var(--auto-chat-avatar) * .45);border:1px solid var(--auto-border);border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-weight:600;display:inline-flex;overflow:hidden}.auto-chat .auto-chat-avatar>*{object-fit:cover;width:100%;height:100%}.auto-chat .auto-chat-message-main{flex-direction:column;flex:auto;gap:.25rem;min-width:0;display:flex}.auto-chat .auto-chat-message-meta{color:var(--auto-secondary);align-items:center;gap:.5rem;font-size:.8125em;display:flex}.auto-chat .auto-chat-message-meta strong{color:var(--auto-text);font-weight:600}.auto-chat .auto-chat-streaming{color:var(--auto-accent);align-items:center;gap:.25rem;display:inline-flex}.auto-chat .auto-chat-streaming:after{content:"";background:var(--auto-accent);border-radius:50%;width:.45em;height:.45em;animation:1.2s ease-in-out infinite auto-chat-pulse}@keyframes auto-chat-pulse{0%,to{opacity:.3;transform:scale(.8)}50%{opacity:1;transform:scale(1.1)}}.auto-chat .auto-chat-message-body{-webkit-user-select:text;user-select:text;overflow-wrap:anywhere;word-break:break-word;min-width:0}.auto-chat .auto-chat-text{white-space:pre-wrap}.auto-chat .auto-chat-message-body pre{white-space:pre;background:var(--auto-muted);border:1px solid var(--auto-border);border-radius:.375rem;max-width:100%;margin:.375rem 0;padding:.5rem .75rem;overflow-x:auto}.auto-chat .auto-chat-message-body table{border-collapse:collapse;max-width:100%;margin:.375rem 0;display:block;overflow-x:auto}.auto-chat .auto-chat-message-body th,.auto-chat .auto-chat-message-body td{border:1px solid var(--auto-border);padding:.375rem .5rem}.auto-chat .auto-chat-message-actions{align-items:center;gap:.25rem;margin-top:.25rem;display:flex}.auto-root.auto-chat .auto-chat-message-actions button{color:var(--auto-secondary);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:.25rem;padding:.2rem .4rem;font-size:.75rem}.auto-root.auto-chat .auto-chat-message-actions button:hover{background:var(--auto-muted);color:var(--auto-text);border-color:var(--auto-border)}.auto-chat .auto-chat-message[data-role=user]{flex-direction:row-reverse;align-self:flex-end;max-width:85%}.auto-chat .auto-chat-message[data-role=user] .auto-chat-message-main{align-items:flex-end}.auto-chat .auto-chat-message[data-role=user] .auto-chat-message-body{background:var(--auto-accent-soft);border:1px solid var(--auto-border);border-radius:.75rem .25rem .75rem .75rem;padding:.5rem .75rem}.auto-chat .auto-chat-message[data-role=assistant]{width:100%}.auto-chat .auto-chat-message[data-role=system]{align-self:center;max-width:85%}.auto-chat .auto-chat-message[data-role=system] .auto-chat-message-main{align-items:center}.auto-chat .auto-chat-message[data-role=system] .auto-chat-message-body{background:var(--auto-muted);color:var(--auto-secondary);border:1px solid var(--auto-border);border-radius:9999px;padding:.25rem .75rem;font-size:.8125em}.auto-chat .auto-chat-message[data-role=tool]{width:100%;font-size:.875em}.auto-chat .auto-chat-message[data-role=tool] .auto-chat-message-body{background:var(--auto-muted);color:var(--auto-secondary);border:1px solid var(--auto-border);border-left:3px solid var(--auto-secondary);border-radius:.25rem;padding:.5rem .75rem}.auto-chat .auto-chat-message[data-role=error]{width:100%}.auto-chat .auto-chat-message[data-role=error] .auto-chat-avatar{background:color-mix(in srgb, var(--auto-danger) 15%, transparent);color:var(--auto-danger);border-color:var(--auto-danger)}.auto-chat .auto-chat-message[data-role=error] .auto-chat-message-meta strong{color:var(--auto-danger)}.auto-chat .auto-chat-message[data-role=error] .auto-chat-message-body{background:color-mix(in srgb, var(--auto-danger) 8%, transparent);color:var(--auto-danger);border:1px solid var(--auto-danger);border-radius:.375rem;padding:.5rem .75rem}.auto-chat .auto-chat-status{color:var(--auto-secondary);flex-shrink:0;align-items:center;gap:.375rem;padding:.25rem 1rem;font-size:.8125em;display:flex}.auto-chat form.auto-chat-composer{padding:var(--auto-chat-pad);border-top:1px solid var(--auto-border);background:var(--auto-bg);flex-direction:column;flex-shrink:0;gap:.5rem;display:flex}.auto-chat form.auto-chat-composer textarea{width:100%;min-width:0;font-family:inherit;font-size:inherit;color:var(--auto-text);background:var(--auto-bg);border:1px solid var(--auto-border);resize:vertical;border-radius:.375rem;outline:none;min-height:4.5rem;padding:.5rem .75rem;line-height:1.4}.auto-chat form.auto-chat-composer textarea:focus{border-color:var(--auto-accent);box-shadow:0 0 0 2px color-mix(in srgb, var(--auto-accent) 25%, transparent)}.auto-chat form.auto-chat-composer textarea::placeholder{color:var(--auto-secondary);opacity:.75}.auto-chat .auto-error{color:var(--auto-danger);background:color-mix(in srgb, var(--auto-danger) 10%, transparent);border:1px solid var(--auto-danger);border-radius:.25rem;align-items:center;gap:.375rem;padding:.375rem .625rem;font-size:.8125em;display:flex}.auto-chat .auto-chat-composer-actions{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:.5rem;display:flex}.auto-chat .auto-chat-composer-actions>div:first-child{flex-wrap:wrap;align-items:center;gap:.375rem;display:flex}.auto-root.auto-chat .auto-chat-composer-actions>div:first-child button{color:var(--auto-secondary);border:1px solid var(--auto-border);cursor:pointer;background:0 0;border-radius:.25rem;padding:.35rem .625rem}.auto-root.auto-chat .auto-chat-composer-actions>div:first-child button:hover{background:var(--auto-muted);color:var(--auto-text)}.auto-root.auto-chat .auto-chat-composer-actions>button{background:var(--auto-accent);color:var(--auto-bg);border:1px solid var(--auto-accent);cursor:pointer;border-radius:.25rem;justify-content:center;align-items:center;gap:.375rem;margin-left:auto;padding:.35rem .875rem;font-weight:500;display:inline-flex}.auto-root.auto-chat .auto-chat-composer-actions>button:hover{opacity:.9}.auto-root.auto-chat .auto-chat-composer-actions>button:active{transform:scale(.98)}.auto-root.auto-chat .auto-chat-composer-actions>button[data-action=stop],.auto-root.auto-chat .auto-chat-composer-actions>button.auto-chat-stop{background:var(--auto-danger);border-color:var(--auto-danger);color:var(--auto-bg)}.auto-root.auto-chat .auto-chat-composer-actions>button:disabled{opacity:.45;cursor:not-allowed}.auto-chat .auto-chat-footer{color:var(--auto-secondary);text-align:center;border-top:1px solid var(--auto-border);flex-shrink:0;padding:.375rem 1rem;font-size:.75rem}.auto-chat .auto-chat-header:empty,.auto-chat .auto-chat-empty:empty,.auto-chat .auto-chat-status:empty,.auto-chat .auto-error:empty,.auto-chat .auto-chat-footer:empty{display:none}.auto-root.auto-chat button:focus-visible,.auto-chat textarea:focus-visible{outline:2px solid var(--auto-accent);outline-offset:2px}@media (width<=480px){.auto-chat{border-left:none;border-right:none;border-radius:0}.auto-chat .auto-chat-message[data-role=user]{max-width:92%}}.auto-chat[data-message-layout=left] .auto-chat-message,.auto-chat[data-message-layout=left] .auto-chat-message[data-role]{flex-direction:row;justify-content:flex-start;align-self:flex-start;width:fit-content;max-width:100%;margin-left:0;margin-right:auto}.auto-chat[data-message-layout=left] .auto-chat-message .auto-chat-message-main,.auto-chat[data-message-layout=left] .auto-chat-message[data-role] .auto-chat-message-main{align-items:flex-start}.auto-chat[data-message-layout=left] .auto-chat-message .auto-chat-message-meta,.auto-chat[data-message-layout=left] .auto-chat-message[data-role] .auto-chat-message-meta{text-align:left;justify-content:flex-start}.auto-chat[data-message-layout=left] .auto-chat-message .auto-chat-message-actions,.auto-chat[data-message-layout=left] .auto-chat-message[data-role] .auto-chat-message-actions{justify-content:flex-start}.auto-chat[data-message-layout=left] .auto-chat-message .auto-chat-message-body,.auto-chat[data-message-layout=left] .auto-chat-message[data-role] .auto-chat-message-body{text-align:left;min-width:0;max-width:100%}.auto-chat[data-message-layout=left] .auto-chat-message[data-role=user] .auto-chat-message-body{border-radius:.25rem .75rem .75rem}.auto-chat[data-message-layout=right] .auto-chat-message,.auto-chat[data-message-layout=right] .auto-chat-message[data-role]{flex-direction:row-reverse;justify-content:flex-start;align-self:flex-end;width:fit-content;max-width:100%;margin-left:auto;margin-right:0}.auto-chat[data-message-layout=right] .auto-chat-message .auto-chat-message-main,.auto-chat[data-message-layout=right] .auto-chat-message[data-role] .auto-chat-message-main{align-items:flex-end}.auto-chat[data-message-layout=right] .auto-chat-message .auto-chat-message-meta,.auto-chat[data-message-layout=right] .auto-chat-message[data-role] .auto-chat-message-meta{text-align:right;justify-content:flex-end}.auto-chat[data-message-layout=right] .auto-chat-message .auto-chat-message-actions,.auto-chat[data-message-layout=right] .auto-chat-message[data-role] .auto-chat-message-actions{justify-content:flex-end}.auto-chat[data-message-layout=right] .auto-chat-message .auto-chat-message-body,.auto-chat[data-message-layout=right] .auto-chat-message[data-role] .auto-chat-message-body{text-align:left;min-width:0;max-width:100%}.auto-chat[data-message-layout=right] .auto-chat-message[data-role=user] .auto-chat-message-body,.auto-chat[data-message-layout=right] .auto-chat-message[data-role=assistant] .auto-chat-message-body,.auto-chat[data-message-layout=right] .auto-chat-message[data-role=tool] .auto-chat-message-body,.auto-chat[data-message-layout=right] .auto-chat-message[data-role=error] .auto-chat-message-body{border-radius:.75rem .25rem .75rem .75rem}.auto-chat[data-message-layout=full] .auto-chat-message,.auto-chat[data-message-layout=full] .auto-chat-message[data-role]{flex-direction:row;justify-content:flex-start;align-self:stretch;width:100%;max-width:100%;margin-left:0;margin-right:0}.auto-chat[data-message-layout=full] .auto-chat-message .auto-chat-message-main,.auto-chat[data-message-layout=full] .auto-chat-message[data-role] .auto-chat-message-main{flex:auto;align-items:stretch;width:100%}.auto-chat[data-message-layout=full] .auto-chat-message .auto-chat-message-meta,.auto-chat[data-message-layout=full] .auto-chat-message[data-role] .auto-chat-message-meta{text-align:left;justify-content:flex-start}.auto-chat[data-message-layout=full] .auto-chat-message .auto-chat-message-actions,.auto-chat[data-message-layout=full] .auto-chat-message[data-role] .auto-chat-message-actions{justify-content:flex-start}.auto-chat[data-message-layout=full] .auto-chat-message .auto-chat-message-body,.auto-chat[data-message-layout=full] .auto-chat-message[data-role] .auto-chat-message-body{text-align:left;width:100%;min-width:0;max-width:100%}.auto-chat[data-message-layout=full] .auto-chat-message[data-role=user] .auto-chat-message-body,.auto-chat[data-message-layout=full] .auto-chat-message[data-role=system] .auto-chat-message-body{border-radius:.375rem}
2
+ /*$vite$:1*/
package/dist/xlsx.js ADDED
@@ -0,0 +1,9 @@
1
+ //#region src/adapters/xlsx.ts
2
+ async function e(e, t) {
3
+ let { default: n } = await import("exceljs"), r = new n.Workbook(), i = r.addWorksheet(t.sheetName ?? "Data");
4
+ i.addRow(e.headers);
5
+ for (let t of e.rows) i.addRow(t.map((e) => e == null ? "" : typeof e == "object" ? JSON.stringify(e) : e));
6
+ return r.xlsx.writeBuffer();
7
+ }
8
+ //#endregion
9
+ export { e as exportXlsx };
@@ -0,0 +1,89 @@
1
+ # AutoChat
2
+
3
+ **English** | [简体中文](i18n/zh-CN/auto-chat.md) | [繁體中文](i18n/zh-TW/auto-chat.md) | [日本語](i18n/ja/auto-chat.md) | [한국어](i18n/ko/auto-chat.md) | [Español](i18n/es/auto-chat.md) | [Français](i18n/fr/auto-chat.md) | [Deutsch](i18n/de/auto-chat.md) | [Português (Brasil)](i18n/pt-BR/auto-chat.md) | [Русский](i18n/ru/auto-chat.md)
4
+
5
+ A conversation layout with an optional composer, streaming follow and earlier-history loading. AutoChat adds no runtime dependency. It does not make network requests, persist messages, parse Markdown, execute tool output or render raw HTML.
6
+
7
+ ## Usage
8
+
9
+ ```tsx
10
+ import { useState } from "react";
11
+ import { AutoChat, type AutoChatMessage } from "@zeroman.yang/react-auto-components";
12
+ import "@zeroman.yang/react-auto-components/style.css";
13
+
14
+ export function Conversation() {
15
+ const [messages, setMessages] = useState<AutoChatMessage[]>([]);
16
+ return (
17
+ <AutoChat
18
+ height={600}
19
+ messages={messages}
20
+ onSend={async (text) => {
21
+ setMessages((current) => [
22
+ ...current,
23
+ { id: crypto.randomUUID(), role: "user", content: text },
24
+ ]);
25
+ // Send to your service and update messages here.
26
+ }}
27
+ />
28
+ );
29
+ }
30
+ ```
31
+
32
+ ## Bring your own renderer
33
+
34
+ Pass React nodes as `content`, or extend `AutoChatMessage` with your application's fields and supply `renderMessage(message, { index })`. Connect an existing Markdown renderer, code viewer, attachment card or tool-result component there. AutoChat never interprets those formats; a plain string is rendered as text. The host renderer controls links, HTML and any interactive content.
35
+
36
+ Each message has a stable, unique `id` and a `role`: `user`, `assistant`, `system`, `tool`, or `error`. Optional `author`, `avatar`, `meta` and `streaming` customize its shell. `renderActions(message, context)` supplies message actions. Keep the same ID while updating a streamed reply, and replace the messages array immutably.
37
+
38
+ ## Behavior and props
39
+
40
+ | Prop | Behavior |
41
+ | --- | --- |
42
+ | `height` | CSS height, default `100%`. Give the parent a definite height, or pass a number such as `600`. History scrolls inside the component. |
43
+ | `autoFollow` | Defaults to `true`. Follow new and resized content at the bottom; pause when the reader scrolls up. **Back to latest** resumes following. |
44
+ | `hasMore`, `onLoadOlder`, `loadingOlder` | Show an earlier-history button. Prepend messages with stable IDs; the visible message stays anchored. Requests are deduplicated, and a rejected request can be retried. |
45
+ | `onSend(text)` | Enables the composer. Receives the original nonblank text; may return a promise. Accepting clears that draft; rejecting preserves it and displays a generic error. A newer draft is never cleared by an older send. |
46
+ | `value`, `defaultValue`, `onValueChange` | Controlled or local composer value. For a controlled value, apply changes in the host. |
47
+ | `generating`, `onStop` | Disable sends during generation and expose a stop button. The host must cancel its own stream/request and update `generating`. |
48
+ | `sendOnEnter` | Defaults to `true`; Shift+Enter inserts a newline. Composition events and IME confirmation never submit. Set to `false` for button-only sending. |
49
+ | `disabled`, `composer` | Disable the built-in editor or hide it (`composer={false}`) when using an external editor. |
50
+ | `conversationKey` | Reset local draft, pending UI and scroll when switching conversations. Controlled values and cancellation remain host-owned. |
51
+ | `header`, `footer`, `empty`, `composerExtra` | React content slots. |
52
+ | `messageLayout` | `"role"` (default) uses role-based alignment; `"left"` or `"right"` aligns every role to that side; `"full"` stretches each message across the available width. Works with virtual and ordinary histories. |
53
+ | `size`, `density` | Override the global `AutoConfigProvider` settings. |
54
+ | `labels` | Override built-in English labels. The provider also translates `chat.send`, `chat.latest`, and other `chat.*` keys. |
55
+ | `onSendError`, `onLoadError` | Receive the original error for application logging; internal error details are not displayed automatically. |
56
+
57
+ For large histories, set `virtual` to use the package's existing TanStack Virtual dependency. Only visible messages and a small overscan window mount; dynamic row heights are measured. Tune `estimatedMessageHeight` (default `120`) and `overscan` (default `6`) if needed. Keep message IDs stable when prepending history. In virtual mode, keep interactive message state in the host when it must survive rows unmounting outside the viewport. Ordinary conversations use the nonvirtual layout by default.
58
+
59
+ The **Large history** demo loads 1,000, 10,000 or 50,000 variable-height messages, reports the actual mounted message count, and supports appending 100 messages, streaming, loading older history and jumping to either end.
60
+
61
+ The `AutoChatHandle` ref exposes `scrollToBottom()`, `scrollToMessage(id)` (returns whether the ID exists), `focusComposer()` and `getScrollElement()`. The history uses a keyboard-focusable log; a separate status region announces send/generation state without announcing each streamed token.
62
+
63
+ See [the runnable demo](../test-project/src/examples/ChatDemo.tsx) for a local streaming simulation, cancellation, a custom tool card, pagination, send failure and ten-language UI.
64
+
65
+ ## Rich rendering in the demo
66
+
67
+ The private `test-project` installs [react-markdown](https://github.com/remarkjs/react-markdown) and [remark-gfm](https://github.com/remarkjs/remark-gfm). These dependencies are not part of the component library. Its format picker inserts Markdown (headings, emphasis, task lists and GFM tables), code, JSON, data tables, a local image, or an interactive React review card.
68
+
69
+ `ChatRenderers.tsx` chooses React components from structured message data. `ChatTaskCard.tsx` demonstrates local interaction state. Markdown uses `skipHtml` and the library's default URL handling; it does not compile JSX or run code fences. The same Markdown renderer displays streamed replies. Custom components are supplied by the application, not instantiated from executable message text.
70
+
71
+ ```tsx
72
+ import Markdown from "react-markdown";
73
+ import remarkGfm from "remark-gfm";
74
+
75
+ <AutoChat
76
+ messages={messages}
77
+ renderMessage={(message) => (
78
+ <Markdown remarkPlugins={[remarkGfm]} skipHtml>
79
+ {String(message.content ?? "")}
80
+ </Markdown>
81
+ )}
82
+ />
83
+ ```
84
+
85
+ ## Interactive test pages
86
+
87
+ The demo has six pages: Conversation, Large history, Rendering, Message layout, Hooks, and Edge states. Rendering covers mixed content, long tokens, wide code and tables, nested Markdown, Unicode/RTL, dynamic image/disclosure heights, partial streamed Markdown, and unsafe markup. Message layout compares all roles with optional avatars and virtualization.
88
+
89
+ Hooks records real `onValueChange`, `onSend`, `onSendError`, `onStop`, `onLoadOlder`, `onLoadError`, message actions and imperative handle calls in a bounded event log. Edge states provides empty, read-only, disabled, controlled, pending and failed-send scenarios. Its manual resolve/reject controls allow switching conversations while a request is pending to inspect draft isolation. These simulations use local data only.
@@ -0,0 +1,203 @@
1
+ # React Auto Components
2
+
3
+ [English](../../../README.md) | [简体中文](../zh-CN/README.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja/README.md) | [한국어](../ko/README.md) | [Español](../es/README.md) | [Français](../fr/README.md) | **Deutsch** | [Português (Brasil)](../pt-BR/README.md) | [Русский](../ru/README.md)
4
+
5
+ Eine eigenständige, schema-getriebene Komponentenbibliothek für React 19 – mit Formularen, Tabellen und Chat. Gebaut mit TypeScript, TanStack Table 9 / Form / Virtual, Radix und Floating UI, ohne Ant Design, Element Plus oder MUI. Die Library-Builds verwenden den React Compiler.
6
+
7
+ [![Auto Studio Demo-Vorschau](../../assets/demo.png)](https://zeroman.github.io/react-auto-components/)
8
+
9
+ <p align="center">
10
+ <a href="https://zeroman.github.io/react-auto-components/"><strong>🚀 Live-Demo (GitHub Pages)</strong></a> · <a href="#eigenständiges-testprojekt-starten">Lokal ausführen</a> · <a href="#komponenten">Komponenten</a>
11
+ </p>
12
+
13
+ ## Projektstatus
14
+
15
+ Die aktuelle Version ist 0.1.0, und die APIs können sich noch ändern. React 19 wird vorausgesetzt. Das Paket stellt ESM- und TypeScript-Deklarationen bereit. Der eingebaute Oberflächentext ist standardmäßig Chinesisch und kann über AutoConfigProvider.config.t übersetzt werden.
16
+
17
+ Installation mit `pnpm add @zeroman.yang/react-auto-components` (npm und yarn funktionieren ebenso). Peer Dependencies sind React 19 und react-dom 19. Importieren Sie das Stylesheet einmal: `import "@zeroman.yang/react-auto-components/style.css"`.
18
+
19
+ - [Live-Demo (GitHub Pages)](https://zeroman.github.io/react-auto-components/)
20
+ - [Mitwirken](https://github.com/Zeroman/react-auto-components/blob/main/docs/i18n/de/CONTRIBUTING.md)
21
+ - [Änderungsprotokoll](https://github.com/Zeroman/react-auto-components/blob/main/docs/i18n/de/CHANGELOG.md)
22
+ - [Kontoeinrichtung und Veröffentlichung](https://github.com/Zeroman/react-auto-components/blob/main/docs/i18n/de/publishing.md)
23
+ - [MIT-Lizenz](../../../LICENSE)
24
+
25
+ ## Eigenständiges Testprojekt starten
26
+
27
+ Erfordert Node.js >= 22.12 und pnpm 12.5.
28
+
29
+ ```sh
30
+ pnpm install --frozen-lockfile
31
+ pnpm prepare:test-project
32
+ pnpm --dir test-project dev
33
+ ```
34
+
35
+ Öffnen Sie http://127.0.0.1:4173. Das Testprojekt enthält Seiten für alle sieben Komponenten, lokale/serverseitige Tabellen, Tabellen mit 10.000 Zeilen und Baumtabellen, CRUD, erneute Versuche nach fehlgeschlagenem Absenden, Entwürfe, verschachtelte Tabs und dynamische Zeilenhöhen.
36
+
37
+ Die Demo erkennt die Browsersprache automatisch, mit Englisch als Rückfallebene. Wählen Sie eine Sprache über den Kopfbereich oder die globalen Einstellungen; die Auswahl bleibt über Neuladen hinweg erhalten. Wählen Sie „Auto“, um erneut der Browsersprache zu folgen. Zehn Sprachen werden unterstützt. Die Seiten füllen den Viewport aus; Tabellen und lange Panels scrollen innerhalb ihrer eigenen Bereiche.
38
+
39
+ Jede Beispielseite enthält eine Schaltfläche **Code anzeigen**, die die echte Quelldatei in einem Dialog öffnet – mit Datei-Tabs, Ein-Klick-Kopieren und GitHub-Link.
40
+
41
+ `test-project` hat eine eigene package.json und Lockdatei. Es installiert die tatsächliche Ausgabe von `pnpm pack`, ohne Quellcode-Aliase. Führen Sie nach Änderungen an der Bibliothek erneut `pnpm prepare:test-project` aus; das Skript verwendet Dateinamen mit Inhalts-Hash, um veraltete Tarball-Caches zu vermeiden.
42
+
43
+ ## Verwendung
44
+
45
+ ```tsx
46
+ import { useState } from 'react';
47
+ import {
48
+ AutoConfigProvider, AutoDialogProvider, AutoTable,
49
+ type AutoColumn, type Field,
50
+ } from '@zeroman.yang/react-auto-components';
51
+ import '@zeroman.yang/react-auto-components/style.css';
52
+
53
+ type Person = { id: number; name: string; enabled: boolean };
54
+ const columns: AutoColumn<Person>[] = [
55
+ { key: 'name', label: 'Name', sortable: true },
56
+ { key: 'enabled', label: 'Aktiviert', options: [
57
+ { label: 'Ja', value: true }, { label: 'Nein', value: false },
58
+ ] },
59
+ ];
60
+ const fields: Field<Person>[] = [
61
+ { name: 'name', label: 'Name', required: true },
62
+ { name: 'enabled', label: 'Aktiviert', type: 'switch', defaultValue: true },
63
+ ];
64
+ export function App() {
65
+ const [rows, setRows] = useState<Person[]>([]);
66
+ return <AutoConfigProvider config={{ namespace: 'my-app' }}>
67
+ <AutoDialogProvider>
68
+ <AutoTable<Person> id="people" rowKey="id" data={rows}
69
+ columns={columns} formFields={fields} searchFields={fields}
70
+ onAdd={value => setRows(old => [...old, { ...value, id: Date.now() }])}
71
+ onEdit={(row, value) => setRows(old => old.map(item => item.id === row.id ? { ...row, ...value } : item))}
72
+ onDelete={selected => setRows(old => old.filter(item => !selected.some(row => row.id === item.id)))}
73
+ />
74
+ </AutoDialogProvider>
75
+ </AutoConfigProvider>;
76
+ }
77
+ ```
78
+
79
+ Felder, Spalten und Refs verwenden Generics: Ungültige Feldnamen oder Standardwerte führen zu Fehlern zur Kompilierzeit. Der Provider unterstützt Namensräume, Berechtigungen, die Übersetzung von Feldbeschriftungen, benutzerdefinierte Felder, Benachrichtigungen und Persistenzadapter. Eingebaute Beschriftungen, Validierungsmeldungen und Texte für Barrierefreiheit verwenden AutoConfigProvider.config.t; explizit angegebene Komponentenbeschriftungen haben Vorrang.
80
+
81
+ Der t-Callback erhält einen Nachrichtenschlüssel und einen Fallback-Text. Nummerierte Platzhalter wie {0} und {1} müssen in übersetzten eingebauten Meldungen erhalten bleiben; die Komponenten setzen ihre Werte erst nach der Übersetzung ein.
82
+
83
+ ## Komponenten
84
+
85
+ | Komponente | Funktionen |
86
+ | --- | --- |
87
+ | AutoForm | Native Feldtypen, virtualisierte Optionen, kaskadierende Auswahl, Upload-Adapter, benutzerdefinierte Darstellung, abhängige Felder, bedingte Sichtbarkeit, asynchrone Validierung, kontrollierter Zustand, Erhalt von Eingaben nach Fehlern |
88
+ | AutoSearchPanel | Einfache/erweiterte Bedingungen, manuelle/sofortige Suche, Zurücksetzen, Sortier-Tags, gemeinsamer Abfrage-AST und RSQL-Serialisierung |
89
+ | AutoTable | Lokale/entfernte Daten, Mehrspaltensortierung, Spaltenfilter, Paginierung, stabile Auswahl, Virtualisierung, Aufklappen von Bäumen/Details, Zusammenfassungen, verbundene Zellen, CRUD, Kontextmenüs und Kopieren |
90
+ | AutoDialog | Deklarative/imperative APIs, isolierte Provider, Entwürfe, Schließschutz, Fokusverwaltung, Ziehen, Vollbild und asynchrones Absenden |
91
+ | AutoTabs | Horizontale/vertikale Layouts, Verschachtelung, Berechtigungen, deaktivierte Tabs, Erhalt des Panelzustands und Aktualisierung |
92
+ | AutoMenu | Seitennavigation mit Icons, Beschreibungen, Badges, verschachtelten Gruppen, Berechtigungen und einklappbarer Icon-Leiste |
93
+ | AutoChat | Vom Aufrufer kontrolliertes Nachrichten-Rendering, optionale Virtualisierung, Streaming-Follow, verankertes Nachladen des Verlaufs, Sende/Stopp-Composer und benutzerdefinierte Aktionen |
94
+
95
+ Tabellenlayout, Sortierung, Filterung und Export unterstützen jeweils benannte Voreinstellungen und unabhängige Versionen. Standardmäßig wird localStorage für die Persistenz verwendet; entfernte Adapter können eingebunden werden. JSON/CSV-Export ist integriert. XLSX verwendet einen optionalen, separaten Adapter:
96
+
97
+ ```tsx
98
+ import { exportXlsx } from '@zeroman.yang/react-auto-components/xlsx';
99
+ // <AutoTable ... exportXlsx={exportXlsx} />
100
+ ```
101
+
102
+ ExcelJS wird beim ersten Einsatz des Adapters dynamisch geladen und ist nicht im Haupteinstiegspunkt der Bibliothek enthalten. Anwendungen, die nur CSV/JSON verwenden, können optionale Abhängigkeiten bei der Installation auslassen.
103
+
104
+ ## Überprüfung
105
+
106
+ ```sh
107
+ pnpm typecheck
108
+ pnpm test
109
+ pnpm build
110
+ pnpm prepare:test-project
111
+ pnpm --dir test-project build
112
+ pnpm exec playwright install chromium # Nur beim ersten Ausführen
113
+ pnpm test:e2e
114
+ ```
115
+
116
+ Unit-Tests decken Felder, asynchrone Validierung, Abfragen, Dialoge, Virtualisierung, Tabellen, Konfigurationsmigrationen und Exporte ab. Playwright testet Interaktionen über die öffentlichen Einstiegspunkte des Pakets. Desktop-/Mobil-Screenshots werden in `test-project/test-results` gespeichert.
117
+
118
+ ## Verhalten und Konventionen
119
+
120
+ - Dies ist eine für React entwickelte API, keine Kompatibilitätsschicht, die Vue Eigenschaft für Eigenschaft oder Methode für Methode nachbildet. Siehe [Migrationsanleitung](migration.md).
121
+ - Der Anwendungscode verwaltet die Daten. CRUD-Callbacks speichern Änderungen; das Auslösen eines Fehlers bei einem Fehlschlag erhält die Bearbeitungen. Nach Erfolg aktualisiert die Komponente entfernte Daten. Lokale Daten muss der Aufrufer aktualisieren.
122
+ - Die `id` einer Tabelle muss innerhalb ihres Namensraums eindeutig sein; `rowKey` muss über alle Seiten und Baumknoten hinweg eindeutig sein. Geben Sie im serverseitigen Modus `columns` explizit an; die Datenquelle liefert die Gesamtanzahl zurück.
123
+ - Wenn `query` / `value` kontrolliert wird, muss die übergeordnete Komponente die Callbacks verarbeiten und den Wert aktualisieren. Für unkontrollierte Verwendung können diese Props entfallen.
124
+ - Verbundene Zellen verwenden eine nicht virtualisierte semantische Tabelle, die sich für paginierte Daten eignet, um rowSpan-Versatz zwischen virtuellen Ausschnitten zu vermeiden.
125
+ - Serverseitige Zusammenfassungen aller gefilterten Zeilen werden über `summaryValues` bereitgestellt. Fehlende Zusammenfassungen zeigen `—`, statt die Summe der aktuellen Seite als Gesamtsumme auszugeben. Setzen Sie `summaryScope="page"`, um ausdrücklich die aktuelle Seite zu berechnen.
126
+ - Während Uploads läuft kein Absenden. Zurücksetzen, Ersetzen von Feldwerten oder Unmounten bricht alte Uploads ab; verspätete Ergebnisse können neuere Werte nicht überschreiben.
127
+ - Entfernte Exporte aller gefilterten Ergebnisse rufen die Daten seitenweise ab. Große Anwendungen können einen eigenen serverseitigen Export implementieren.
128
+ - Importieren Sie Browser-Stile ausdrücklich aus `style.css`. JavaScript-Module lassen sich in Node ohne `window` importieren.
129
+
130
+ ## Mit AutoTable die verbleibende Höhe ausfüllen
131
+
132
+ `height={440}` legt weiterhin eine feste Höhe für den Daten-Scrollbereich fest. Mit `height="auto"` füllt die gesamte Tabelle die vom übergeordneten Layout zugewiesene Höhe aus. Suche, Werkzeugleiste und Paginierung nehmen ihre natürliche Höhe ein; der Datenbereich nutzt den übrigen Platz und scrollt unabhängig:
133
+
134
+ ```tsx
135
+ <div style={{ height: '100dvh', display: 'flex', flexDirection: 'column', gap: 12 }}>
136
+ <header>Seitentitel und Beschreibung</header>
137
+ <AutoTable<Person> id="people" rowKey="id" data={rows}
138
+ columns={columns} height="auto" />
139
+ <footer>Seitenfußzeile</footer>
140
+ </div>
141
+ ```
142
+
143
+ Das übergeordnete Element muss eine bestimmte Höhe haben. Verwenden Sie `flex: 1; min-height: 0` in verschachtelten Flex-Containern, um den verbleibenden Platz weiterzugeben, oder `grid-template-rows: auto minmax(0, 1fr) auto` für Grid-Layouts. Eine JavaScript-Berechnung aus Viewport-Höhe minus Werkzeugleistenhöhe ist nicht erforderlich: Das Layout berücksichtigt hinzugefügte/entfernte Suchfelder, umgebrochene Werkzeugleisten und Größenänderungen des übergeordneten Elements; die virtuelle Liste folgt den tatsächlichen Abmessungen des Scrollbereichs.
144
+
145
+ Dabei wird die Tabellengröße nicht an die Zeilenanzahl angepasst. Leere und kleine Datensätze füllen weiterhin den verfügbaren Platz. Das übergeordnete Element muss mindestens Platz für Suchbereich, Werkzeugleiste und Paginierung selbst bieten.
146
+
147
+ Das Testprojekt zeigt dies im Tab **AutoTable → Verbleibende Höhe**, wobei Seitenleiste und Seitenkopf erhalten bleiben. Die ältere URL `http://127.0.0.1:4173/?demo=auto-height` wählt diesen Tab direkt aus. Browsertests: `test-project/tests/auto-height.spec.ts`.
148
+
149
+ ## Globales Formularlayout
150
+
151
+ Verwenden Sie `AutoConfigProvider.config.form`, um reguläre Formulare, Suchpanels, Tabellensuchbereiche und Dialogformulare einheitlich zu konfigurieren. Beschriftungen können über oder links neben Steuerelementen stehen, mit unabhängig davon links- oder rechtsbündigem Text. Standardmäßig stehen Beschriftungen oben und die Abstände sind großzügig.
152
+
153
+ ```tsx
154
+ <AutoConfigProvider config={{
155
+ form: {
156
+ labelPosition: 'left', // 'top': oberhalb; 'left': links neben dem Steuerelement
157
+ labelAlign: 'right', // Rechtsbündiger Text; das Label bleibt links neben dem Steuerelement
158
+ labelWidth: 80,
159
+ density: 'compact', // 'comfortable': mehr Abstand
160
+ },
161
+ }}>
162
+ <App />
163
+ </AutoConfigProvider>
164
+ ```
165
+
166
+ Verschachtelte Provider führen Layouteinstellungen Eigenschaft für Eigenschaft zusammen. Explizite Komponenten-Props überschreiben den umgebenden Provider. Beispielsweise können Sie in einem Formular Beschriftungen oben beibehalten und global Beschriftungen neben den Steuerelementen verwenden:
167
+
168
+ ```tsx
169
+ <AutoForm fields={fields} labelPosition="top" density="comfortable" />
170
+ <AutoTable id="people" rowKey="id" data={rows} columns={columns}
171
+ searchFields={searchFields}
172
+ searchLayout={{ labelWidth: 100, columns: 3 }} />
173
+ ```
174
+
175
+ `labelWidth` ist standardmäßig `"auto"` und akzeptiert auch eine Pixelzahl oder CSS-Breite wie `"6em"`. Im automatischen Modus passt sich jede Suchbeschriftung ihrem Text an; reguläre Formulare und Dialogformulare verwenden eine gemeinsame, aus sichtbaren Beschriftungen ermittelte Breite, um Steuerelemente auszurichten. Lange Beschriftungen belegen höchstens 45 % der Feldbreite und werden darüber hinaus umgebrochen, damit Platz für Steuerelemente bleibt. Explizite feste Breiten unterliegen dieser automatischen Begrenzung nicht. Kompakte Suchbereiche platzieren Aktionsschaltflächen bei ausreichendem Platz in derselben Zeile und umbrechen sie auf schmalen Bildschirmen. Beschriftungszuordnungen bleiben erhalten, Fehler und Beschreibungen werden an Steuerelementen ausgerichtet und lange Beschriftungen können umbrechen.
176
+
177
+ Öffnen Sie in der Demo **Globale Einstellungen** über die Seitenleiste oder das Zahnrad oben rechts, um Layout, Dichte, Beschriftungsbreite und Design zu ändern. Änderungen wirken sofort, ohne aktuelle Eingaben zu löschen. Die Formularseite unterstützt **Globalen Einstellungen folgen** oder lokale Überschreibungen. Die Demo aktiviert über ihren Provider ausdrücklich ein kompaktes Layout mit Beschriftungen neben den Steuerelementen.
178
+
179
+ ## Globale Größe und Dichte
180
+
181
+ `AutoConfigProvider` unterstützt `size: "small" | "medium" | "large"` und `density: "compact" | "comfortable"`. Explizite Komponenten-Props haben Vorrang vor Einstellungen der Komponentenkategorie; diese haben Vorrang vor globalen Werten:
182
+
183
+ ```tsx
184
+ <AutoConfigProvider config={{
185
+ size: "medium",
186
+ density: "compact",
187
+ form: { labelPosition: "left", labelAlign: "right" },
188
+ table: { density: "compact" },
189
+ tabs: { density: "compact" },
190
+ }}>
191
+ <AutoForm fields={fields} size="small" />
192
+ </AutoConfigProvider>
193
+ ```
194
+
195
+ Die Tabellendichte unterstützt außerdem `normal`. Das Tabelleneinstellungspanel folgt standardmäßig den globalen Einstellungen. Die Auswahl kompakter, normaler oder großzügiger Abstände überschreibt die globale Dichte und wird mit der Layoutvoreinstellung gespeichert; das `density`-Prop der Komponente hat die höchste Priorität. Lokale Größen verschachtelter Komponenten gelten unabhängig voneinander.
196
+
197
+ Formulare unterstützen `resetLabel`, `extraActions` und `onReset`; Suchpanels unterstützen `searchLabel`, `resetLabel` und `extraActions`; Dialoge unterstützen `cancelLabel` und `extraActions`. Einträge von `AutoTabs` können ein `badge` definieren; `AutoTable.empty` passt den Inhalt für einen leeren Zustand an.
198
+
199
+ ### AutoChat
200
+
201
+ AutoChat bietet ein leichtgewichtiges Unterhaltungs-Layout mit Stream-Follow, Verlaufsladen und einem Eingabebereich. Für das Rendern der Nachrichten übergibst du React-Inhalte oder renderMessage; zusätzliche Laufzeit-Abhängigkeiten sind nicht erforderlich.
202
+
203
+ [AutoChat API](auto-chat.md)
@@ -0,0 +1,82 @@
1
+ # AutoChat
2
+
3
+ [English](../../auto-chat.md) | [简体中文](../zh-CN/auto-chat.md) | [繁體中文](../zh-TW/auto-chat.md) | [日本語](../ja/auto-chat.md) | [한국어](../ko/auto-chat.md) | [Español](../es/auto-chat.md) | [Français](../fr/auto-chat.md) | **Deutsch** | [Português (Brasil)](../pt-BR/auto-chat.md) | [Русский](../ru/auto-chat.md)
4
+
5
+ Ein Konversationslayout mit optionalem Composer, Streaming-Follow und Laden älterer Verläufe. AutoChat fügt keine Laufzeitabhängigkeit hinzu und stellt keine Netzwerkanfragen, speichert keine Nachrichten, parst kein Markdown, führt keine Tool-Ausgaben aus und rendert kein rohes HTML.
6
+
7
+ ## Verwendung
8
+
9
+ ```tsx
10
+ import { useState } from "react";
11
+ import { AutoChat, type AutoChatMessage } from "@zeroman.yang/react-auto-components";
12
+ import "@zeroman.yang/react-auto-components/style.css";
13
+
14
+ export function Conversation() {
15
+ const [messages, setMessages] = useState<AutoChatMessage[]>([]);
16
+ return (
17
+ <AutoChat
18
+ height={600}
19
+ messages={messages}
20
+ onSend={async (text) => {
21
+ setMessages((current) => [
22
+ ...current,
23
+ { id: crypto.randomUUID(), role: "user", content: text },
24
+ ]);
25
+ // Rufen Sie hier Ihren Dienst auf und aktualisieren Sie messages.
26
+ }}
27
+ />
28
+ );
29
+ }
30
+ ```
31
+
32
+ ## Eigene Renderer mitbringen
33
+
34
+ Übergeben Sie React-Knoten als `content`, oder erweitern Sie `AutoChatMessage` um Felder Ihrer Anwendung und stellen Sie `renderMessage(message, { index })` bereit. Binden Sie dort einen bestehenden Markdown-Renderer, Code-Viewer, Anhangskarte oder Tool-Ergebnis-Komponente an. AutoChat interpretiert diese Formate nie; eine einfache Zeichenfolge wird als Text gerendert. Links, HTML und interaktive Inhalte steuert der Host-Renderer.
35
+
36
+ Jede Nachricht hat eine stabile, eindeutige `id` und eine `role`: `user`, `assistant`, `system`, `tool` oder `error`. Optionale Felder `author`, `avatar`, `meta` und `streaming` passen die Hülle an; `renderActions(message, context)` liefert Nachrichtenaktionen. Behalten Sie beim Aktualisieren einer Streaming-Antwort dieselbe ID und ersetzen Sie das messages-Array unveränderlich.
37
+
38
+ ## Verhalten und Props
39
+
40
+ | Prop | Verhalten |
41
+ | --- | --- |
42
+ | `height` | CSS-Höhe, Standard `100%`. Geben Sie dem Parent eine bestimmte Höhe oder übergeben Sie eine Zahl wie `600`. Der Verlauf scrollt innerhalb der Komponente. |
43
+ | `autoFollow` | Standard `true`. Folgt neuen und in der Größe veränderten Inhalten am unteren Rand; pausiert, wenn die Lesenden nach oben scrollen. **Zum Neuesten** setzt das Folgen fort. |
44
+ | `hasMore`, `onLoadOlder`, `loadingOlder` | Zeigen eine Schaltfläche für ältere Verläufe. Nachrichten werden mit stabilen IDs vorangestellt; die sichtbare Nachricht bleibt verankert. Anfragen werden dedupliziert, abgelehnte Anfragen können wiederholt werden. |
45
+ | `onSend(text)` | Aktiviert den Composer. Empfängt den ursprünglichen, nicht leeren Text; darf ein Promise zurückgeben. Bei Annahme wird der Entwurf geleert, bei Ablehnung bleibt er erhalten und ein generischer Fehler erscheint. Ein neuerer Entwurf wird nie durch ein älteres Senden geleert. |
46
+ | `value`, `defaultValue`, `onValueChange` | Gesteuerter oder lokaler Composer-Wert. Bei gesteuertem Wert wenden Sie Änderungen im Host an. |
47
+ | `generating`, `onStop` | Deaktiviert Senden während der Generierung und zeigt eine Stopp-Schaltfläche. Der Host muss eigenen Stream/Anfrage abbrechen und `generating` aktualisieren. |
48
+ | `sendOnEnter` | Standard `true`; Shift+Enter fügt einen Zeilenumbruch ein. Kompositionsereignisse und IME-Bestätigung senden nie. Auf `false` setzen für Senden nur per Schaltfläche. |
49
+ | `disabled`, `composer` | Deaktiviert den integrierten Editor oder blendet ihn aus (`composer={false}`), wenn ein externer Editor genutzt wird. |
50
+ | `conversationKey` | Setzt lokalen Entwurf, ausstehende UI und Scroll beim Wechsel der Konversation zurück. Gesteuerte Werte und Abbruch bleiben beim Host. |
51
+ | `header`, `footer`, `empty`, `composerExtra` | React-Inhaltsslots. |
52
+ | `size`, `density` | Überschreiben die globalen `AutoConfigProvider`-Einstellungen. |
53
+ | `labels` | Überschreiben die eingebauten englischen Beschriftungen. Der Provider übersetzt auch `chat.send`, `chat.latest` und weitere `chat.*`-Schlüssel. |
54
+ | `onSendError`, `onLoadError` | Empfangen den ursprünglichen Fehler für Anwendungs-Logging; interne Fehlerdetails werden nicht automatisch angezeigt. |
55
+
56
+ Für große Verläufe aktivieren Sie `virtual`, um die bereits vorhandene TanStack-Virtual-Abhängigkeit des Pakets zu nutzen. Es werden nur sichtbare Nachrichten und ein kleines Overscan-Fenster eingebaut; dynamische Zeilenhöhen werden gemessen. Passen Sie bei Bedarf `estimatedMessageHeight` (Standard `120`) und `overscan` (Standard `6`) an. Behalten Sie beim Voranstellen von Verlauf stabile Nachrichten-IDs. Halten Sie im virtuellen Modus interaktiven Zustand, der außerhalb des Viewports unmontierte Zeilen überdauern muss, im Host. Normale Konversationen nutzen standardmäßig das nichtvirtuelle Layout.
57
+
58
+ Die Demo **Großer Verlauf** lädt 1.000, 10.000 oder 50.000 Meldungen variabler Höhe, meldet die tatsächlich eingebauten Nachrichten und unterstützt das Anhängen von 100 Nachrichten, Streaming, das Laden älterer Verläufe und das Springen an beide Enden.
59
+
60
+ Das `AutoChatHandle`-Ref legt `scrollToBottom()`, `scrollToMessage(id)` (gibt an, ob die ID existiert), `focusComposer()` und `getScrollElement()` offen. Der Verlauf ist ein mit der Tastatur fokussierbares Log; ein getrennter Statusbereich kündigt Sende-/Generierungszustand an, ohne jeden Streaming-Token zu melden.
61
+
62
+ Siehe [die ausführbare Demo](../../../test-project/src/examples/ChatDemo.tsx) für lokale Streaming-Simulation, Abbruch, eine benutzerdefinierte Tool-Karte, Pagination, Sendefehler und eine Oberfläche in zehn Sprachen.
63
+
64
+ ## Reichhaltiges Rendering in der Demo
65
+
66
+ Das private `test-project` installiert [react-markdown](https://github.com/remarkjs/react-markdown) und [remark-gfm](https://github.com/remarkjs/remark-gfm). Diese Abhängigkeiten gehören nicht zur Komponentenbibliothek. Dessen Formatauswahl fügt Markdown (Überschriften, Hervorhebungen, Aufgabenlisten und GFM-Tabellen), Code, JSON, Datentabellen, ein lokales Bild oder eine interaktive React-Review-Karte ein.
67
+
68
+ `ChatRenderers.tsx` wählt React-Komponenten aus strukturierten Nachrichtendaten. `ChatTaskCard.tsx` demonstriert lokalen Interaktionszustand. Markdown nutzt `skipHtml` und die Standard-URL-Behandlung der Bibliothek; es kompiliert kein JSX und führt keine Code-Blöcke aus. Derselbe Markdown-Renderer zeigt Streaming-Antworten. Benutzerdefinierte Komponenten stellt die Anwendung bereit; sie werden nicht aus ausführbarem Nachrichtentext instanziiert.
69
+
70
+ ```tsx
71
+ import Markdown from "react-markdown";
72
+ import remarkGfm from "remark-gfm";
73
+
74
+ <AutoChat
75
+ messages={messages}
76
+ renderMessage={(message) => (
77
+ <Markdown remarkPlugins={[remarkGfm]} skipHtml>
78
+ {String(message.content ?? "")}
79
+ </Markdown>
80
+ )}
81
+ />
82
+ ```
@@ -0,0 +1,71 @@
1
+ # Leitfaden zur Komponentenintegration
2
+
3
+ [English](../../migration.md) | [简体中文](../zh-CN/migration.md) | [繁體中文](../zh-TW/migration.md) | [日本語](../ja/migration.md) | [한국어](../ko/migration.md) | [Español](../es/migration.md) | [Français](../fr/migration.md) | **Deutsch** | [Português (Brasil)](../pt-BR/migration.md) | [Русский](../ru/migration.md)
4
+
5
+ Konfigurieren Sie Komponenten über React-Generics, Callbacks und Provider. Die folgende Tabelle ordnet häufige Anwendungsanforderungen den öffentlichen APIs und lauffähigen Beispielen zu.
6
+
7
+ | Ursprünglicher Anwendungsfall | React-API | Ausführbares Beispiel / Test |
8
+ | --- | --- | --- |
9
+ | Formularfelder und v-model | `fields: Field<T>[]`, `value/onChange` oder `defaultValue` | Formularseite in `test-project/src/examples/FormDemo.tsx`; `tests/form*.test.tsx` |
10
+ | Slots und angehängte Inhalte | Feld-`render`, Spalten-`render/header`, ReactNode | Formular-/Tabellenseiten |
11
+ | Operationen der Formularinstanz | `ref.validate/reset/getValues/setValue/focus` | `tests/form.test.tsx` |
12
+ | Suche, verknüpfte Bedingungen, RSQL | `buildQuery`, `matchesQuery`, `serializeRsql` | Suchseite; `tests/query.test.ts` |
13
+ | Lokale/entfernte Tabellendaten | Entweder `data` oder `dataSource(query,{signal})` | Tabellenseite; `tests/table.test.tsx` |
14
+ | Layout-/Filter-/Sortier-/Exportvoreinstellungen | Unabhängige Voreinstellungen im Einstellungsdialog, separat durch `versions` ungültig gemacht | Tabellenseite; `tests/table-settings.test.ts` |
15
+ | Bäume, Details, Zusammenfassungen, verbundene Zellen | `getChildren/renderExpanded`, Spalten-`summary/merge` | Baum- und Aufklappbeispiele; `tests/table-advanced.test.tsx` |
16
+ | Hinzufügen, Bearbeiten, Löschen | `formFields` und `onAdd/onEdit/onDelete` | CRUD-Browsertests |
17
+ | Imperative Dialoge | `AutoDialogProvider` + `useAutoDialog().open()` | Dialogseite; `tests/dialog.test.tsx` |
18
+ | Tabs und verschachtelte Tabs | `AutoTabs`-Einträge, value/onChange, keepMounted | Tab-Seite; `tests/tabs.test.tsx` |
19
+ | Chat-Nachrichtenlisten und Konversations-UI | `AutoChat`, `messages`, `onSend`, `renderMessage` | Chat-Seiten in `test-project/src/examples/Chat*.tsx`; `tests/chat.test.tsx` |
20
+
21
+ ## Feldtypen
22
+
23
+ `input/email/textarea/integer/float/percentage/progress/switch/select/select-v2/radio/checkbox/cascader/autocomplete/date/datetime/daterange/datetimerange/upload/text/title/tip/button/append/custom`.
24
+
25
+ `select-v2` virtualisiert Optionen. Datumsbereiche verwenden zwei native Eingabefelder mit getrennten Beschriftungen; `dateValue` wählt Zeichenfolgen oder Zeitstempel. Numerische Eingaben erlauben Zwischenzustände während der Bearbeitung; verwenden Sie Feldregeln, um fachliche Einschränkungen beim Absenden zu validieren. `rules` unterstützt asynchrone Validierung; ausgeblendete Felder überspringen die Validierung. Optionen behalten numerische/boolesche Werte bei, statt sie in Zeichenfolgen umzuwandeln.
26
+
27
+ ```tsx
28
+ const fields: Field<User>[] = [
29
+ { name: 'name', label: 'Name', required: true },
30
+ { name: 'note', label: 'Notiz', hidden: values => !values.enabled,
31
+ render: ({ value, onChange, disabled }) =>
32
+ <textarea disabled={disabled} value={String(value ?? '')}
33
+ onChange={event => onChange(event.target.value)} /> },
34
+ ];
35
+ ```
36
+
37
+ Die vollständige API finden Sie in den exportierten TypeScript-Typen. `Field<T>` bindet an tatsächliche Schlüssel von T; Strukturelemente wie Titel und Hinweise benötigen keine Dateneigenschaft.
38
+
39
+ ## Serverseitige Datenquellen
40
+
41
+ ```tsx
42
+ const dataSource: DataSource<User> = async (query, { signal }) => {
43
+ const response = await fetch('/api/users/search', {
44
+ method: 'POST', signal,
45
+ headers: { 'Content-Type': 'application/json' },
46
+ body: JSON.stringify(query),
47
+ });
48
+ if (!response.ok) throw new Error('Laden fehlgeschlagen');
49
+ return response.json(); // { rows: User[], total: number }
50
+ };
51
+ ```
52
+
53
+ Seitenindizes beginnen bei 0. `sort` ist ein geordnetes Array von Feldern; `filter` ist ein strukturierter Abfragebaum. Komponenten brechen alte Anfragen ab und verhindern, dass verspätete Antworten neuere Abfragen überschreiben. Rufen Sie `ref.refresh()` der Tabelle auf, wenn sich fachliche Bedingungen außerhalb der Closure der Datenquelle ändern. Halten Sie die Datenquellenfunktion stabil, um unnötige Anfragen zu vermeiden. Die RSQL-Serialisierung ist lediglich ein Adapter für Backends, die sie benötigen; sie führt keine Abfragezeichenfolgen aus.
54
+
55
+ ## Uploads und Persistenz der Anwendung
56
+
57
+ `upload(files, signal)` eines Feldes gibt den Feldwert zurück, nachdem die Anwendung die Dateien gespeichert hat. Die Komponente zeigt Upload-Fehler an; Aufrufer stellen Upload-URLs, Authentifizierung und Richtlinien für Objektspeicher bereit.
58
+
59
+ ```tsx
60
+ <AutoConfigProvider config={{
61
+ namespace: 'tenant-admin',
62
+ canAccess: access => !access.permissions?.length || access.permissions.every(p => myPermissions.includes(p)),
63
+ settings: {
64
+ load: key => api.loadTableSettings(key),
65
+ save: (key, settings) => api.saveTableSettings(key, settings),
66
+ },
67
+ notify: (message, level) => showToast(message, level),
68
+ }}>{children}</AutoConfigProvider>
69
+ ```
70
+
71
+ Lokale Änderungen werden sofort angewendet; entfernte Speicherungen laufen nacheinander ab, mit einer Wiederholungsoption nach Fehlern. Verwenden Sie beim Ändern gespeicherter Einstellungsformate eine neue Tabellen-ID oder Version, um das Laden inkompatibler Einstellungen zu vermeiden.