@cogito.ai/astryx-web 0.0.0-stage → 0.2.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 +21 -0
- package/README.md +34 -2
- package/astryx.integration.mjs +15 -0
- package/bin/astryx-web.mjs +353 -0
- package/docs/dock-accessibility.doc.mjs +24 -0
- package/docs/dock-components.doc.mjs +26 -0
- package/docs/dock-copy.doc.mjs +23 -0
- package/docs/dock-design-base.doc.mjs +35 -0
- package/docs/dock-environment.doc.mjs +24 -0
- package/docs/dock-layout.doc.mjs +25 -0
- package/docs/dock-product-stance.doc.mjs +25 -0
- package/docs/dock-refuse-list.doc.mjs +34 -0
- package/docs/dock-states.doc.mjs +23 -0
- package/docs/dock-style-archetypes.doc.mjs +104 -0
- package/docs/dock-touch-mobile.doc.mjs +27 -0
- package/docs/dock-visual-acceptance.doc.mjs +23 -0
- package/package.json +51 -3
- package/skills/astryx-web-design/SKILL.md +21 -0
- package/skills/astryx-web-design/references/acceptance.md +12 -0
- package/skills/astryx-web-design/references/design-direction.md +52 -0
- package/skills/astryx-web-design/references/page-building.md +18 -0
- package/templates/dock-editor-frame.doc.mjs +19 -0
- package/templates/dock-editor-frame.tsx +229 -0
- package/templates/dock-form-flow.doc.mjs +19 -0
- package/templates/dock-form-flow.tsx +169 -0
- package/templates/dock-landing.doc.mjs +11 -0
- package/templates/dock-landing.tsx +104 -0
- package/templates/dock-list.doc.mjs +20 -0
- package/templates/dock-list.tsx +223 -0
- package/templates/dock-settings.doc.mjs +19 -0
- package/templates/dock-settings.tsx +272 -0
- package/templates/dock-workbench.doc.mjs +11 -0
- package/templates/dock-workbench.tsx +193 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/** @type {import('@astryxdesign/cli/authoring').ReferenceDoc} */
|
|
2
|
+
export default {
|
|
3
|
+
type: "generic",
|
|
4
|
+
name: "dock-style-archetypes",
|
|
5
|
+
title: "Dock Style Archetypes",
|
|
6
|
+
description: "Eight approved visual directions built on Astryx themes.",
|
|
7
|
+
sections: [
|
|
8
|
+
{
|
|
9
|
+
title: "Style archetypes",
|
|
10
|
+
content: [
|
|
11
|
+
{
|
|
12
|
+
type: "prose",
|
|
13
|
+
text: "The design discussion may only propose directions from this table. Reference brands describe a look; never copy their fonts, logos, or assets.",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
type: "table",
|
|
17
|
+
headers: [
|
|
18
|
+
"Id",
|
|
19
|
+
"Base theme",
|
|
20
|
+
"Temperament",
|
|
21
|
+
"Color strategy",
|
|
22
|
+
"Type, density, radius",
|
|
23
|
+
"Suits",
|
|
24
|
+
"Look reference",
|
|
25
|
+
],
|
|
26
|
+
rows: [
|
|
27
|
+
[
|
|
28
|
+
"quiet-tool",
|
|
29
|
+
"neutral",
|
|
30
|
+
"calm, focused, efficient",
|
|
31
|
+
"about 90% neutral; one accent for the primary action and focus only",
|
|
32
|
+
"system sans; compact; small radii",
|
|
33
|
+
"editors, studios, productivity tools",
|
|
34
|
+
"Linear, Figma",
|
|
35
|
+
],
|
|
36
|
+
[
|
|
37
|
+
"warm-learning",
|
|
38
|
+
"butter",
|
|
39
|
+
"friendly, encouraging, light",
|
|
40
|
+
"warm surfaces, one blue accent; clear success and error states",
|
|
41
|
+
"rounded sans; comfortable; medium radii",
|
|
42
|
+
"learning and practice, habits",
|
|
43
|
+
"Duolingo (restrained), Headspace",
|
|
44
|
+
],
|
|
45
|
+
[
|
|
46
|
+
"calm-content",
|
|
47
|
+
"matcha",
|
|
48
|
+
"natural, steady, trustworthy",
|
|
49
|
+
"low-saturation green and neutrals; few accents",
|
|
50
|
+
"readable body type; generous spacing",
|
|
51
|
+
"wellness, reading, content-first",
|
|
52
|
+
"Calm, Notion",
|
|
53
|
+
],
|
|
54
|
+
[
|
|
55
|
+
"crafted-record",
|
|
56
|
+
"stone",
|
|
57
|
+
"plain, reliable, warm",
|
|
58
|
+
"warm grey and slate; a low-saturation accent",
|
|
59
|
+
"sans; comfortable; medium radii",
|
|
60
|
+
"records, archives, personal management",
|
|
61
|
+
"Things, Bear",
|
|
62
|
+
],
|
|
63
|
+
[
|
|
64
|
+
"editorial",
|
|
65
|
+
"gothic",
|
|
66
|
+
"serious, memorable",
|
|
67
|
+
"deep blue-grey; display serif headings",
|
|
68
|
+
"serif display with sans body; spacious",
|
|
69
|
+
"reports, portfolios, long-form",
|
|
70
|
+
"Medium, The Atlantic",
|
|
71
|
+
],
|
|
72
|
+
[
|
|
73
|
+
"warm-premium",
|
|
74
|
+
"chocolate",
|
|
75
|
+
"rich, refined",
|
|
76
|
+
"brown palette; serif headings",
|
|
77
|
+
"the theme's Fraunces and Albert Sans; spacious",
|
|
78
|
+
"lifestyle, premium content",
|
|
79
|
+
"Aesop, Kinfolk",
|
|
80
|
+
],
|
|
81
|
+
[
|
|
82
|
+
"playful",
|
|
83
|
+
"y2k",
|
|
84
|
+
"bubbly, young",
|
|
85
|
+
"saturated pink and lime, used sparingly",
|
|
86
|
+
"the theme's Poppins; comfortable; large radii",
|
|
87
|
+
"kids, entertainment, community",
|
|
88
|
+
"—",
|
|
89
|
+
],
|
|
90
|
+
[
|
|
91
|
+
"precise-data",
|
|
92
|
+
"neutral with a blue brand color",
|
|
93
|
+
"exact, credible",
|
|
94
|
+
"neutrals plus a data-visualization palette",
|
|
95
|
+
"tabular figures; compact",
|
|
96
|
+
"dashboards, evaluation, admin",
|
|
97
|
+
"Vercel, Stripe",
|
|
98
|
+
],
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** @type {import('@astryxdesign/cli/authoring').ReferenceDoc} */
|
|
2
|
+
export default {
|
|
3
|
+
type: 'generic',
|
|
4
|
+
name: 'dock-touch-mobile',
|
|
5
|
+
title: 'Dock Touch Mobile',
|
|
6
|
+
description: 'Touch targets, safe areas, compact navigation, and mobile interaction rules.',
|
|
7
|
+
sections: [
|
|
8
|
+
{
|
|
9
|
+
title: 'Touch and mobile',
|
|
10
|
+
content: [
|
|
11
|
+
{
|
|
12
|
+
type: 'list',
|
|
13
|
+
style: 'unordered',
|
|
14
|
+
items: [
|
|
15
|
+
'Touch targets are at least 44×44px. 32px is allowed only in dense toolbars that never appear on touch screens.',
|
|
16
|
+
'On compact containers, first-level destinations live in the bottom navigation, and the primary action of a flow sits in a bottom bar within thumb reach.',
|
|
17
|
+
'Respect safe areas: `viewport-fit=cover` and `env(safe-area-inset-*)` padding on fixed bars.',
|
|
18
|
+
'Use `100dvh`, not `100vh`.',
|
|
19
|
+
'Inputs use at least a 16px font so iOS does not zoom.',
|
|
20
|
+
'Anything revealed on hover must also work by tap; gate hover styles with `@media (hover: hover)`.',
|
|
21
|
+
'Secondary choices on compact containers open as bottom sheets, not floating menus.',
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** @type {import('@astryxdesign/cli/authoring').ReferenceDoc} */
|
|
2
|
+
export default {
|
|
3
|
+
type: 'generic',
|
|
4
|
+
name: 'dock-visual-acceptance',
|
|
5
|
+
title: 'Dock Visual Acceptance',
|
|
6
|
+
description: 'The render matrix and visual review rules for UI work.',
|
|
7
|
+
sections: [
|
|
8
|
+
{
|
|
9
|
+
title: 'Visual acceptance',
|
|
10
|
+
content: [
|
|
11
|
+
{
|
|
12
|
+
type: 'list',
|
|
13
|
+
style: 'unordered',
|
|
14
|
+
items: [
|
|
15
|
+
'Render the changed pages at 390×844 and 1440×900, in light and dark.',
|
|
16
|
+
'Check them against A1–A9. Fix everything you find in one batch. At most two rounds, then hand over.',
|
|
17
|
+
'Screenshots are for judging what the user sees. Never use them to watch CI, pipelines, or progress; read the API.',
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,54 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cogito.ai/astryx-web",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Mobile-first page archetypes and design guidance for AgentDock web projects",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"bin": {
|
|
10
|
+
"astryx-web": "./bin/astryx-web.mjs"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
"./templates/dock-landing": "./templates/dock-landing.tsx",
|
|
14
|
+
"./templates/dock-workbench": "./templates/dock-workbench.tsx",
|
|
15
|
+
"./templates/dock-list": "./templates/dock-list.tsx",
|
|
16
|
+
"./templates/dock-form-flow": "./templates/dock-form-flow.tsx",
|
|
17
|
+
"./templates/dock-settings": "./templates/dock-settings.tsx",
|
|
18
|
+
"./templates/dock-editor-frame": "./templates/dock-editor-frame.tsx"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"astryx.integration.mjs",
|
|
22
|
+
"templates/",
|
|
23
|
+
"docs/",
|
|
24
|
+
"skills/",
|
|
25
|
+
"bin/",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE"
|
|
28
|
+
],
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=22.13.0"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@astryxdesign/cli": ">=0.7.0",
|
|
34
|
+
"@astryxdesign/core": "^0.7.5"
|
|
35
|
+
},
|
|
36
|
+
"peerDependenciesMeta": {
|
|
37
|
+
"@astryxdesign/cli": {
|
|
38
|
+
"optional": true
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@astryxdesign/cli": "0.7.5",
|
|
43
|
+
"@astryxdesign/core": "0.7.5",
|
|
44
|
+
"typescript": "6.0.3"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"check": "pnpm test && pnpm run check:integration && pnpm run check:templates && pnpm run check:intents",
|
|
48
|
+
"check:integration": "astryx integration check --strict && astryx integration verify",
|
|
49
|
+
"check:templates": "node scripts/check-templates.mjs",
|
|
50
|
+
"check:intents": "node scripts/golden-intents.mjs",
|
|
51
|
+
"check-types": "pnpm run check",
|
|
52
|
+
"test": "node --test test/*.test.mjs"
|
|
53
|
+
}
|
|
6
54
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: astryx-web-design
|
|
3
|
+
description: Use before any UI work in a web-tanstackstart project or a domain package Web. If DESIGN.md is not approved, hold the design-direction discussion with the owner (brand, UI style, UX, color system) and stop until they decide; otherwise create pages only with pnpm page:new and accept them at phone and desktop sizes.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Astryx web design
|
|
7
|
+
|
|
8
|
+
| Situation | Read |
|
|
9
|
+
| ---------------------------------------------------------------------- | --------------------------------------------------------- |
|
|
10
|
+
| `DESIGN.md` says `status: draft` (new project, or no direction agreed) | `references/design-direction.md`, before any feature work |
|
|
11
|
+
| Adding or changing a page | `references/page-building.md` |
|
|
12
|
+
| About to call UI work done | `references/acceptance.md` |
|
|
13
|
+
|
|
14
|
+
Rules that never bend:
|
|
15
|
+
|
|
16
|
+
- No feature page before the owner approves the design direction. Never choose for the owner, never
|
|
17
|
+
set a deadline, never fall back to a default.
|
|
18
|
+
- Every page comes from `pnpm page:new`. Never lay a page out from scratch.
|
|
19
|
+
- The shared rules are in `pnpm exec astryx docs dock-design-base`. Read the section you need
|
|
20
|
+
instead of guessing.
|
|
21
|
+
- Screenshots are for judging what the user sees. Never use them to watch CI or progress.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Visual acceptance
|
|
2
|
+
|
|
3
|
+
1. `pnpm dev`, then `pnpm design:samples` for every changed route with the project theme, light and
|
|
4
|
+
dark, 390x844 and 1440x900.
|
|
5
|
+
2. Open every image and check it against `pnpm exec astryx docs dock-visual-acceptance` and
|
|
6
|
+
`pnpm exec astryx docs dock-refuse-list`, plus `DESIGN.md`.
|
|
7
|
+
3. Also check: no horizontal scroll at 360px; touch targets at least 44px; keyboard path and visible
|
|
8
|
+
focus; both locales.
|
|
9
|
+
4. Fix everything you found in one batch and render again. At most two rounds; then report the
|
|
10
|
+
image folder to the owner.
|
|
11
|
+
|
|
12
|
+
Screenshots are only for judging the UI. Never use them to watch CI, a pipeline, or progress.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Design direction (before any feature work)
|
|
2
|
+
|
|
3
|
+
Outcome: the owner decides the brand, UI style, UX model, and color system. You record them in
|
|
4
|
+
`PRODUCT.md` and `DESIGN.md` and set `DESIGN.md` to `approved`.
|
|
5
|
+
|
|
6
|
+
## 1 · Understand the product (no visuals yet)
|
|
7
|
+
|
|
8
|
+
Read the product's intent first (`README.md`; in a domain package also `contract.json` and
|
|
9
|
+
`roadmap.yaml`). Then ask the owner at most three questions per message until `PRODUCT.md` can be
|
|
10
|
+
filled:
|
|
11
|
+
|
|
12
|
+
- who uses it, where (phone, desktop App, browser), and how often;
|
|
13
|
+
- the one or two core tasks, and what "done" looks like for the user;
|
|
14
|
+
- the brand's personality in three adjectives, and one or two products it must not feel like.
|
|
15
|
+
|
|
16
|
+
Write `PRODUCT.md`, show it, and correct what the owner corrects.
|
|
17
|
+
|
|
18
|
+
## 2 · Round 1: three directions
|
|
19
|
+
|
|
20
|
+
1. Read `pnpm exec astryx docs dock-style-archetypes`. Choose three rows that fit `PRODUCT.md` and
|
|
21
|
+
differ along one named axis (for example calm ↔ energetic). Never propose a direction that is
|
|
22
|
+
not in the table.
|
|
23
|
+
2. For each direction write five lines: the archetype and its base theme; type, density, and
|
|
24
|
+
radius; navigation on phone and on desktop; the first screen; the core task in three steps.
|
|
25
|
+
3. Render the three sample pages (landing, settings, workbench) under each direction's base theme:
|
|
26
|
+
`pnpm dev`, then
|
|
27
|
+
`pnpm design:samples --route /zh-CN --route /zh-CN/settings --route /zh-CN/hello --theme <base> --mode light --mode dark --size 390x844 --size 1440x900 --out <dir>/round1/<direction>`.
|
|
28
|
+
Use the output directory the owner gave you; if none, `design-samples/` at the repository root.
|
|
29
|
+
If a base theme is not installed yet, add it first with `pnpm exec astryx theme add <slug>`;
|
|
30
|
+
after the decision, remove the themes that were added only for this round.
|
|
31
|
+
4. Send the owner the five lines and the render folder for each direction. **Stop and wait.** No
|
|
32
|
+
deadline, no default. If the owner mixes directions or asks for changes, adjust and render again.
|
|
33
|
+
|
|
34
|
+
## 3 · Round 2: brand color
|
|
35
|
+
|
|
36
|
+
1. For the chosen direction, generate two or three palette candidates with
|
|
37
|
+
`pnpm exec astryx theme palette generate <config>` (`pnpm exec astryx docs cli/commands/theme-palette`).
|
|
38
|
+
2. Build each candidate as a theme (`pnpm exec astryx docs author-a-theme`). An ejected theme's
|
|
39
|
+
local icon file may import packages the app does not have; use the base theme package's exported
|
|
40
|
+
icon registry instead of adding a dependency. Render the landing page with each candidate, light
|
|
41
|
+
and dark, phone and desktop, into `<dir>/round2/<candidate>`.
|
|
42
|
+
3. Send the candidates with their contrast ratios for body text. **Stop and wait.**
|
|
43
|
+
|
|
44
|
+
## 4 · Record
|
|
45
|
+
|
|
46
|
+
1. Keep the chosen brand theme as the project's default theme; add its built module and CSS to
|
|
47
|
+
`AppearanceProvider`'s theme options, update its explicit theme-list test, and remove the other
|
|
48
|
+
candidates.
|
|
49
|
+
2. Fill `DESIGN.md`: front matter, then Overview, Colors, Typography, Layout and navigation, Pages
|
|
50
|
+
(planned routes with their archetypes), Do and don't.
|
|
51
|
+
3. Add a dated entry to `## Decisions`: what was chosen, what else was shown, and the owner's words.
|
|
52
|
+
4. Set `status: approved`, `approvedBy`, and `approvedAt` only now. Run `pnpm check`.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Building a page
|
|
2
|
+
|
|
3
|
+
1. Name the page by type and purpose: "<type> page for <purpose>" (types: landing, workbench,
|
|
4
|
+
list, form, settings, editor). Put the page type last: write `mobile settings page`, not
|
|
5
|
+
`settings page on mobile`. Run `pnpm page:new "<intent>" --route <path>`. If it rejects the
|
|
6
|
+
intent, pick a template from the list it prints and pass `--template <id>`.
|
|
7
|
+
2. Replace the `SAMPLE_*` data with feature data through the feature's public API (`LLM.md` §7).
|
|
8
|
+
3. Write the page's copy in `src/i18n/pages/<page>.ts` for every locale.
|
|
9
|
+
4. Change the page only inside its sections; keep its frame, gaps, and padding. For a part the
|
|
10
|
+
archetype lacks, `pnpm exec astryx build "<part>"` lists blocks; print one with
|
|
11
|
+
`pnpm exec astryx template <Block>`, then move its strings to the catalog and drop any `style`
|
|
12
|
+
attribute.
|
|
13
|
+
5. A domain component (a canvas, a player) goes into the archetype's slot; never replace the frame.
|
|
14
|
+
6. Follow `DESIGN.md` and `pnpm exec astryx docs dock-design-base`. Run `pnpm check`, then
|
|
15
|
+
`references/acceptance.md`.
|
|
16
|
+
|
|
17
|
+
Never: lay a page out from scratch; use a Core template without `--allow-core`; add a package to
|
|
18
|
+
satisfy a template's import.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** @type {import('@astryxdesign/cli/authoring').IntegrationTemplateDoc} */
|
|
2
|
+
export default {
|
|
3
|
+
type: 'page',
|
|
4
|
+
name: 'Editor frame',
|
|
5
|
+
displayName: 'Editor frame',
|
|
6
|
+
description:
|
|
7
|
+
'A full-bleed editor workspace with a named content slot, floating tools, an overflow menu, and compact bottom navigation.',
|
|
8
|
+
category: 'Editor - Canvas',
|
|
9
|
+
keywords: [
|
|
10
|
+
'canvas editor',
|
|
11
|
+
'diagram editor',
|
|
12
|
+
'workspace',
|
|
13
|
+
'editor frame',
|
|
14
|
+
'floating toolbar',
|
|
15
|
+
'mobile',
|
|
16
|
+
],
|
|
17
|
+
replaces: 'canvas-editor',
|
|
18
|
+
isReady: true,
|
|
19
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { DropdownMenu } from '@astryxdesign/core/DropdownMenu'
|
|
2
|
+
import { Icon } from '@astryxdesign/core/Icon'
|
|
3
|
+
import { IconButton } from '@astryxdesign/core/IconButton'
|
|
4
|
+
import { MoreMenu } from '@astryxdesign/core/MoreMenu'
|
|
5
|
+
import { Stack } from '@astryxdesign/core/Stack'
|
|
6
|
+
import { Text } from '@astryxdesign/core/Text'
|
|
7
|
+
import { useTranslator } from '@astryxdesign/core/i18n'
|
|
8
|
+
import * as stylex from '@stylexjs/stylex'
|
|
9
|
+
|
|
10
|
+
const styles = stylex.create({
|
|
11
|
+
frame: {
|
|
12
|
+
position: 'relative',
|
|
13
|
+
flex: 1,
|
|
14
|
+
minHeight: 0,
|
|
15
|
+
width: 'calc(100% + 1.5rem)',
|
|
16
|
+
marginInline: '-0.75rem',
|
|
17
|
+
marginBlock: '-0.75rem',
|
|
18
|
+
overflow: 'hidden',
|
|
19
|
+
backgroundColor: 'var(--color-background-muted)',
|
|
20
|
+
'@container (min-width: 420px)': {
|
|
21
|
+
width: 'calc(100% + 2.5rem)',
|
|
22
|
+
marginInline: '-1.25rem',
|
|
23
|
+
marginBlock: '-1.25rem',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
tools: {
|
|
27
|
+
position: 'absolute',
|
|
28
|
+
top: 'max(0.75rem, env(safe-area-inset-top))',
|
|
29
|
+
left: 'max(0.75rem, env(safe-area-inset-left))',
|
|
30
|
+
zIndex: 2,
|
|
31
|
+
padding: '0.25rem',
|
|
32
|
+
borderRadius: 'var(--radius-element)',
|
|
33
|
+
backgroundColor: 'var(--color-background-card)',
|
|
34
|
+
boxShadow: 'var(--shadow-med)',
|
|
35
|
+
'@container (min-width: 640px)': {
|
|
36
|
+
top: 'max(1.5rem, env(safe-area-inset-top))',
|
|
37
|
+
left: 'max(1.5rem, env(safe-area-inset-left))',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
menu: {
|
|
41
|
+
position: 'absolute',
|
|
42
|
+
top: 'max(0.75rem, env(safe-area-inset-top))',
|
|
43
|
+
right: 'max(0.75rem, env(safe-area-inset-right))',
|
|
44
|
+
zIndex: 2,
|
|
45
|
+
'@container (min-width: 640px)': {
|
|
46
|
+
top: 'max(1.5rem, env(safe-area-inset-top))',
|
|
47
|
+
right: 'max(1.5rem, env(safe-area-inset-right))',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
bottomNav: {
|
|
51
|
+
position: 'absolute',
|
|
52
|
+
left: '50%',
|
|
53
|
+
bottom: 'max(0.75rem, env(safe-area-inset-bottom))',
|
|
54
|
+
transform: 'translateX(-50%)',
|
|
55
|
+
zIndex: 2,
|
|
56
|
+
padding: '0.25rem',
|
|
57
|
+
borderRadius: 'var(--radius-full)',
|
|
58
|
+
backgroundColor: 'var(--color-background-card)',
|
|
59
|
+
boxShadow: 'var(--shadow-med)',
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
function EditorSlot() {
|
|
64
|
+
const t = useTranslator()
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<Stack
|
|
68
|
+
aria-label={t('page.__PAGE__.slot.label')}
|
|
69
|
+
height="100%"
|
|
70
|
+
hAlign="center"
|
|
71
|
+
vAlign="center"
|
|
72
|
+
gap={2}
|
|
73
|
+
>
|
|
74
|
+
<Text type="body" weight="semibold">
|
|
75
|
+
{t('page.__PAGE__.slot.title')}
|
|
76
|
+
</Text>
|
|
77
|
+
<Text type="supporting" color="secondary">
|
|
78
|
+
{t('page.__PAGE__.slot.description')}
|
|
79
|
+
</Text>
|
|
80
|
+
</Stack>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export default function DockEditorFrame() {
|
|
85
|
+
const t = useTranslator()
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<Stack width="100%" xstyle={styles.frame}>
|
|
89
|
+
<EditorSlot />
|
|
90
|
+
|
|
91
|
+
<Stack direction="horizontal" gap={1} xstyle={styles.tools}>
|
|
92
|
+
<IconButton
|
|
93
|
+
label={t('page.__PAGE__.tool.select')}
|
|
94
|
+
icon={<Icon icon="arrowUp" size="sm" />}
|
|
95
|
+
variant="ghost"
|
|
96
|
+
size="sm"
|
|
97
|
+
/>
|
|
98
|
+
<IconButton
|
|
99
|
+
label={t('page.__PAGE__.tool.move')}
|
|
100
|
+
icon={<Icon icon="arrowDown" size="sm" />}
|
|
101
|
+
variant="ghost"
|
|
102
|
+
size="sm"
|
|
103
|
+
/>
|
|
104
|
+
<IconButton
|
|
105
|
+
label={t('page.__PAGE__.tool.find')}
|
|
106
|
+
icon={<Icon icon="search" size="sm" />}
|
|
107
|
+
variant="ghost"
|
|
108
|
+
size="sm"
|
|
109
|
+
/>
|
|
110
|
+
<IconButton
|
|
111
|
+
label={t('page.__PAGE__.tool.layers')}
|
|
112
|
+
icon={<Icon icon="viewColumns" size="sm" />}
|
|
113
|
+
variant="ghost"
|
|
114
|
+
size="sm"
|
|
115
|
+
/>
|
|
116
|
+
<IconButton
|
|
117
|
+
label={t('page.__PAGE__.tool.adjust')}
|
|
118
|
+
icon={<Icon icon="wrench" size="sm" />}
|
|
119
|
+
variant="ghost"
|
|
120
|
+
size="sm"
|
|
121
|
+
/>
|
|
122
|
+
<MoreMenu
|
|
123
|
+
label={t('page.__PAGE__.tool.more')}
|
|
124
|
+
size="sm"
|
|
125
|
+
presentation="adaptive"
|
|
126
|
+
items={[
|
|
127
|
+
{
|
|
128
|
+
id: 'duplicate',
|
|
129
|
+
label: t('page.__PAGE__.action.duplicate'),
|
|
130
|
+
icon: <Icon icon="copy" size="sm" />,
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
id: 'delete',
|
|
134
|
+
label: t('page.__PAGE__.action.delete'),
|
|
135
|
+
variant: 'destructive',
|
|
136
|
+
icon: <Icon icon="close" size="sm" />,
|
|
137
|
+
},
|
|
138
|
+
]}
|
|
139
|
+
/>
|
|
140
|
+
</Stack>
|
|
141
|
+
|
|
142
|
+
<DropdownMenu
|
|
143
|
+
xstyle={styles.menu}
|
|
144
|
+
hasChevron={false}
|
|
145
|
+
button={{
|
|
146
|
+
label: t('page.__PAGE__.menu'),
|
|
147
|
+
icon: <Icon icon="menu" size="sm" />,
|
|
148
|
+
variant: 'secondary',
|
|
149
|
+
size: 'sm',
|
|
150
|
+
}}
|
|
151
|
+
items={[
|
|
152
|
+
{
|
|
153
|
+
id: 'rename',
|
|
154
|
+
label: t('page.__PAGE__.action.rename'),
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: 'export',
|
|
158
|
+
label: t('page.__PAGE__.action.export'),
|
|
159
|
+
},
|
|
160
|
+
]}
|
|
161
|
+
/>
|
|
162
|
+
|
|
163
|
+
<Stack direction="horizontal" gap={1} xstyle={styles.bottomNav}>
|
|
164
|
+
<IconButton
|
|
165
|
+
label={t('page.__PAGE__.nav.back')}
|
|
166
|
+
icon={<Icon icon="chevronLeft" size="sm" />}
|
|
167
|
+
variant="ghost"
|
|
168
|
+
size="sm"
|
|
169
|
+
/>
|
|
170
|
+
<IconButton
|
|
171
|
+
label={t('page.__PAGE__.nav.history')}
|
|
172
|
+
icon={<Icon icon="clock" size="sm" />}
|
|
173
|
+
variant="ghost"
|
|
174
|
+
size="sm"
|
|
175
|
+
/>
|
|
176
|
+
<IconButton
|
|
177
|
+
label={t('page.__PAGE__.nav.done')}
|
|
178
|
+
icon={<Icon icon="check" size="sm" />}
|
|
179
|
+
variant="primary"
|
|
180
|
+
size="sm"
|
|
181
|
+
/>
|
|
182
|
+
</Stack>
|
|
183
|
+
</Stack>
|
|
184
|
+
)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/*
|
|
188
|
+
astryx-messages
|
|
189
|
+
{
|
|
190
|
+
"en": {
|
|
191
|
+
"page.__PAGE__.slot.label": "Editor content",
|
|
192
|
+
"page.__PAGE__.slot.title": "Editor canvas",
|
|
193
|
+
"page.__PAGE__.slot.description": "Put the domain editor in this slot.",
|
|
194
|
+
"page.__PAGE__.tool.select": "Select",
|
|
195
|
+
"page.__PAGE__.tool.move": "Move",
|
|
196
|
+
"page.__PAGE__.tool.find": "Find",
|
|
197
|
+
"page.__PAGE__.tool.layers": "Layers",
|
|
198
|
+
"page.__PAGE__.tool.adjust": "Adjust",
|
|
199
|
+
"page.__PAGE__.tool.more": "More tools",
|
|
200
|
+
"page.__PAGE__.menu": "Editor menu",
|
|
201
|
+
"page.__PAGE__.action.duplicate": "Duplicate",
|
|
202
|
+
"page.__PAGE__.action.delete": "Delete",
|
|
203
|
+
"page.__PAGE__.action.rename": "Rename",
|
|
204
|
+
"page.__PAGE__.action.export": "Export",
|
|
205
|
+
"page.__PAGE__.nav.back": "Back",
|
|
206
|
+
"page.__PAGE__.nav.history": "History",
|
|
207
|
+
"page.__PAGE__.nav.done": "Done"
|
|
208
|
+
},
|
|
209
|
+
"zh-CN": {
|
|
210
|
+
"page.__PAGE__.slot.label": "编辑器内容",
|
|
211
|
+
"page.__PAGE__.slot.title": "编辑器画布",
|
|
212
|
+
"page.__PAGE__.slot.description": "在此插槽中放入领域编辑器。",
|
|
213
|
+
"page.__PAGE__.tool.select": "选择",
|
|
214
|
+
"page.__PAGE__.tool.move": "移动",
|
|
215
|
+
"page.__PAGE__.tool.find": "查找",
|
|
216
|
+
"page.__PAGE__.tool.layers": "图层",
|
|
217
|
+
"page.__PAGE__.tool.adjust": "调整",
|
|
218
|
+
"page.__PAGE__.tool.more": "更多工具",
|
|
219
|
+
"page.__PAGE__.menu": "编辑器菜单",
|
|
220
|
+
"page.__PAGE__.action.duplicate": "复制",
|
|
221
|
+
"page.__PAGE__.action.delete": "删除",
|
|
222
|
+
"page.__PAGE__.action.rename": "重命名",
|
|
223
|
+
"page.__PAGE__.action.export": "导出",
|
|
224
|
+
"page.__PAGE__.nav.back": "返回",
|
|
225
|
+
"page.__PAGE__.nav.history": "历史",
|
|
226
|
+
"page.__PAGE__.nav.done": "完成"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
*/
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** @type {import('@astryxdesign/cli/authoring').IntegrationTemplateDoc} */
|
|
2
|
+
export default {
|
|
3
|
+
type: 'page',
|
|
4
|
+
name: 'Form flow',
|
|
5
|
+
displayName: 'Form flow',
|
|
6
|
+
description:
|
|
7
|
+
'A mobile-first creation form or wizard with one step per screen, inline validation, and actions within thumb reach.',
|
|
8
|
+
category: 'Form - Flow',
|
|
9
|
+
keywords: [
|
|
10
|
+
'creation form',
|
|
11
|
+
'multi-step form',
|
|
12
|
+
'wizard form',
|
|
13
|
+
'mobile form',
|
|
14
|
+
'mobile',
|
|
15
|
+
'several steps',
|
|
16
|
+
],
|
|
17
|
+
replaces: 'form-wizard',
|
|
18
|
+
isReady: true,
|
|
19
|
+
}
|