@joplo-app/plugin-ui 0.0.0-stage → 0.3.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.
- package/LICENSE +97 -0
- package/dist/catalog.d.ts +30 -0
- package/dist/catalog.js +255 -0
- package/dist/components.d.ts +150 -0
- package/dist/components.js +129 -0
- package/dist/guide.d.ts +3 -0
- package/dist/guide.js +182 -0
- package/dist/plugin.d.ts +5 -0
- package/dist/plugin.js +66 -0
- package/dist/runtime.d.ts +67 -0
- package/dist/runtime.js +1447 -0
- package/dist/story-data.d.ts +20 -0
- package/dist/story-data.js +46 -0
- package/dist/version.json +3 -0
- package/package.json +50 -3
- package/README.md +0 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Required Notice: Copyright 2026 Joplo-app (https://joplo.app, support@joplo.app)
|
|
2
|
+
|
|
3
|
+
Licensor Line of Business: Joplo, a tool for authoring, previewing, reviewing, and publishing interactive product prototypes, demos, and presentations (https://joplo.app)
|
|
4
|
+
Licensor Line of Business: Joplo Cloud, a service for hosting, sharing, commenting on, reviewing, and measuring Joplo prototypes and presentations (https://joplo.app)
|
|
5
|
+
|
|
6
|
+
What counts as competing, and how to ask about other uses: see COMMERCIAL.md
|
|
7
|
+
https://github.com/Joplo-app/Joplo/blob/main/COMMERCIAL.md
|
|
8
|
+
|
|
9
|
+
# PolyForm Shield License 1.0.0
|
|
10
|
+
|
|
11
|
+
<https://polyformproject.org/licenses/shield/1.0.0>
|
|
12
|
+
|
|
13
|
+
## Acceptance
|
|
14
|
+
|
|
15
|
+
In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
|
|
16
|
+
|
|
17
|
+
## Copyright License
|
|
18
|
+
|
|
19
|
+
The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license).
|
|
20
|
+
|
|
21
|
+
## Distribution License
|
|
22
|
+
|
|
23
|
+
The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license).
|
|
24
|
+
|
|
25
|
+
## Notices
|
|
26
|
+
|
|
27
|
+
You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software. For example:
|
|
28
|
+
|
|
29
|
+
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
30
|
+
|
|
31
|
+
## Changes and New Works License
|
|
32
|
+
|
|
33
|
+
The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
|
|
34
|
+
|
|
35
|
+
## Patent License
|
|
36
|
+
|
|
37
|
+
The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
|
|
38
|
+
|
|
39
|
+
## Noncompete
|
|
40
|
+
|
|
41
|
+
Any purpose is a permitted purpose, except for providing any product that competes with the software or any product the licensor or any of its affiliates provides using the software.
|
|
42
|
+
|
|
43
|
+
## Competition
|
|
44
|
+
|
|
45
|
+
Goods and services compete even when they provide functionality through different kinds of interfaces or for different technical platforms. Applications can compete with services, libraries with plugins, frameworks with development tools, and so on, even if they're written in different programming languages or for different computer architectures. Goods and services compete even when provided free of charge. If you market a product as a practical substitute for the software or another product, it definitely competes.
|
|
46
|
+
|
|
47
|
+
## New Products
|
|
48
|
+
|
|
49
|
+
If you are using the software to provide a product that does not compete, but the licensor or any of its affiliates brings your product into competition by providing a new version of the software or another product using the software, you may continue using versions of the software available under these terms beforehand to provide your competing product, but not any later versions.
|
|
50
|
+
|
|
51
|
+
## Discontinued Products
|
|
52
|
+
|
|
53
|
+
You may begin using the software to compete with a product or service that the licensor or any of its affiliates has stopped providing, unless the licensor includes a plain-text line beginning with `Licensor Line of Business:` with the software that mentions that line of business. For example:
|
|
54
|
+
|
|
55
|
+
> Licensor Line of Business: YoyodyneCMS Content Management System (http://example.com/cms)
|
|
56
|
+
|
|
57
|
+
## Sales of Business
|
|
58
|
+
|
|
59
|
+
If the licensor or any of its affiliates sells a line of business developing the software or using the software to provide a product, the buyer can also enforce [Noncompete](#noncompete) for that product.
|
|
60
|
+
|
|
61
|
+
## Fair Use
|
|
62
|
+
|
|
63
|
+
You may have "fair use" rights for the software under the law. These terms do not limit them.
|
|
64
|
+
|
|
65
|
+
## No Other Rights
|
|
66
|
+
|
|
67
|
+
These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
|
|
68
|
+
|
|
69
|
+
## Patent Defense
|
|
70
|
+
|
|
71
|
+
If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
|
|
72
|
+
|
|
73
|
+
## Violations
|
|
74
|
+
|
|
75
|
+
The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
|
|
76
|
+
|
|
77
|
+
## No Liability
|
|
78
|
+
|
|
79
|
+
***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.***
|
|
80
|
+
|
|
81
|
+
## Definitions
|
|
82
|
+
|
|
83
|
+
The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
|
|
84
|
+
|
|
85
|
+
A **product** can be a good or service, or a combination of them.
|
|
86
|
+
|
|
87
|
+
**You** refers to the individual or entity agreeing to these terms.
|
|
88
|
+
|
|
89
|
+
**Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all its affiliates.
|
|
90
|
+
|
|
91
|
+
**Affiliates** means the other organizations than an organization has control over, is under the control of, or is under common control with.
|
|
92
|
+
|
|
93
|
+
**Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
|
|
94
|
+
|
|
95
|
+
**Your licenses** are all the licenses granted to you for the software under these terms.
|
|
96
|
+
|
|
97
|
+
**Use** means anything you do with the software requiring one of your licenses.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 第一方 UI 组件目录(D35 / D87):名称与属性对齐 Mantine(数据表对齐 mantine-datatable),另加少量 AI 交互组件、
|
|
3
|
+
* HTML 兜底标签和 Joplo 专用组件。复合组件用点语法:`<AppShell.Header>` 编译出的节点 type 是 'ui:AppShell.Header'。
|
|
4
|
+
*
|
|
5
|
+
* 目录是唯一来源:@joplo-app/plugin-ui 的导出、同包 runtime 的实现、COMPONENT_DOCS 都必须与 COMPONENT_TYPES 一致
|
|
6
|
+
* (packages/core/test/catalog.test.ts 与渲染器的类型检查保证)。目录之外的名称在编译时报错,不会被静默渲染。
|
|
7
|
+
* 只换词汇,不换渲染:运行时不引入 Mantine,仍由 Joplo 渲染成低保真风格。
|
|
8
|
+
*/
|
|
9
|
+
export declare const HTML_TAGS: readonly string[];
|
|
10
|
+
export declare const COMPONENT_TYPES: readonly ["AppShell", "AppShell.Header", "AppShell.Navbar", "AppShell.Main", "AppShell.Aside", "AppShell.Footer", "Container", "Stack", "Group", "Flex", "Grid", "Grid.Col", "SimpleGrid", "Center", "Box", "Space", "Paper", "Card", "Card.Section", "Divider", "ScrollArea", "Title", "Text", "Code", "Kbd", "Blockquote", "List", "List.Item", "Badge", "Avatar", "Image", "ThemeIcon", "Indicator", "Timeline", "Timeline.Item", "Table", "Table.Thead", "Table.Tbody", "Table.Tr", "Table.Th", "Table.Td", "DataTable", "Accordion", "Accordion.Item", "Accordion.Panel", "Radio", "Tabs.List", "Tabs.Panel", "Breadcrumbs", "Stepper", "Stepper.Step", "Alert", "Loader", "Progress", "RingProgress", "Skeleton", "Notification", "Modal", "Drawer", "ChatMessage", "ToolCall", "Thinking", "Artifact", "Email", "DataCard", "StateFlow", "Terminal", "Terminal.Command", "Terminal.Output", "Phone", "Avatar.Group", "Radio.Card", "EmptyState", "ListRow", "Stat", "KeyValue", "BarChart", "LineChart", "Menu", "Menu.Target", "Menu.Dropdown", "Menu.Label", "Menu.Divider", "div", "span", "p", "h1", "h2", "h3", "h4", "main", "section", "header", "footer", "nav", "aside", "ul", "ol", "li", "strong", "em", "small", "code", "Placeholder", "Button", "ActionIcon", "CloseButton", "Anchor", "a", "NavLink", "Burger", "TextInput", "PasswordInput", "NumberInput", "Textarea", "Select", "MultiSelect", "Checkbox", "Radio.Group", "Switch", "SegmentedControl", "FileInput", "Tabs", "Tabs.Tab", "Accordion.Control", "Pagination", "PromptInput", "Terminal.Input", "Artifact.Ref", "Menu.Item", "TabBar"];
|
|
11
|
+
export type ComponentType = (typeof COMPONENT_TYPES)[number];
|
|
12
|
+
export declare const INTERACTIVE_TYPES: ReadonlySet<string>;
|
|
13
|
+
/** 可接收输入值;type/select/toggle 动作写入 state.inputs[nodeId]。 */
|
|
14
|
+
export declare const VALUE_TYPES: ReadonlySet<string>;
|
|
15
|
+
/**
|
|
16
|
+
* 只有 opened(兼容旧写法 open)为真时自身和子节点才可见的浮层。
|
|
17
|
+
* Menu.Dropdown(D68):作者把 opened 写在 Menu 上(与 Mantine 一致),编译器把它抄到菜单里的 Menu.Dropdown 上。
|
|
18
|
+
*/
|
|
19
|
+
export declare const GATED_CONTAINERS: ReadonlySet<string>;
|
|
20
|
+
/**
|
|
21
|
+
* 每个组件一行常用属性提示(`joplo skill components` 由此生成)。所有组件另外都接受:
|
|
22
|
+
* 样式属性 m/mt/mb/ml/mr/mx/my、p/pt/pb/pl/pr/px/py、w/h/miw/maw/mih/mah、c/bg/fz/fw/ta/ff/lh/opacity,
|
|
23
|
+
* 响应式写成 { base, xs, sm, md, lg, xl };visibleFrom / hiddenFrom;以及 Joplo 属性 id/when/disabled/disabledReason/unmodeled/note。
|
|
24
|
+
*/
|
|
25
|
+
export declare const COMPONENT_DOCS: Record<ComponentType, string>;
|
|
26
|
+
/**
|
|
27
|
+
* 示例(D68,`npx joplo components <名字>` 输出):每个都能直接放进页面或层级里用;交互状态写成 $.ui / $.data 绑定,由步骤 set()。
|
|
28
|
+
* 只给最容易写错、或需要和步骤配合的组件;其余组件看 COMPONENT_DOCS 的一行提示就够。
|
|
29
|
+
*/
|
|
30
|
+
export declare const COMPONENT_EXAMPLES: Partial<Record<ComponentType, string>>;
|
package/dist/catalog.js
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 第一方 UI 组件目录(D35 / D87):名称与属性对齐 Mantine(数据表对齐 mantine-datatable),另加少量 AI 交互组件、
|
|
3
|
+
* HTML 兜底标签和 Joplo 专用组件。复合组件用点语法:`<AppShell.Header>` 编译出的节点 type 是 'ui:AppShell.Header'。
|
|
4
|
+
*
|
|
5
|
+
* 目录是唯一来源:@joplo-app/plugin-ui 的导出、同包 runtime 的实现、COMPONENT_DOCS 都必须与 COMPONENT_TYPES 一致
|
|
6
|
+
* (packages/core/test/catalog.test.ts 与渲染器的类型检查保证)。目录之外的名称在编译时报错,不会被静默渲染。
|
|
7
|
+
* 只换词汇,不换渲染:运行时不引入 Mantine,仍由 Joplo 渲染成低保真风格。
|
|
8
|
+
*/
|
|
9
|
+
/** HTML 兜底标签(不可操作);`a` 在 INTERACTIVE 里。目录之外的标签(br、img、button、input…)报 UNKNOWN_COMPONENT。 */
|
|
10
|
+
const HTML = ['div', 'span', 'p', 'h1', 'h2', 'h3', 'h4', 'main', 'section', 'header', 'footer', 'nav', 'aside', 'ul', 'ol', 'li', 'strong', 'em', 'small', 'code'];
|
|
11
|
+
export const HTML_TAGS = [...HTML, 'a'];
|
|
12
|
+
/** 布局、展示与容器:不可操作。 */
|
|
13
|
+
const STRUCTURE = [
|
|
14
|
+
// 布局
|
|
15
|
+
'AppShell', 'AppShell.Header', 'AppShell.Navbar', 'AppShell.Main', 'AppShell.Aside', 'AppShell.Footer',
|
|
16
|
+
'Container', 'Stack', 'Group', 'Flex', 'Grid', 'Grid.Col', 'SimpleGrid', 'Center', 'Box', 'Space',
|
|
17
|
+
'Paper', 'Card', 'Card.Section', 'Divider', 'ScrollArea',
|
|
18
|
+
// 文字与展示
|
|
19
|
+
'Title', 'Text', 'Code', 'Kbd', 'Blockquote', 'List', 'List.Item', 'Badge', 'Avatar', 'Image', 'ThemeIcon', 'Indicator',
|
|
20
|
+
'Timeline', 'Timeline.Item',
|
|
21
|
+
'Table', 'Table.Thead', 'Table.Tbody', 'Table.Tr', 'Table.Th', 'Table.Td', 'DataTable',
|
|
22
|
+
'Accordion', 'Accordion.Item', 'Accordion.Panel',
|
|
23
|
+
'Radio',
|
|
24
|
+
// 导航
|
|
25
|
+
'Tabs.List', 'Tabs.Panel', 'Breadcrumbs', 'Stepper', 'Stepper.Step',
|
|
26
|
+
// 反馈与浮层
|
|
27
|
+
'Alert', 'Loader', 'Progress', 'RingProgress', 'Skeleton', 'Notification', 'Modal', 'Drawer',
|
|
28
|
+
// AI 交互(Joplo 自有)
|
|
29
|
+
'ChatMessage', 'ToolCall', 'Thinking', 'Artifact', 'Email', 'DataCard', 'StateFlow',
|
|
30
|
+
// 设备外框(Joplo 自有):终端与手机
|
|
31
|
+
'Terminal', 'Terminal.Command', 'Terminal.Output', 'Phone',
|
|
32
|
+
// 产品界面(D68):官网示例里反复手拼的常见界面,名字能对齐 Mantine 的就对齐(Menu、Avatar.Group、Radio.Card、BarChart、LineChart)
|
|
33
|
+
'Avatar.Group', 'Radio.Card', 'EmptyState', 'ListRow', 'Stat', 'KeyValue', 'BarChart', 'LineChart',
|
|
34
|
+
'Menu', 'Menu.Target', 'Menu.Dropdown', 'Menu.Label', 'Menu.Divider',
|
|
35
|
+
// HTML 兜底
|
|
36
|
+
...HTML,
|
|
37
|
+
// Joplo
|
|
38
|
+
'Placeholder', // props: label, h —— 图片/图表等占位
|
|
39
|
+
];
|
|
40
|
+
/** 看起来可操作:必须有演示行为、明确禁用并说明原因,或标记 unmodeled。 */
|
|
41
|
+
const INTERACTIVE = [
|
|
42
|
+
'Button', 'ActionIcon', 'CloseButton', 'Anchor', 'a', 'NavLink', 'Burger',
|
|
43
|
+
'TextInput', 'PasswordInput', 'NumberInput', 'Textarea', 'Select', 'MultiSelect', 'Checkbox', 'Radio.Group', 'Switch',
|
|
44
|
+
'SegmentedControl', 'FileInput', 'Tabs', 'Tabs.Tab', 'Accordion.Control', 'Pagination', 'PromptInput', 'Terminal.Input',
|
|
45
|
+
'Artifact.Ref',
|
|
46
|
+
// 产品界面(D68)
|
|
47
|
+
'Menu.Item', 'TabBar',
|
|
48
|
+
];
|
|
49
|
+
export const COMPONENT_TYPES = [...STRUCTURE, ...INTERACTIVE];
|
|
50
|
+
export const INTERACTIVE_TYPES = new Set(INTERACTIVE);
|
|
51
|
+
/** 可接收输入值;type/select/toggle 动作写入 state.inputs[nodeId]。 */
|
|
52
|
+
export const VALUE_TYPES = new Set([
|
|
53
|
+
'TextInput', 'PasswordInput', 'NumberInput', 'Textarea', 'Select', 'MultiSelect', 'Checkbox', 'Radio.Group', 'Switch',
|
|
54
|
+
'SegmentedControl', 'FileInput', 'Tabs', 'Accordion', 'Pagination', 'PromptInput', 'Terminal.Input', 'TabBar',
|
|
55
|
+
]);
|
|
56
|
+
/**
|
|
57
|
+
* 只有 opened(兼容旧写法 open)为真时自身和子节点才可见的浮层。
|
|
58
|
+
* Menu.Dropdown(D68):作者把 opened 写在 Menu 上(与 Mantine 一致),编译器把它抄到菜单里的 Menu.Dropdown 上。
|
|
59
|
+
*/
|
|
60
|
+
export const GATED_CONTAINERS = new Set(['Modal', 'Drawer', 'Menu.Dropdown']);
|
|
61
|
+
/**
|
|
62
|
+
* 每个组件一行常用属性提示(`joplo skill components` 由此生成)。所有组件另外都接受:
|
|
63
|
+
* 样式属性 m/mt/mb/ml/mr/mx/my、p/pt/pb/pl/pr/px/py、w/h/miw/maw/mih/mah、c/bg/fz/fw/ta/ff/lh/opacity,
|
|
64
|
+
* 响应式写成 { base, xs, sm, md, lg, xl };visibleFrom / hiddenFrom;以及 Joplo 属性 id/when/disabled/disabledReason/unmodeled/note。
|
|
65
|
+
*/
|
|
66
|
+
export const COMPONENT_DOCS = {
|
|
67
|
+
AppShell: 'header={{ height }}, navbar={{ width, breakpoint, collapsed: { mobile, desktop } }}, aside={{ width, breakpoint, collapsed }}, footer={{ height }}, padding; navigation collapses below breakpoint and shows Burger',
|
|
68
|
+
'AppShell.Header': 'Header; p, px',
|
|
69
|
+
'AppShell.Navbar': 'Navigation sidebar; p; contains NavLink',
|
|
70
|
+
'AppShell.Main': 'Main content; contains <Outlet />',
|
|
71
|
+
'AppShell.Aside': 'Right sidebar; p',
|
|
72
|
+
'AppShell.Footer': 'Footer; p',
|
|
73
|
+
Container: 'size: xs|sm|md|lg|xl|number (default md), fluid',
|
|
74
|
+
Stack: 'gap (default md), align, justify; vertical layout',
|
|
75
|
+
Group: 'gap (default md), justify, align (default center), wrap, grow; horizontal layout',
|
|
76
|
+
Flex: 'direction, gap, rowGap, columnGap, align, justify, wrap; all responsive',
|
|
77
|
+
Grid: 'columns (default 12), gutter, justify, align, grow; Grid.Col children',
|
|
78
|
+
'Grid.Col': 'span: number|"auto"|"content"|{ base, md }, offset',
|
|
79
|
+
SimpleGrid: 'cols={{ base: 1, md: 3 }}, spacing, verticalSpacing',
|
|
80
|
+
Center: 'inline; centers content',
|
|
81
|
+
Box: 'Generic container; style props only',
|
|
82
|
+
Space: 'h, w; blank space',
|
|
83
|
+
Paper: 'p, withBorder, shadow, radius',
|
|
84
|
+
Card: 'padding (default md), withBorder, shadow, radius; Card.Section for edge-to-edge sections',
|
|
85
|
+
'Card.Section': 'withBorder, inheritPadding',
|
|
86
|
+
Divider: 'label, labelPosition: left|center|right, orientation, my',
|
|
87
|
+
ScrollArea: 'h, mah',
|
|
88
|
+
Title: 'order: 1-6; text in children',
|
|
89
|
+
Text: 'size: xs|sm|md|lg|xl, c: dimmed|red|green|…, fw, ta, truncate, lineClamp, span; preserves newlines',
|
|
90
|
+
Code: 'block (multiline code block), color',
|
|
91
|
+
Kbd: 'Keyboard key',
|
|
92
|
+
Blockquote: 'cite, color',
|
|
93
|
+
List: 'type: ordered|unordered, spacing; List.Item children',
|
|
94
|
+
'List.Item': 'List item',
|
|
95
|
+
Badge: 'color, variant: filled|light|outline|dot|default, size',
|
|
96
|
+
Avatar: 'name (shows first character), src, color, radius, size',
|
|
97
|
+
Image: 'src={asset("./photo.jpg")} (embeds a project image), alt, h, w, radius, fit: cover|contain (default cover), position (e.g. "center 20%"); other src values draw a placeholder with alt',
|
|
98
|
+
ThemeIcon: 'color, variant, size, radius; one character as child',
|
|
99
|
+
Indicator: 'label, color, disabled (hides the badge; can be a condition), processing; wraps one element with a corner badge',
|
|
100
|
+
Timeline: 'active (completed item index), bulletSize; Timeline.Item children',
|
|
101
|
+
'Timeline.Item': 'title, bullet; description in children',
|
|
102
|
+
Table: 'data={{ head: [...], body: [[...]] }} or Table.Thead/Tbody/Tr/Th/Td; striped, withTableBorder',
|
|
103
|
+
'Table.Thead': 'Table head',
|
|
104
|
+
'Table.Tbody': 'Table body',
|
|
105
|
+
'Table.Tr': 'Row',
|
|
106
|
+
'Table.Th': 'Header cell',
|
|
107
|
+
'Table.Td': 'Cell',
|
|
108
|
+
DataTable: 'records (can bind $.data.x), columns: [{ accessor, title, textAlign, width, sortable, badge: true | { value: color }, avatar: true }], sortStatus: { columnAccessor, direction: asc|desc } (arrow only; set sorted records yourself), selectedRecords (ids, checkbox column), idAccessor (default id), fetching (loading overlay), noRecordsText; matches mantine-datatable',
|
|
109
|
+
Accordion: 'value / defaultValue (expanded item); select sets the expanded item; Accordion.Item children',
|
|
110
|
+
'Accordion.Item': 'value; contains Accordion.Control and Accordion.Panel',
|
|
111
|
+
'Accordion.Panel': 'Content shown when expanded',
|
|
112
|
+
Radio: 'value, label; place inside Radio.Group',
|
|
113
|
+
'Tabs.List': 'Tab bar; contains Tabs.Tab',
|
|
114
|
+
'Tabs.Panel': 'value; current tab content',
|
|
115
|
+
Breadcrumbs: 'separator; Anchor or text children',
|
|
116
|
+
Stepper: 'active (zero-based); Stepper.Step children',
|
|
117
|
+
'Stepper.Step': 'label, description; step content in children (only current step shown)',
|
|
118
|
+
Alert: 'title, color (default blue), variant, icon (character), withCloseButton; description in children',
|
|
119
|
+
Loader: 'size, color, type; optional child text',
|
|
120
|
+
Progress: 'value 0-100, color, size, striped',
|
|
121
|
+
RingProgress: 'sections: [{ value, color }], label, size, thickness',
|
|
122
|
+
Skeleton: 'h, w, circle, radius, visible (false shows children), animate (pulse, default true)',
|
|
123
|
+
Notification: 'title, color, icon (character), loading, withCloseButton, position: top|top-left|top-right|bottom|bottom-left|bottom-right (floats over the page; show it with when); inline without position; Buttons in children (e.g. Undo)',
|
|
124
|
+
Modal: 'opened (gated, usually opened={$.ui.open}), title, size, centered, fullScreen',
|
|
125
|
+
Drawer: 'opened (gated), title, position: left|right|top|bottom (default left), size',
|
|
126
|
+
ChatMessage: "from: 'user'|'assistant', name; message content in children (preserves newlines)",
|
|
127
|
+
ToolCall: "title, state: 'running'|'done'|'error'; call details in children",
|
|
128
|
+
Email: 'from, to, subject, time; simple email card, body in children; can contain Button',
|
|
129
|
+
DataCard: 'title, value (object or state binding), fields?: [{ key, label }]; lists all keys by default; rows changed this step show old value → new value',
|
|
130
|
+
StateFlow: 'value (current state binding), states: string[], labels?: { state: name }; earlier states are completed, current state highlighted',
|
|
131
|
+
Thinking: 'title (current thought; can bind $.ui.x), active (thinking: title pulses), duration (shows "Thought for …" when finished), opened (expands the process); thinking process in children',
|
|
132
|
+
Artifact: "title, kind: 'doc'|'code'|'sheet'|'web'|'image', status: 'generating'|'ready'|'error', version; Agent artifact side panel, content in children",
|
|
133
|
+
Terminal: 'title; terminal window (CLI prototype), Terminal.Command / Terminal.Output / Terminal.Input children; scrolls internally when content exceeds h or mah',
|
|
134
|
+
'Terminal.Command': 'prompt (default "$"); command text in children',
|
|
135
|
+
'Terminal.Output': "tone: 'plain'|'ok'|'warn'|'error' (default plain); output text in children (preserves newlines)",
|
|
136
|
+
Phone: 'scale (visual scale, default 1), h (screen height, default 844), landscape (turned sideways: content 772 × 358, notch on the left; use it for video-style or landscape mobile screens); phone frame, children laid out at mobile width 390 with breakpoints based on that width; viewport: "mobile" on a page adds it automatically; do not add Phone explicitly',
|
|
137
|
+
div: 'HTML fallback; prefer Box/Stack/Group',
|
|
138
|
+
span: 'HTML fallback; prefer Text span',
|
|
139
|
+
p: 'HTML fallback; prefer Text',
|
|
140
|
+
h1: 'HTML fallback; prefer Title order={1}',
|
|
141
|
+
h2: 'HTML fallback; prefer Title order={2}',
|
|
142
|
+
h3: 'HTML fallback; prefer Title order={3}',
|
|
143
|
+
h4: 'HTML fallback; prefer Title order={4}',
|
|
144
|
+
main: 'HTML fallback; prefer AppShell.Main',
|
|
145
|
+
section: 'HTML fallback; prefer Box',
|
|
146
|
+
header: 'HTML fallback; prefer AppShell.Header',
|
|
147
|
+
footer: 'HTML fallback; prefer AppShell.Footer',
|
|
148
|
+
nav: 'HTML fallback; prefer AppShell.Navbar',
|
|
149
|
+
aside: 'HTML fallback; prefer AppShell.Aside',
|
|
150
|
+
ul: 'HTML fallback; prefer List',
|
|
151
|
+
ol: 'HTML fallback; prefer List type="ordered"',
|
|
152
|
+
li: 'HTML fallback; prefer List.Item',
|
|
153
|
+
strong: 'HTML fallback; prefer Text fw={700} span',
|
|
154
|
+
em: 'HTML fallback; prefer Text fs="italic" span',
|
|
155
|
+
small: 'HTML fallback; prefer Text size="xs"',
|
|
156
|
+
code: 'HTML fallback; prefer Code',
|
|
157
|
+
'Avatar.Group': 'spacing (overlap, default sm); Avatar children shown as an overlapping stack',
|
|
158
|
+
'Radio.Card': 'value, label, description, leftSection (character); selectable card inside Radio.Group (select writes the group value)',
|
|
159
|
+
EmptyState: 'icon (character), title, description, withBorder, color; empty lists, 404 / expired / no-access pages, result pages; action Buttons in children',
|
|
160
|
+
ListRow: 'avatar (name) or icon (character), title, description, active, withBorder, color; list row with right-side content (Badge, Button, Text) in children; not clickable itself: use NavLink for a tappable row',
|
|
161
|
+
Stat: 'label, value, diff (e.g. "+12%", red when it starts with -), description, icon, color, progress (0-100); KPI card',
|
|
162
|
+
KeyValue: 'items: [{ label, value }] (values can bind $.data.x), total (bold last row), withDivider; order summary / details list',
|
|
163
|
+
BarChart: 'data: [{ month: "Jan", signups: 40 }] (can bind $.data.x), dataKey (x axis), series: [{ name, label?, color? }], h (default 220), unit, withLegend; low-fi bars, values animate when data changes',
|
|
164
|
+
LineChart: 'same props as BarChart; low-fi lines with points',
|
|
165
|
+
Menu: 'opened (usually opened={$.ui.menu}; dropdown shows only when true), position: bottom-start|bottom-end|top-start|top-end; Menu.Target + Menu.Dropdown children',
|
|
166
|
+
'Menu.Target': 'Wraps the trigger (ActionIcon or Button with its own id)',
|
|
167
|
+
'Menu.Dropdown': 'Menu items; visible only while the Menu is opened; floats above tables and cards',
|
|
168
|
+
'Menu.Label': 'Section label inside Menu.Dropdown',
|
|
169
|
+
'Menu.Divider': 'Divider inside Menu.Dropdown',
|
|
170
|
+
Placeholder: 'label, h; placeholder for images, charts, etc.',
|
|
171
|
+
Button: 'variant: filled|light|outline|subtle|default|white, color, size, fullWidth, loading, leftSection / rightSection (character)',
|
|
172
|
+
ActionIcon: "Icon button: aria-label (required as name), variant, color, size; one character child such as '+'",
|
|
173
|
+
CloseButton: 'aria-label, size',
|
|
174
|
+
Anchor: 'href is display-only; clicking never navigates; use go() in the step; c, underline',
|
|
175
|
+
a: 'HTML fallback; prefer Anchor',
|
|
176
|
+
NavLink: 'label, description, href (highlighted when equal to current route), active, leftSection / rightSection (character or short text); nested NavLink allowed',
|
|
177
|
+
Burger: 'opened, aria-label; narrow-screen navigation toggle, usually with hiddenFrom="sm"',
|
|
178
|
+
TextInput: 'label, placeholder, description, error, withAsterisk, type; type action writes the value',
|
|
179
|
+
PasswordInput: 'label, placeholder, description, error; type action writes the value, shown as dots',
|
|
180
|
+
NumberInput: 'label, placeholder, min, max, suffix, prefix; type action writes the value',
|
|
181
|
+
Textarea: 'label, placeholder, description, error, minRows, autosize; type action writes the value',
|
|
182
|
+
Select: 'label, data: string[] | { value, label }[], placeholder, description; select accepts value or label',
|
|
183
|
+
MultiSelect: 'label, data, placeholder; each select toggles one option',
|
|
184
|
+
Checkbox: 'label, description, checked; toggle action writes the value',
|
|
185
|
+
'Radio.Group': 'label, value; Radio value/label children; select accepts value or label',
|
|
186
|
+
Switch: 'label, description, checked; toggle action writes the value',
|
|
187
|
+
SegmentedControl: 'data: string[] | { value, label }[], fullWidth; select accepts value or label',
|
|
188
|
+
FileInput: 'label, placeholder, accept; type action writes the filename',
|
|
189
|
+
Tabs: 'value / defaultValue; Tabs.Tab inside Tabs.List, content in Tabs.Panel; select switches tabs',
|
|
190
|
+
'Tabs.Tab': 'value, leftSection (character), rightSection (count or short text, e.g. 3)',
|
|
191
|
+
'Accordion.Control': 'Clickable heading (requires id)',
|
|
192
|
+
Pagination: 'total, value / defaultValue; select action writes the page number',
|
|
193
|
+
PromptInput: 'placeholder, value; native multiline AI input, type action writes the value; audience edits are disposable exploration; use ActionIcon or Button to send',
|
|
194
|
+
'Artifact.Ref': "title, kind, status; card linking to an artifact in the conversation (requires id; clickable)",
|
|
195
|
+
'Terminal.Input': 'prompt (default "$"), placeholder; terminal input line (requires id), type action writes the value',
|
|
196
|
+
'Menu.Item': 'leftSection (character), rightSection (text), color (red for destructive); clickable menu row (requires id)',
|
|
197
|
+
TabBar: 'data: string[] | [{ value, label, icon?, badge? }], value / defaultValue, aria-label; mobile bottom tab bar, select switches tabs; place it last in a full-height Stack',
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* 示例(D68,`npx joplo components <名字>` 输出):每个都能直接放进页面或层级里用;交互状态写成 $.ui / $.data 绑定,由步骤 set()。
|
|
201
|
+
* 只给最容易写错、或需要和步骤配合的组件;其余组件看 COMPONENT_DOCS 的一行提示就够。
|
|
202
|
+
*/
|
|
203
|
+
export const COMPONENT_EXAMPLES = {
|
|
204
|
+
EmptyState: `<EmptyState icon="✉" title="No members yet" description="Invite teammates to start working together">
|
|
205
|
+
<Button id="invite_first">Invite members</Button>
|
|
206
|
+
</EmptyState>`,
|
|
207
|
+
ListRow: `<Stack gap={0}>
|
|
208
|
+
<ListRow avatar="Ana Lee" title="Ana Lee" description="ana@example.com"><Badge color="green" variant="light">Admin</Badge></ListRow>
|
|
209
|
+
<ListRow avatar="Bo Chen" title="Bo Chen" description={$.ui.boStatus} active={$.ui.boNew}><Button id="resend" variant="subtle">Resend</Button></ListRow>
|
|
210
|
+
</Stack>`,
|
|
211
|
+
Menu: `<Menu opened={$.ui.rowMenu} position="bottom-end">
|
|
212
|
+
<Menu.Target><ActionIcon id="row_more" aria-label="More actions">⋯</ActionIcon></Menu.Target>
|
|
213
|
+
<Menu.Dropdown>
|
|
214
|
+
<Menu.Item id="copy_link" leftSection="🔗">Copy invite link</Menu.Item>
|
|
215
|
+
<Menu.Divider />
|
|
216
|
+
<Menu.Item id="revoke" color="red" leftSection="✕">Revoke invite</Menu.Item>
|
|
217
|
+
</Menu.Dropdown>
|
|
218
|
+
</Menu>
|
|
219
|
+
// steps: .click('row_more', set($.ui.rowMenu, true)).click('revoke', set($.ui.rowMenu, false), set($.ui.confirm, true))`,
|
|
220
|
+
TabBar: `<Stack h="100%" gap={0}>
|
|
221
|
+
<ScrollArea style={{ flex: 1, minHeight: 0 }}>…page…</ScrollArea>
|
|
222
|
+
<TabBar id="tabs" aria-label="Bottom navigation" data={[{ value: 'home', label: 'Home', icon: '⌂' }, { value: 'trips', label: 'Trips', icon: '⛺', badge: 2 }, { value: 'me', label: 'Me', icon: '☺' }]} />
|
|
223
|
+
</Stack>
|
|
224
|
+
// steps: .select('tabs', 'trips', go('/trips'))`,
|
|
225
|
+
Stat: `<SimpleGrid cols={3}>
|
|
226
|
+
<Stat label="Signups this week" value={$.data.signups} diff="+12%" icon="↗" />
|
|
227
|
+
<Stat label="Seats used" value="8 / 10" progress={80} description="2 seats left" />
|
|
228
|
+
<Stat label="Failed payments" value="3" diff="-2" color="red" />
|
|
229
|
+
</SimpleGrid>`,
|
|
230
|
+
KeyValue: `<KeyValue withDivider total items={[{ label: 'Seats', value: '5 × $9' }, { label: 'Tax', value: '$4.50' }, { label: 'Total', value: $.data.total }]} />`,
|
|
231
|
+
Image: `<Image src={asset('../../assets/capitol.jpg')} alt="U.S. Capitol" h={240} fit="cover" position="center 40%" radius="md" />
|
|
232
|
+
// import { asset } from '@joplo-app/kit'; the path is relative to this file. jpg/png/gif/webp/avif/svg, up to 2 MB each; compress first.
|
|
233
|
+
// The image is embedded, so the board, build and share show it offline. For a tinted or full-bleed background, use style={{ backgroundImage: \`url(\${asset('./bg.jpg')})\` }}.`,
|
|
234
|
+
BarChart: `<BarChart h={220} dataKey="week" unit="" data={$.data.weeks} series={[{ name: 'signups', label: 'Signups' }, { name: 'churn', label: 'Churn', color: 'red' }]} />
|
|
235
|
+
// state: data: { weeks: [{ week: 'W1', signups: 40, churn: 4 }, { week: 'W2', signups: 52, churn: 6 }] }; set() a new array to animate`,
|
|
236
|
+
LineChart: `<LineChart h={200} dataKey="day" data={[{ day: 'Mon', p95: 320 }, { day: 'Tue', p95: 280 }]} series={[{ name: 'p95', label: 'p95 latency' }]} unit="ms" />`,
|
|
237
|
+
DataTable: `<DataTable idAccessor="id" records={$.data.members} selectedRecords={$.ui.selected} fetching={$.ui.loading}
|
|
238
|
+
sortStatus={{ columnAccessor: 'joined', direction: 'desc' }}
|
|
239
|
+
columns={[{ accessor: 'name', title: 'Name', avatar: true }, { accessor: 'status', title: 'Status', badge: { Active: 'green', Pending: 'yellow', Expired: 'gray' } }, { accessor: 'joined', title: 'Joined', sortable: true }]} />`,
|
|
240
|
+
Notification: `<Notification when={$.ui.deleted} position="bottom" title="Invite revoked" icon="↺" withCloseButton={false}>
|
|
241
|
+
<Group justify="space-between">Ana can no longer join<Button id="undo" variant="subtle" size="xs">Undo</Button></Group>
|
|
242
|
+
</Notification>`,
|
|
243
|
+
'Radio.Card': `<Radio.Group id="plan" label="Plan">
|
|
244
|
+
<Stack gap="xs">
|
|
245
|
+
<Radio.Card value="team" label="Team" description="Up to 10 seats" leftSection="👥" />
|
|
246
|
+
<Radio.Card value="pro" label="Pro" description="Unlimited seats" leftSection="★" />
|
|
247
|
+
</Stack>
|
|
248
|
+
</Radio.Group>
|
|
249
|
+
// steps: .select('plan', 'pro')`,
|
|
250
|
+
'Avatar.Group': `<Avatar.Group><Avatar name="Ana Lee" /><Avatar name="Bo Chen" /><Avatar name="+3" /></Avatar.Group>`,
|
|
251
|
+
Modal: `<Modal id="confirm" opened={$.ui.confirm} title="Revoke this invite?" size="sm">
|
|
252
|
+
<Text>Ana's link stops working right away. You can invite her again later.</Text>
|
|
253
|
+
<Group justify="flex-end"><Button id="cancel_revoke" variant="default">Cancel</Button><Button id="do_revoke" color="red">Revoke</Button></Group>
|
|
254
|
+
</Modal>`,
|
|
255
|
+
};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { JoploProps } from '@joplo-app/kit/plugin';
|
|
2
|
+
export declare const AppShell: ((props: JoploProps) => any) & {
|
|
3
|
+
Header: (props: JoploProps) => any;
|
|
4
|
+
Navbar: (props: JoploProps) => any;
|
|
5
|
+
Main: (props: JoploProps) => any;
|
|
6
|
+
Aside: (props: JoploProps) => any;
|
|
7
|
+
Footer: (props: JoploProps) => any;
|
|
8
|
+
};
|
|
9
|
+
export declare const Container: (props: JoploProps) => any;
|
|
10
|
+
export declare const Stack: (props: JoploProps) => any;
|
|
11
|
+
export declare const Group: (props: JoploProps) => any;
|
|
12
|
+
export declare const Flex: (props: JoploProps) => any;
|
|
13
|
+
export declare const Grid: ((props: JoploProps) => any) & {
|
|
14
|
+
Col: (props: JoploProps) => any;
|
|
15
|
+
};
|
|
16
|
+
export declare const SimpleGrid: (props: JoploProps) => any;
|
|
17
|
+
export declare const Center: (props: JoploProps) => any;
|
|
18
|
+
export declare const Box: (props: JoploProps) => any;
|
|
19
|
+
export declare const Space: (props: JoploProps) => any;
|
|
20
|
+
export declare const Paper: (props: JoploProps) => any;
|
|
21
|
+
export declare const Card: ((props: JoploProps) => any) & {
|
|
22
|
+
Section: (props: JoploProps) => any;
|
|
23
|
+
};
|
|
24
|
+
export declare const Divider: (props: JoploProps) => any;
|
|
25
|
+
export declare const ScrollArea: (props: JoploProps) => any;
|
|
26
|
+
export declare const Title: (props: JoploProps) => any;
|
|
27
|
+
export declare const Text: (props: JoploProps) => any;
|
|
28
|
+
export declare const Code: (props: JoploProps) => any;
|
|
29
|
+
export declare const Kbd: (props: JoploProps) => any;
|
|
30
|
+
export declare const Blockquote: (props: JoploProps) => any;
|
|
31
|
+
export declare const List: ((props: JoploProps) => any) & {
|
|
32
|
+
Item: (props: JoploProps) => any;
|
|
33
|
+
};
|
|
34
|
+
export declare const Badge: (props: JoploProps) => any;
|
|
35
|
+
export declare const Avatar: ((props: JoploProps) => any) & {
|
|
36
|
+
Group: (props: JoploProps) => any;
|
|
37
|
+
};
|
|
38
|
+
export declare const Image: (props: JoploProps) => any;
|
|
39
|
+
export declare const ThemeIcon: (props: JoploProps) => any;
|
|
40
|
+
export declare const Indicator: (props: JoploProps) => any;
|
|
41
|
+
export declare const Timeline: ((props: JoploProps) => any) & {
|
|
42
|
+
Item: (props: JoploProps) => any;
|
|
43
|
+
};
|
|
44
|
+
export declare const Table: ((props: JoploProps) => any) & {
|
|
45
|
+
Thead: (props: JoploProps) => any;
|
|
46
|
+
Tbody: (props: JoploProps) => any;
|
|
47
|
+
Tr: (props: JoploProps) => any;
|
|
48
|
+
Th: (props: JoploProps) => any;
|
|
49
|
+
Td: (props: JoploProps) => any;
|
|
50
|
+
};
|
|
51
|
+
export declare const DataTable: (props: JoploProps) => any;
|
|
52
|
+
export declare const Accordion: ((props: JoploProps) => any) & {
|
|
53
|
+
Item: (props: JoploProps) => any;
|
|
54
|
+
Control: (props: JoploProps) => any;
|
|
55
|
+
Panel: (props: JoploProps) => any;
|
|
56
|
+
};
|
|
57
|
+
export declare const Button: (props: JoploProps) => any;
|
|
58
|
+
export declare const ActionIcon: (props: JoploProps) => any;
|
|
59
|
+
export declare const CloseButton: (props: JoploProps) => any;
|
|
60
|
+
export declare const TextInput: (props: JoploProps) => any;
|
|
61
|
+
export declare const PasswordInput: (props: JoploProps) => any;
|
|
62
|
+
export declare const NumberInput: (props: JoploProps) => any;
|
|
63
|
+
export declare const Textarea: (props: JoploProps) => any;
|
|
64
|
+
export declare const Select: (props: JoploProps) => any;
|
|
65
|
+
export declare const MultiSelect: (props: JoploProps) => any;
|
|
66
|
+
export declare const Checkbox: (props: JoploProps) => any;
|
|
67
|
+
export declare const Radio: ((props: JoploProps) => any) & {
|
|
68
|
+
Group: (props: JoploProps) => any;
|
|
69
|
+
Card: (props: JoploProps) => any;
|
|
70
|
+
};
|
|
71
|
+
export declare const Switch: (props: JoploProps) => any;
|
|
72
|
+
export declare const SegmentedControl: (props: JoploProps) => any;
|
|
73
|
+
export declare const FileInput: (props: JoploProps) => any;
|
|
74
|
+
export declare const Anchor: (props: JoploProps) => any;
|
|
75
|
+
export declare const NavLink: (props: JoploProps) => any;
|
|
76
|
+
export declare const Tabs: ((props: JoploProps) => any) & {
|
|
77
|
+
List: (props: JoploProps) => any;
|
|
78
|
+
Tab: (props: JoploProps) => any;
|
|
79
|
+
Panel: (props: JoploProps) => any;
|
|
80
|
+
};
|
|
81
|
+
export declare const Breadcrumbs: (props: JoploProps) => any;
|
|
82
|
+
export declare const Pagination: (props: JoploProps) => any;
|
|
83
|
+
export declare const Stepper: ((props: JoploProps) => any) & {
|
|
84
|
+
Step: (props: JoploProps) => any;
|
|
85
|
+
};
|
|
86
|
+
export declare const Burger: (props: JoploProps) => any;
|
|
87
|
+
export declare const Alert: (props: JoploProps) => any;
|
|
88
|
+
export declare const Loader: (props: JoploProps) => any;
|
|
89
|
+
export declare const Progress: (props: JoploProps) => any;
|
|
90
|
+
export declare const RingProgress: (props: JoploProps) => any;
|
|
91
|
+
export declare const Skeleton: (props: JoploProps) => any;
|
|
92
|
+
export declare const Notification: (props: JoploProps) => any;
|
|
93
|
+
/** 简单邮件卡片,正文可放 Button。 */
|
|
94
|
+
export declare const Email: (props: JoploProps) => any;
|
|
95
|
+
/** 键值记录;fields 缺省时展示 value 的全部键,绑定的变化行显示前后对比。 */
|
|
96
|
+
export declare const DataCard: (props: JoploProps) => any;
|
|
97
|
+
/** 按 states 顺序展示完成/当前/待完成状态,labels 可替换显示文字。 */
|
|
98
|
+
export declare const StateFlow: (props: JoploProps) => any;
|
|
99
|
+
export declare const Modal: (props: JoploProps) => any;
|
|
100
|
+
export declare const Drawer: (props: JoploProps) => any;
|
|
101
|
+
export declare const ChatMessage: (props: JoploProps) => any;
|
|
102
|
+
export declare const ToolCall: (props: JoploProps) => any;
|
|
103
|
+
export declare const PromptInput: (props: JoploProps) => any;
|
|
104
|
+
/**
|
|
105
|
+
* 思考过程(D56):`<Thinking title={$.ui.thought} active={$.ui.thinking} duration="8 秒" opened>…</Thinking>`。
|
|
106
|
+
* title 是此刻在想什么(随步骤 set 变化);active 时标题闪动;结束后显示“思考了 {duration}”;opened 时展开子节点里的过程。
|
|
107
|
+
*/
|
|
108
|
+
export declare const Thinking: (props: JoploProps) => any;
|
|
109
|
+
/**
|
|
110
|
+
* Agent 的侧边产物(D56):`<Artifact title="露营行程.md" kind="doc" status={$.ui.planStatus} version="v2">…</Artifact>`,
|
|
111
|
+
* 子节点是产物内容(Text / List / Table / Code 等,文字可以用 stream 逐字生成)。
|
|
112
|
+
* 对话里引用它用 `<Artifact.Ref id="open_plan" title="露营行程" kind="doc" />`(可点击)。
|
|
113
|
+
*/
|
|
114
|
+
export declare const Artifact: ((props: JoploProps) => any) & {
|
|
115
|
+
Ref: (props: JoploProps) => any;
|
|
116
|
+
};
|
|
117
|
+
/** 终端窗口:`<Terminal title="~/work"><Terminal.Command>npx joplo skill</Terminal.Command><Terminal.Output tone="ok">…</Terminal.Output></Terminal>`。 */
|
|
118
|
+
export declare const Terminal: ((props: JoploProps) => any) & {
|
|
119
|
+
Command: (props: JoploProps) => any;
|
|
120
|
+
Output: (props: JoploProps) => any;
|
|
121
|
+
Input: (props: JoploProps) => any;
|
|
122
|
+
};
|
|
123
|
+
/** 手机外框:子节点按手机宽度排版。页面写 viewport: 'mobile' 时舞台会自动套上,不用写它。 */
|
|
124
|
+
export declare const Phone: (props: JoploProps) => any;
|
|
125
|
+
/** 空状态 / 结果页:`<EmptyState icon="✉" title="还没有成员" description="邀请同事一起协作"><Button id="invite">邀请成员</Button></EmptyState>`。 */
|
|
126
|
+
export declare const EmptyState: (props: JoploProps) => any;
|
|
127
|
+
/** 列表行:`<ListRow avatar="阿杰" title="阿杰" description="已确认"><Badge>成员</Badge></ListRow>`;右侧内容放在子节点里。 */
|
|
128
|
+
export declare const ListRow: (props: JoploProps) => any;
|
|
129
|
+
/** 指标卡:`<Stat label="本月注册" value={$.data.signups} diff="+12%" />`。 */
|
|
130
|
+
export declare const Stat: (props: JoploProps) => any;
|
|
131
|
+
/** 键值清单:`<KeyValue items={[{ label: '席位', value: '5 个' }, { label: '合计', value: '¥ 450' }]} total />`。 */
|
|
132
|
+
export declare const KeyValue: (props: JoploProps) => any;
|
|
133
|
+
/** 低保真图表(对齐 @mantine/charts):`<BarChart data={$.data.weeks} dataKey="week" series={[{ name: 'signups', label: '注册' }]} />`。 */
|
|
134
|
+
export declare const BarChart: (props: JoploProps) => any;
|
|
135
|
+
export declare const LineChart: (props: JoploProps) => any;
|
|
136
|
+
/**
|
|
137
|
+
* 菜单(对齐 Mantine):opened 写在 Menu 上,下拉只在为真时出现。
|
|
138
|
+
* `<Menu opened={$.ui.rowMenu}><Menu.Target><ActionIcon id="row_more" aria-label="更多">⋯</ActionIcon></Menu.Target>
|
|
139
|
+
* <Menu.Dropdown><Menu.Item id="revoke" color="red">撤销邀请</Menu.Item></Menu.Dropdown></Menu>`
|
|
140
|
+
*/
|
|
141
|
+
export declare const Menu: ((props: JoploProps) => any) & {
|
|
142
|
+
Target: (props: JoploProps) => any;
|
|
143
|
+
Dropdown: (props: JoploProps) => any;
|
|
144
|
+
Item: (props: JoploProps) => any;
|
|
145
|
+
Label: (props: JoploProps) => any;
|
|
146
|
+
Divider: (props: JoploProps) => any;
|
|
147
|
+
};
|
|
148
|
+
/** 手机底部标签栏:`<TabBar id="tabs" aria-label="底部导航" value={$.ui.tab} data={[{ value: 'home', label: '首页', icon: '⌂' }]} />`,select 切换。 */
|
|
149
|
+
export declare const TabBar: (props: JoploProps) => any;
|
|
150
|
+
export declare const Placeholder: (props: JoploProps) => any;
|