openyida 2026.9.21 → 2026.9.22-beta.2
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/README.md +14 -20
- package/bin/yida.js +6 -11
- package/lib/app/app-list.js +3 -7
- package/lib/app/canvas-compile.js +12 -22
- package/lib/app/check-prd-completeness.js +0 -7
- package/lib/app/create-app.js +1 -4
- package/lib/app/create-form/args.js +12 -37
- package/lib/app/create-form/batch.js +11 -86
- package/lib/app/create-form.js +86 -193
- package/lib/app/create-page.js +17 -84
- package/lib/app/custom-theme.js +0 -11
- package/lib/app/form-field-validator.js +41 -26
- package/lib/app/form-open-guard.js +10 -97
- package/lib/app/get-form-config.js +0 -1
- package/lib/app/inline-css-guard.js +31 -1
- package/lib/app/services/form-compiler.js +4 -2
- package/lib/app/theme-from-design.js +41 -144
- package/lib/app/theme-presets.js +1 -1
- package/lib/app/update-app.js +13 -63
- package/lib/asset/ai-image.js +9 -59
- package/lib/asset/asset-cmd.js +7 -18
- package/lib/asset/asset-plan.js +9 -102
- package/lib/asset/asset-resolve.js +10 -55
- package/lib/asset/asset-status.js +4 -5
- package/lib/asset/host-capabilities.js +2 -11
- package/lib/asset/url-verify.js +4 -19
- package/lib/auth/dws-sync.js +148 -0
- package/lib/auth/token-auth.js +73 -9
- package/lib/auth/token-store.js +50 -0
- package/lib/connector/connector-test.js +5 -19
- package/lib/connector/contract.js +1 -3
- package/lib/core/agent-capabilities.js +16 -19
- package/lib/core/command-manifest.js +40 -329
- package/lib/core/locales/en.js +17 -74
- package/lib/core/locales/zh.js +16 -73
- package/lib/core/redact.js +10 -15
- package/lib/core/sample.js +30 -72
- package/lib/core/utils.js +4 -0
- package/lib/design-plan/design-plan.js +4 -51
- package/lib/design-plan/init.js +26 -121
- package/lib/design-plan/materialize.js +348 -451
- package/lib/design-plan/normalize.js +29 -74
- package/lib/design-plan/parallel.js +16 -71
- package/lib/design-plan/patch.js +16 -63
- package/lib/design-plan/preview.js +8 -6
- package/lib/design-plan/validate.js +11 -71
- package/lib/process/create-process.js +50 -84
- package/lib/samples/openyida-scaffold/canvas-form-drawer.canvas.jsx +90 -20
- package/lib/samples/openyida-scaffold/canvas-nav/content.jsx +13 -93
- package/lib/samples/openyida-scaffold/canvas-nav/data.jsx +18 -100
- package/lib/samples/openyida-scaffold/canvas-nav/mixed.jsx +4 -6
- package/lib/samples/openyida-scaffold/canvas-nav/shared.jsx +5 -5
- package/lib/samples/openyida-scaffold/canvas-nav/side.jsx +2 -1
- package/lib/samples/openyida-scaffold/canvas-nav/sidebar.jsx +1 -1
- package/lib/samples/openyida-scaffold/canvas-nav/top.jsx +9 -15
- package/lib/samples/yida-canvas-table-form/table-form-batch-submit.canvas.jsx +83 -9
- package/lib/samples/yida-rechart/trend-combo.canvas.jsx +87 -14
- package/package.json +1 -3
- package/scripts/postinstall.js +3 -3
- package/yida-skills/SKILL.md +16 -19
- package/yida-skills/references/official-example-schema-patterns.md +1 -1
- package/yida-skills/references/yida-api.md +0 -4
- package/yida-skills/skills/yida-app/SKILL.md +23 -46
- package/yida-skills/skills/yida-app/workflow/parallel-work.md +6 -15
- package/yida-skills/skills/yida-app/workflow/plan/step-1-understand.md +1 -1
- package/yida-skills/skills/yida-app/workflow/plan/step-2-confirm.md +1 -1
- package/yida-skills/skills/yida-app/workflow/plan/step-4-deliver.md +15 -29
- package/yida-skills/skills/yida-app/workflow/plan/workflow.md +11 -29
- package/yida-skills/skills/yida-app/workflow/step-1-resource-context.md +2 -4
- package/yida-skills/skills/yida-app/workflow/step-2-design.md +9 -23
- package/yida-skills/skills/yida-app/workflow/step-3-create-or-reuse-app.md +4 -6
- package/yida-skills/skills/yida-app/workflow/step-4-forms-processes.md +4 -15
- package/yida-skills/skills/yida-app/workflow/step-6-main-page.md +4 -6
- package/yida-skills/skills/yida-app/workflow/step-7-page-code.md +9 -15
- package/yida-skills/skills/yida-app/workflow/step-8-publish-navigation.md +11 -25
- package/yida-skills/skills/yida-app/workflow/step-9-output-finish.md +28 -68
- package/yida-skills/skills/yida-canvas-custom-page/SKILL.md +43 -42
- package/yida-skills/skills/yida-canvas-custom-page/references/canvas-style-implementation-guide.md +44 -60
- package/yida-skills/skills/yida-canvas-custom-page/references/canvas-theme-provider.md +50 -72
- package/yida-skills/skills/yida-canvas-custom-page/references/component-library-guide.md +1 -13
- package/yida-skills/skills/yida-canvas-custom-page/references/data-bridge-guide.md +1 -140
- package/yida-skills/skills/yida-canvas-custom-page/references/navigation-and-entry-guide.md +72 -101
- package/yida-skills/skills/yida-canvas-custom-page/references/page-generation-guide.md +32 -35
- package/yida-skills/skills/yida-canvas-custom-page/scripts/build-canvas-theme.js +3 -29
- package/yida-skills/skills/yida-canvas-custom-page/scripts/canvas-theme-provider.template.jsx +6 -69
- package/yida-skills/skills/yida-canvas-data-binding/SKILL.md +0 -26
- package/yida-skills/skills/yida-create-app/SKILL.md +0 -2
- package/yida-skills/skills/yida-create-form-page/SKILL.md +58 -72
- package/yida-skills/skills/yida-create-form-page/references/advanced-form-modes.md +5 -5
- package/yida-skills/skills/yida-create-form-page/references/association-form-field.md +4 -4
- package/yida-skills/skills/yida-create-form-page/references/batch-forms.md +5 -6
- package/yida-skills/skills/yida-create-form-page/references/field-definition-guide.md +19 -7
- package/yida-skills/skills/yida-create-form-page/references/form-field-properties.md +44 -62
- package/yida-skills/skills/yida-create-page/SKILL.md +6 -14
- package/yida-skills/skills/yida-create-process/SKILL.md +2 -13
- package/yida-skills/skills/yida-custom-page/SKILL.md +0 -2
- package/yida-skills/skills/yida-custom-page/references/design-system.md +1 -1
- package/yida-skills/skills/yida-dashboard/SKILL.md +4 -5
- package/yida-skills/skills/yida-data-management/SKILL.md +2 -4
- package/yida-skills/skills/yida-data-management/references/data-format-guide.md +4 -4
- package/yida-skills/skills/yida-design/SKILL.md +14 -29
- package/yida-skills/skills/yida-design/references/app/blueprint.md +70 -0
- package/yida-skills/skills/yida-design/references/app/navigation-patterns.md +43 -0
- package/yida-skills/skills/yida-design/references/app/role-journey.md +30 -0
- package/yida-skills/skills/yida-design/references/ask-human-interaction-contract.md +42 -67
- package/yida-skills/skills/yida-design/references/asset-workflow.md +2 -6
- package/yida-skills/skills/yida-design/references/design-mode.md +4 -4
- package/yida-skills/skills/yida-design/references/page-quality-gates.md +38 -26
- package/yida-skills/skills/yida-design/references/style-design-selection.md +137 -0
- package/yida-skills/skills/yida-design/references/style-designs/_design-md-template.md +185 -0
- package/yida-skills/skills/yida-design/references/style-designs/aqua-service-progress-dashboard.md +242 -0
- package/yida-skills/skills/yida-design/references/style-designs/blue-insight-operations-dashboard.md +243 -0
- package/yida-skills/skills/yida-design/references/style-designs/blue-productivity-insight-workbench.md +242 -0
- package/yida-skills/skills/yida-design/references/style-designs/command-filter-card-console.md +304 -0
- package/yida-skills/skills/yida-design/references/style-designs/contrast-command-analytics-workbench.md +261 -0
- package/yida-skills/skills/yida-design/references/style-designs/dark-stage-analytic-dashboard.md +369 -0
- package/yida-skills/skills/yida-design/references/style-designs/filterable-card-catalog.md +354 -0
- package/yida-skills/skills/yida-design/references/style-designs/green-timeline-progress-workbench.md +250 -0
- package/yida-skills/skills/yida-design/references/style-designs/registry.md +117 -0
- package/yida-skills/skills/yida-design/references/style-designs/soft-analytic-workbench.md +348 -0
- package/yida-skills/skills/yida-design/references/style-designs/soft-blue-grid-analytic-dashboard.md +658 -0
- package/yida-skills/skills/yida-design/references/style-designs/soft-bordered-analytic-workbench.md +385 -0
- package/yida-skills/skills/yida-design/references/style-designs/soft-curated-filter-gallery.md +300 -0
- package/yida-skills/skills/yida-design/references/style-designs/soft-modular-analytic-workbench.md +404 -0
- package/yida-skills/skills/yida-design/references/style-designs/soft-progress-analytics-workbench.md +382 -0
- package/yida-skills/skills/yida-design/references/style-designs/soft-timeline-analytics-workbench.md +367 -0
- package/yida-skills/skills/yida-design/references/style-designs/teal-rail-analytics-workbench.md +341 -0
- package/yida-skills/skills/yida-design/references/theme/app-custom-theme-template.css +432 -350
- package/yida-skills/skills/yida-design/references/visual-decision-engine.md +143 -19
- package/yida-skills/skills/yida-design/references/visual-scaffold-recipes.md +27 -15
- package/yida-skills/skills/yida-design/sub_skill/page-design/SKILL.md +0 -4
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/SKILL.md +8 -22
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/assets/README.md +10 -14
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/assets/build-plan-template.html +4 -9
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/references/build-plan-compact-schema.md +27 -49
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/references/build-plan-schema.md +154 -33
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/references/visual-design.md +127 -48
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/references/visual-theme-selection.md +51 -37
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/scripts/render_build_plan.py +48 -43
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/scripts/validate_design_themes.py +190 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/README.md +98 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/airy-media-grid.md +339 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/airy-modular-clarity.md +348 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/airy-structured-clarity.md +344 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/ambient-halo-layered.md +345 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/dark-focus-layered.md +355 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/dark-luminous-modular.md +377 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/deep-stage-duotone.md +352 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/hairline-runway-clarity.md +389 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/high-contrast-modular.md +364 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/index.json +329 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/interlocked-vivid-modules.md +348 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/matrix-grid-focus.md +345 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/media-rail-inspector.md +379 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/mist-layered-signal.md +347 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/modular-rail-signal.md +352 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/mono-grid-signal.md +386 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/ribbon-ledger-lift.md +384 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/segmented-meter-clarity.md +388 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/split-rail-precision.md +341 -0
- package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/status-framed-media-grid.md +361 -0
- package/yida-skills/skills/yida-design/workflow/output-design.md +375 -117
- package/yida-skills/skills/yida-design/workflow/output-prd.md +185 -0
- package/yida-skills/skills/yida-design/workflow/step-1-read-brief.md +1 -1
- package/yida-skills/skills/yida-design/workflow/step-2-theme-system.md +29 -33
- package/yida-skills/skills/yida-design/workflow/step-4-wireframe-interaction.md +1 -3
- package/yida-skills/skills/yida-design/workflow/step-5-visual-states.md +106 -22
- package/yida-skills/skills/yida-design/workflow/step-6-handoff.md +22 -15
- package/yida-skills/skills/yida-form-permission/SKILL.md +0 -6
- package/yida-skills/skills/yida-image-assets/SKILL.md +50 -73
- package/yida-skills/skills/yida-image-assets/references/manifest-contract.md +52 -82
- package/yida-skills/skills/yida-image-assets/references/source-policy.md +15 -14
- package/yida-skills/skills/yida-integration/SKILL.md +0 -1
- package/yida-skills/skills/yida-login/SKILL.md +0 -2
- package/yida-skills/skills/yida-nav-group/SKILL.md +2 -4
- package/yida-skills/skills/yida-nav-shell/SKILL.md +12 -36
- package/yida-skills/skills/yida-nav-shell/references/nav-shell-patterns.md +136 -79
- package/yida-skills/skills/yida-page-config/SKILL.md +4 -13
- package/yida-skills/skills/yida-prd/SKILL.md +3 -5
- package/yida-skills/skills/yida-prd/references/app/blueprint.md +4 -4
- package/yida-skills/skills/yida-prd/references/app/navigation-patterns.md +3 -6
- package/yida-skills/skills/yida-prd/references/app/role-journey.md +3 -5
- package/yida-skills/skills/yida-prd/references/plan-content.md +0 -4
- package/yida-skills/skills/yida-prd/workflow/output-prd.md +11 -18
- package/yida-skills/skills/yida-prd/workflow/plan-business.md +4 -4
- package/yida-skills/skills/yida-prd/workflow/step-2-information-architecture.md +8 -11
- package/yida-skills/skills/yida-publish-page/SKILL.md +1 -9
- package/yida-skills/skills/yida-requirement-analysis/SKILL.md +39 -10
- package/yida-skills/skills/yida-requirement-analysis/workflow/prepare-brief.md +71 -40
- package/yida-skills/skills-index.json +16 -36
- package/lib/app/application-entry-urls.js +0 -31
- package/lib/app/application-style.js +0 -69
- package/lib/app/canvas-icon-exports.json +0 -6160
- package/lib/app/canvas-icon-guard.js +0 -87
- package/lib/app/canvas-navigation-guard.js +0 -84
- package/lib/app/canvas-path-guard.js +0 -78
- package/lib/app/canvas-theme-guard.js +0 -184
- package/lib/app/form-data-response-guard.js +0 -57
- package/lib/asset/asset-execution.js +0 -79
- package/lib/core/css-structure.js +0 -37
- package/lib/design/check-design.js +0 -51
- package/lib/design/document.js +0 -458
- package/lib/design/icon-contrast.js +0 -85
- package/lib/design/page-content.js +0 -11
- package/lib/design-plan/artifact-updates.js +0 -117
- package/lib/design-plan/confirmation.js +0 -13
- package/lib/design-plan/entry-navigation.js +0 -97
- package/lib/design-plan/navigation-policy.js +0 -38
- package/lib/design-plan/rebase.js +0 -60
- package/lib/design-plan/themes.js +0 -101
- package/lib/design-plan/visual-policy.js +0 -42
- package/lib/samples/openyida-scaffold/canvas-admin-entry.jsx +0 -62
- package/lib/samples/openyida-scaffold/canvas-navigation.jsx +0 -56
- package/lib/samples/openyida-scaffold/canvas-view-state.jsx +0 -74
- package/yida-skills/skills/yida-app/references/entry-navigation.md +0 -193
- package/yida-skills/skills/yida-canvas-custom-page/references/view-state-recovery.md +0 -52
- package/yida-skills/skills/yida-canvas-data-binding/references/business-action-permissions.md +0 -31
- package/yida-skills/skills/yida-design/references/application-style-library.md +0 -93
- package/yida-skills/skills/yida-design/references/application-theme-consistency.md +0 -150
- package/yida-skills/skills/yida-design/references/native-form-styles.md +0 -208
- package/yida-skills/skills/yida-design/references/navigation-decision.md +0 -53
- package/yida-skills/skills/yida-design/references/page-continuity.md +0 -42
- package/yida-skills/skills/yida-design/references/theme/application-style-recipes.css +0 -58
- package/yida-skills/skills/yida-design/references/theme-selection.md +0 -67
- package/yida-skills/skills/yida-design/scripts/validate_design_themes.py +0 -302
- package/yida-skills/skills/yida-design/templates/application-styles.json +0 -398
- package/yida-skills/skills/yida-design/templates/design-themes/README.md +0 -73
- package/yida-skills/skills/yida-design/templates/design-themes/app-amber/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-amber/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-amber/form-layout.json +0 -15
- package/yida-skills/skills/yida-design/templates/design-themes/app-editorial/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-editorial/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-editorial/form-layout.json +0 -14
- package/yida-skills/skills/yida-design/templates/design-themes/app-executive/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-executive/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-executive/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/app-finance/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-finance/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-finance/form-layout.json +0 -14
- package/yida-skills/skills/yida-design/templates/design-themes/app-glass/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-glass/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-glass/form-layout.json +0 -14
- package/yida-skills/skills/yida-design/templates/design-themes/app-graphite/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-graphite/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-graphite/form-layout.json +0 -14
- package/yida-skills/skills/yida-design/templates/design-themes/app-line/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-line/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-line/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/app-neon/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-neon/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-neon/form-layout.json +0 -14
- package/yida-skills/skills/yida-design/templates/design-themes/app-nordic/app_theme.css +0 -754
- package/yida-skills/skills/yida-design/templates/design-themes/app-nordic/design.md +0 -279
- package/yida-skills/skills/yida-design/templates/design-themes/app-nordic/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/app-paper/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-paper/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-paper/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/app-platinum/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-platinum/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-platinum/form-layout.json +0 -14
- package/yida-skills/skills/yida-design/templates/design-themes/app-plum/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-plum/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-plum/form-layout.json +0 -14
- package/yida-skills/skills/yida-design/templates/design-themes/app-pop/app_theme.css +0 -758
- package/yida-skills/skills/yida-design/templates/design-themes/app-pop/design.md +0 -281
- package/yida-skills/skills/yida-design/templates/design-themes/app-pop/form-layout.json +0 -14
- package/yida-skills/skills/yida-design/templates/design-themes/app-sage/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-sage/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-sage/form-layout.json +0 -14
- package/yida-skills/skills/yida-design/templates/design-themes/app-teal/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-teal/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-teal/form-layout.json +0 -14
- package/yida-skills/skills/yida-design/templates/design-themes/app-terminal/app_theme.css +0 -754
- package/yida-skills/skills/yida-design/templates/design-themes/app-terminal/design.md +0 -279
- package/yida-skills/skills/yida-design/templates/design-themes/app-terminal/form-layout.json +0 -14
- package/yida-skills/skills/yida-design/templates/design-themes/app-ticket/app_theme.css +0 -752
- package/yida-skills/skills/yida-design/templates/design-themes/app-ticket/design.md +0 -278
- package/yida-skills/skills/yida-design/templates/design-themes/app-ticket/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/app-wire/app_theme.css +0 -748
- package/yida-skills/skills/yida-design/templates/design-themes/app-wire/design.md +0 -274
- package/yida-skills/skills/yida-design/templates/design-themes/app-wire/form-layout.json +0 -14
- package/yida-skills/skills/yida-design/templates/design-themes/basic-tokens.json +0 -118
- package/yida-skills/skills/yida-design/templates/design-themes/dark-inset-hairline/app_theme.css +0 -690
- package/yida-skills/skills/yida-design/templates/design-themes/dark-inset-hairline/design.md +0 -382
- package/yida-skills/skills/yida-design/templates/design-themes/dark-inset-hairline/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-fine-lines/app_theme.css +0 -691
- package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-fine-lines/design.md +0 -380
- package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-fine-lines/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-signal-panels/app_theme.css +0 -696
- package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-signal-panels/design.md +0 -378
- package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-signal-panels/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/free-creative/app_theme.css +0 -689
- package/yida-skills/skills/yida-design/templates/design-themes/free-creative/design.md +0 -238
- package/yida-skills/skills/yida-design/templates/design-themes/free-creative/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/graphite-bevel-grid/app_theme.css +0 -692
- package/yida-skills/skills/yida-design/templates/design-themes/graphite-bevel-grid/design.md +0 -375
- package/yida-skills/skills/yida-design/templates/design-themes/graphite-bevel-grid/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/hairline-shared-bands/app_theme.css +0 -691
- package/yida-skills/skills/yida-design/templates/design-themes/hairline-shared-bands/design.md +0 -362
- package/yida-skills/skills/yida-design/templates/design-themes/hairline-shared-bands/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/hairline-soft-blocks/app_theme.css +0 -691
- package/yida-skills/skills/yida-design/templates/design-themes/hairline-soft-blocks/design.md +0 -409
- package/yida-skills/skills/yida-design/templates/design-themes/hairline-soft-blocks/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/index.json +0 -464
- package/yida-skills/skills/yida-design/templates/design-themes/ink-glow-soft-panels/app_theme.css +0 -701
- package/yida-skills/skills/yida-design/templates/design-themes/ink-glow-soft-panels/design.md +0 -379
- package/yida-skills/skills/yida-design/templates/design-themes/ink-glow-soft-panels/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/inset-frame-pixel-rhythm/app_theme.css +0 -691
- package/yida-skills/skills/yida-design/templates/design-themes/inset-frame-pixel-rhythm/design.md +0 -404
- package/yida-skills/skills/yida-design/templates/design-themes/inset-frame-pixel-rhythm/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/outlined-texture-duotone/app_theme.css +0 -698
- package/yida-skills/skills/yida-design/templates/design-themes/outlined-texture-duotone/design.md +0 -389
- package/yida-skills/skills/yida-design/templates/design-themes/outlined-texture-duotone/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/soft-inset-surfaces/app_theme.css +0 -691
- package/yida-skills/skills/yida-design/templates/design-themes/soft-inset-surfaces/design.md +0 -372
- package/yida-skills/skills/yida-design/templates/design-themes/soft-inset-surfaces/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/soft-outline-rhythm/app_theme.css +0 -690
- package/yida-skills/skills/yida-design/templates/design-themes/soft-outline-rhythm/design.md +0 -455
- package/yida-skills/skills/yida-design/templates/design-themes/soft-outline-rhythm/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/soft-rail-bold-band/app_theme.css +0 -698
- package/yida-skills/skills/yida-design/templates/design-themes/soft-rail-bold-band/design.md +0 -394
- package/yida-skills/skills/yida-design/templates/design-themes/soft-rail-bold-band/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/soft-spectral-panels/app_theme.css +0 -692
- package/yida-skills/skills/yida-design/templates/design-themes/soft-spectral-panels/design.md +0 -391
- package/yida-skills/skills/yida-design/templates/design-themes/soft-spectral-panels/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/warm-canvas-contrast-panels/app_theme.css +0 -711
- package/yida-skills/skills/yida-design/templates/design-themes/warm-canvas-contrast-panels/design.md +0 -408
- package/yida-skills/skills/yida-design/templates/design-themes/warm-canvas-contrast-panels/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/design-themes/warm-rail-muted-panels/app_theme.css +0 -692
- package/yida-skills/skills/yida-design/templates/design-themes/warm-rail-muted-panels/design.md +0 -383
- package/yida-skills/skills/yida-design/templates/design-themes/warm-rail-muted-panels/form-layout.json +0 -13
- package/yida-skills/skills/yida-design/templates/navigation-styles.json +0 -769
- package/yida-skills/skills/yida-requirement-analysis/references/experience-groups.md +0 -79
- package/yida-skills/skills/yida-requirement-analysis/references/handoff.md +0 -68
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* preserveScroll 只恢复当前实例内本地视图的位置;筛选、数据、草稿和路由由调用方持有。
|
|
7
|
-
* 导航节点不随 contentKey 重建;不要给整个壳添加随菜单变化的 key。
|
|
8
|
-
*/
|
|
3
|
+
// 顶部导航与内容的高度链;侧栏布局可在侧栏右侧已分配高度的区域使用 height="100%"。
|
|
4
|
+
// 只管理布局:菜单权限、URL/hash、离开未保存表单的确认由调用方处理。
|
|
5
|
+
// 合并到页面时保留组件,合并重复 import;不要额外包裹滚动卡片。
|
|
9
6
|
function CanvasNavigationContent({
|
|
10
7
|
navigation,
|
|
11
8
|
children,
|
|
@@ -17,99 +14,22 @@ function CanvasNavigationContent({
|
|
|
17
14
|
gutter = 'clamp(12px, 2vw, 24px)',
|
|
18
15
|
radius = 16,
|
|
19
16
|
background = 'transparent',
|
|
20
|
-
layout = 'workspace',
|
|
21
|
-
preserveScroll = false,
|
|
22
|
-
navigationPosition = 'sticky',
|
|
23
|
-
navigationTop = 0,
|
|
24
17
|
}) {
|
|
25
18
|
const embedded = Boolean(iframeSrc);
|
|
26
|
-
const documentLayout = layout === 'document';
|
|
27
|
-
const rootRef = React.useRef(null);
|
|
28
|
-
const navigationRef = React.useRef(null);
|
|
29
|
-
const contentRef = React.useRef(null);
|
|
30
|
-
const scrollPositions = React.useRef(new Map());
|
|
31
|
-
|
|
32
|
-
// 测量真实菜单高度,兼容窄屏换行、字体加载和菜单展开,不猜固定的 80px。
|
|
33
|
-
React.useLayoutEffect(() => {
|
|
34
|
-
if (!documentLayout) return;
|
|
35
|
-
const root = rootRef.current;
|
|
36
|
-
const nav = navigationRef.current;
|
|
37
|
-
if (!root) return;
|
|
38
|
-
const navStyle = nav ? { position: nav.style.position, left: nav.style.left, width: nav.style.width, top: nav.style.top } : null;
|
|
39
|
-
const measure = () => {
|
|
40
|
-
const navHeight = nav?.getBoundingClientRect().height || 0;
|
|
41
|
-
root.style.setProperty('--openyida-navigation-height', `${navHeight}px`);
|
|
42
|
-
const bounds = root.getBoundingClientRect();
|
|
43
|
-
// scroll 事件捕获覆盖宿主内滚动;不假设 window.scrollY 是实际滚动位置。
|
|
44
|
-
let boundary = 0;
|
|
45
|
-
for (let ancestor = root.parentElement; ancestor; ancestor = ancestor.parentElement) {
|
|
46
|
-
if (/(auto|scroll)/.test(window.getComputedStyle(ancestor).overflowY)) {
|
|
47
|
-
boundary = ancestor.getBoundingClientRect().top + ancestor.clientTop;
|
|
48
|
-
break;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
const top = Math.max(0, boundary) + navigationTop;
|
|
52
|
-
root.dataset.scrolled = String(bounds.top < top - 1);
|
|
53
|
-
if (nav && navigationPosition === 'fixed') {
|
|
54
|
-
// 仅覆盖本页宽度,不能盖住平台侧栏;离开页面底部后随本页退出。
|
|
55
|
-
Object.assign(nav.style, { position: 'fixed', left: `${bounds.left}px`, width: `${bounds.width}px`,
|
|
56
|
-
top: `${Math.min(Math.max(bounds.top, top), bounds.bottom - navHeight)}px` });
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
measure();
|
|
60
|
-
const observer = nav && window.ResizeObserver ? new window.ResizeObserver(measure) : null;
|
|
61
|
-
if (observer) observer.observe(nav);
|
|
62
|
-
if (observer) observer.observe(root);
|
|
63
|
-
window.addEventListener('resize', measure);
|
|
64
|
-
window.addEventListener('scroll', measure, true);
|
|
65
|
-
return () => {
|
|
66
|
-
if (observer) observer.disconnect();
|
|
67
|
-
window.removeEventListener('resize', measure);
|
|
68
|
-
window.removeEventListener('scroll', measure, true);
|
|
69
|
-
if (navStyle) Object.assign(nav.style, navStyle);
|
|
70
|
-
};
|
|
71
|
-
}, [documentLayout, navigation != null, navigationPosition, navigationTop]);
|
|
72
|
-
|
|
73
|
-
React.useLayoutEffect(() => {
|
|
74
|
-
const viewport = contentRef.current;
|
|
75
|
-
if (documentLayout || embedded || !preserveScroll || contentKey == null || !viewport) return;
|
|
76
|
-
const position = scrollPositions.current.get(contentKey);
|
|
77
|
-
viewport.scrollTop = position?.top || 0;
|
|
78
|
-
viewport.scrollLeft = position?.left || 0;
|
|
79
|
-
}, [contentKey, documentLayout, embedded, preserveScroll]);
|
|
80
|
-
|
|
81
|
-
if (documentLayout && embedded) throw new Error('CanvasNavigationContent: iframeSrc requires workspace layout');
|
|
82
|
-
if (!['sticky', 'fixed'].includes(navigationPosition)) throw new Error('CanvasNavigationContent: navigationPosition must be sticky or fixed');
|
|
83
19
|
return (
|
|
84
|
-
<div
|
|
85
|
-
height:
|
|
86
|
-
|
|
87
|
-
// 长页不创建第二层滚动容器;导航和 main 共享网格区域,背景可到达导航背后。
|
|
88
|
-
overflow: documentLayout ? 'visible' : 'hidden', background,
|
|
89
|
-
position: 'relative', isolation: 'isolate',
|
|
20
|
+
<div className="openyida-nav-layout" style={{
|
|
21
|
+
height, minHeight: 0, minWidth: 0, display: 'flex', flexDirection: 'column',
|
|
22
|
+
overflow: 'hidden', background,
|
|
90
23
|
}}>
|
|
91
|
-
{navigation != null && <div
|
|
92
|
-
flexShrink: 0, minWidth: 0, zIndex: 10,
|
|
93
|
-
...(documentLayout ? { gridArea: '1 / 1', alignSelf: 'start', position: 'sticky', top: navigationTop } : {}),
|
|
94
|
-
}}>{navigation}</div>}
|
|
24
|
+
{navigation != null && <div style={{ flexShrink: 0 }}>{navigation}</div>}
|
|
95
25
|
<main className="openyida-nav-main" aria-label={title} style={{
|
|
96
|
-
display:
|
|
97
|
-
|
|
98
|
-
minWidth: 0, overflow: documentLayout ? 'visible' : 'hidden',
|
|
99
|
-
padding: documentLayout ? 0 : gutter, boxSizing: 'border-box',
|
|
100
|
-
...(documentLayout ? { gridArea: '1 / 1' } : {}),
|
|
26
|
+
display: 'flex', flexDirection: 'column', flex: '1 1 0', minHeight: 0,
|
|
27
|
+
minWidth: 0, overflow: 'hidden', padding: gutter, boxSizing: 'border-box',
|
|
101
28
|
}}>
|
|
102
|
-
<div key={contentKey}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
scrollPositions.current.set(contentKey, { top: viewport.scrollTop, left: viewport.scrollLeft });
|
|
107
|
-
}
|
|
108
|
-
}} style={{
|
|
109
|
-
position: 'relative', flex: documentLayout ? undefined : '1 1 0', minHeight: documentLayout ? 'auto' : 0, minWidth: 0,
|
|
110
|
-
width: '100%', maxWidth: documentLayout ? undefined : maxWidth,
|
|
111
|
-
margin: '0 auto', borderRadius: documentLayout ? 0 : radius,
|
|
112
|
-
overflow: documentLayout ? 'visible' : embedded ? 'hidden' : 'auto',
|
|
29
|
+
<div key={contentKey} className="openyida-nav-content" style={{
|
|
30
|
+
position: 'relative', flex: '1 1 0', minHeight: 0, minWidth: 0,
|
|
31
|
+
width: '100%', maxWidth, margin: '0 auto', borderRadius: radius,
|
|
32
|
+
overflow: embedded ? 'hidden' : 'auto',
|
|
113
33
|
}}>
|
|
114
34
|
{embedded ? <iframe title={title} src={iframeSrc} style={{
|
|
115
35
|
position: 'absolute', inset: 0, width: '100%', height: '100%',
|
|
@@ -1,131 +1,48 @@
|
|
|
1
|
-
/**
|
|
2
|
-
function
|
|
3
|
-
if (!['local', 'platform', 'independent'].includes(mode)) throw new Error('未知导航模式');
|
|
4
|
-
for (const item of items) {
|
|
5
|
-
if (Array.isArray(item.children) && item.children.length) {
|
|
6
|
-
validateCanvasNavigationItems(item.children, mode);
|
|
7
|
-
} else if (mode === 'local') {
|
|
8
|
-
if (item.targetType !== 'local' || !String(item.key || '').trim() || !String(item.viewKey || '').trim()
|
|
9
|
-
|| item.href || item.url) throw new Error('local 模式只接受含 key/viewKey 的本页菜单,真实页面请使用 platform 或 independent');
|
|
10
|
-
} else if (mode === 'platform' && (item.targetType === 'local' || (!item.formUuid && !item.navUuid))) {
|
|
11
|
-
throw new Error('页内菜单不能按平台导航过滤:使用 mode=local 或直接管理本地视图;真实页面需绑定 formUuid/navUuid');
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function filterCanvasNavigation(items, navs, hiddenNav = [], { mode = 'platform', access } = {}) {
|
|
17
|
-
validateCanvasNavigationItems(items, mode);
|
|
18
|
-
const isHidden = value => value === true || value === 'y' || value === 'true';
|
|
1
|
+
/** PRD 决定菜单结构,平台结果只过滤不可见入口;同一资源可对应多个任务入口。 */
|
|
2
|
+
function filterCanvasNavigation(items, navs, hiddenNav = []) {
|
|
19
3
|
const visibleIds = new Set();
|
|
20
4
|
function collectVisible(nodes) {
|
|
21
5
|
for (const nav of nodes) {
|
|
22
|
-
if (
|
|
6
|
+
if (nav.hidden || hiddenNav.includes(nav.slug) || hiddenNav.includes(nav.navUuid)) continue;
|
|
23
7
|
if (nav.navUuid) visibleIds.add(nav.navUuid);
|
|
24
|
-
if (nav.formUuid) visibleIds.add(nav.formUuid);
|
|
25
8
|
collectVisible(nav.children || []);
|
|
26
9
|
}
|
|
27
10
|
}
|
|
28
|
-
|
|
29
|
-
const validRequirement = requirement => requirement && typeof requirement.formUuid === 'string' && requirement.formUuid.trim()
|
|
30
|
-
&& typeof requirement.operation === 'string' && requirement.operation.trim()
|
|
31
|
-
&& (requirement.viewUuid === undefined || (typeof requirement.viewUuid === 'string' && requirement.viewUuid.trim()));
|
|
32
|
-
const grantKey = requirement => JSON.stringify([requirement.formUuid, requirement.viewUuid || '', requirement.operation]);
|
|
33
|
-
const grants = new Map();
|
|
34
|
-
for (const grant of access?.grants || []) {
|
|
35
|
-
if (!validRequirement(grant)) continue;
|
|
36
|
-
const key = grantKey(grant);
|
|
37
|
-
// 重复结果存在拒绝或未知时,不采用其中的允许结果。
|
|
38
|
-
grants.set(key, grant.allowed === true && grants.get(key) !== false);
|
|
39
|
-
}
|
|
40
|
-
function allowed(item, leaf) {
|
|
41
|
-
const requirements = item.access;
|
|
42
|
-
if (requirements === undefined) return mode === 'local' || mode === 'platform' || (!leaf && !item.formUuid && !item.navUuid);
|
|
43
|
-
if (!Array.isArray(requirements) || !requirements.length || !requirements.every(validRequirement)) return false;
|
|
44
|
-
if (leaf && mode !== 'local') {
|
|
45
|
-
const operation = item.targetType === 'submission' ? 'OPERATE_CREATE' : 'OPERATE_VIEW';
|
|
46
|
-
if (!item.formUuid || !requirements.some(requirement => requirement.formUuid === item.formUuid
|
|
47
|
-
&& (requirement.viewUuid || '') === (item.viewUuid || item.params?.viewUuid || '') && requirement.operation === operation)) return false;
|
|
48
|
-
}
|
|
49
|
-
return requirements.every(requirement => grants.get(grantKey(requirement)) === true);
|
|
50
|
-
}
|
|
11
|
+
collectVisible(navs);
|
|
51
12
|
function filterItems(nodes) {
|
|
52
13
|
return nodes.flatMap(item => {
|
|
53
14
|
const resourceId = item.navUuid || item.formUuid;
|
|
54
|
-
if (
|
|
55
|
-
if (item.children !== undefined && !Array.isArray(item.children)) return [];
|
|
15
|
+
if (item.hidden || (resourceId && !visibleIds.has(resourceId))) return [];
|
|
56
16
|
if (item.children?.length) {
|
|
57
|
-
if (!allowed(item, false)) return [];
|
|
58
17
|
const children = filterItems(item.children);
|
|
59
18
|
return children.length ? [{ ...item, children }] : [];
|
|
60
19
|
}
|
|
61
|
-
|
|
62
|
-
return mode !== 'platform' || visibleIds.has(resourceId) ? [item] : [];
|
|
20
|
+
return visibleIds.has(resourceId) ? [item] : [];
|
|
63
21
|
});
|
|
64
22
|
}
|
|
65
23
|
return filterItems(items);
|
|
66
24
|
}
|
|
67
25
|
|
|
68
|
-
/**
|
|
69
|
-
function selectCanvasNavigation(items, requestedKey, defaultKey) {
|
|
70
|
-
const leaves = [];
|
|
71
|
-
function collect(nodes) {
|
|
72
|
-
for (const item of nodes) {
|
|
73
|
-
if (item.children?.length) collect(item.children);
|
|
74
|
-
else if (!item.disabled) leaves.push(item);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
collect(items);
|
|
78
|
-
return leaves.find(item => item.key === requestedKey) || leaves.find(item => item.key === defaultKey) || leaves[0];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** 用途决定路由;独立页面走 custom,管理视图保留真实 viewUuid。 */
|
|
26
|
+
/** 按入口任务选择提交页或管理页;targetType 由 PRD 明确,表单类型不决定入口用途。 */
|
|
82
27
|
function buildCanvasNavigationUrl(item, appType, { embedded = false } = {}) {
|
|
83
28
|
if (item.targetType === 'url') return item.url;
|
|
84
|
-
if (!['submission', 'page'
|
|
29
|
+
if (!['submission', 'page'].includes(item.targetType)) throw new Error('请明确导航入口用途');
|
|
85
30
|
const formUuid = item.formUuid || item.navUuid;
|
|
86
31
|
if (!appType || !formUuid) throw new Error('缺少导航目标');
|
|
87
32
|
const query = new URLSearchParams(item.params || {});
|
|
88
|
-
const route =
|
|
89
|
-
if (item.viewUuid) {
|
|
90
|
-
if (route !== 'workbench') throw new Error('管理视图必须使用 workbench 入口');
|
|
91
|
-
query.set('viewUuid', item.viewUuid);
|
|
92
|
-
}
|
|
93
|
-
if (route === 'custom') query.delete('isRenderNav');
|
|
33
|
+
const route = item.targetType === 'submission' ? 'submission' : 'workbench';
|
|
94
34
|
if (embedded) {
|
|
95
|
-
if (route === '
|
|
96
|
-
else query.set('
|
|
35
|
+
if (route === 'submission') query.set('isRenderNav', 'false');
|
|
36
|
+
else query.set('iframe', 'true');
|
|
97
37
|
}
|
|
98
38
|
const suffix = query.toString();
|
|
99
39
|
return `/${encodeURIComponent(appType)}/${route}/${encodeURIComponent(formUuid)}${suffix ? '?' + suffix : ''}`;
|
|
100
40
|
}
|
|
101
41
|
|
|
102
|
-
/**
|
|
103
|
-
async function loadCanvasNavigation({ items, appType, formUuid, csrfToken, hiddenNav = [], signal
|
|
42
|
+
/** 使用当前访问者的登录态读取导航;csrfToken、hiddenNav 由当前页面运行态提供。 */
|
|
43
|
+
async function loadCanvasNavigation({ items, appType, formUuid, csrfToken, hiddenNav = [], signal }) {
|
|
104
44
|
if (!Array.isArray(items)) throw new Error('缺少 PRD 导航配置');
|
|
105
|
-
|
|
106
|
-
if (mode !== 'local' && !appType) throw new Error('缺少应用标识');
|
|
107
|
-
let needsAccess = mode === 'independent';
|
|
108
|
-
const requirements = [];
|
|
109
|
-
function collect(nodes) {
|
|
110
|
-
for (const item of nodes) {
|
|
111
|
-
if (item.access !== undefined) {
|
|
112
|
-
needsAccess = true;
|
|
113
|
-
if (Array.isArray(item.access)) requirements.push(...item.access);
|
|
114
|
-
}
|
|
115
|
-
if (Array.isArray(item.children)) collect(item.children);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
collect(items);
|
|
119
|
-
let access;
|
|
120
|
-
if (needsAccess) {
|
|
121
|
-
if (!appType) throw new Error('权限查询需要应用标识');
|
|
122
|
-
if (typeof resolveAccess !== 'function') throw new Error('缺少当前访问者的权限查询能力');
|
|
123
|
-
access = await resolveAccess({ appType, requirements, signal });
|
|
124
|
-
if (access?.appType !== appType || !Array.isArray(access.grants)) throw new Error('权限查询失败,请重试');
|
|
125
|
-
}
|
|
126
|
-
if (signal?.aborted) throw new Error('导航加载已取消');
|
|
127
|
-
// 独立菜单不依赖平台树是否含有被隐藏的资源;授权必须来自上述实时权限查询。
|
|
128
|
-
if (mode !== 'platform') return filterCanvasNavigation(items, [], [], { mode, access });
|
|
45
|
+
if (!appType) throw new Error('缺少应用标识');
|
|
129
46
|
const query = new URLSearchParams({ _api: 'nattyFetch', _mock: 'false' });
|
|
130
47
|
if (formUuid) query.set('formUuid', formUuid);
|
|
131
48
|
if (csrfToken) query.set('_csrf_token', csrfToken);
|
|
@@ -136,7 +53,8 @@ async function loadCanvasNavigation({ items, appType, formUuid, csrfToken, hidde
|
|
|
136
53
|
});
|
|
137
54
|
if (!response.ok) throw new Error('导航加载失败,请重试');
|
|
138
55
|
const result = await response.json();
|
|
139
|
-
if (result.success !== true || !Array.isArray(result.content?.navs))
|
|
140
|
-
|
|
141
|
-
|
|
56
|
+
if (result.success !== true || !Array.isArray(result.content?.navs)) {
|
|
57
|
+
throw new Error('导航加载失败,请重试');
|
|
58
|
+
}
|
|
59
|
+
return filterCanvasNavigation(items, result.content.navs, hiddenNav);
|
|
142
60
|
}
|
|
@@ -4,14 +4,12 @@ function CanvasNav({ items = [], activeKey, onSelect, title, logo, actions, chil
|
|
|
4
4
|
return <div className="oy-canvas-nav oy-nav-mixed">
|
|
5
5
|
<style>{CANVAS_NAV_CSS + `
|
|
6
6
|
.oy-nav-mixed { display: flex; flex-direction: column; }
|
|
7
|
-
.oy-nav-mixed .oy-nav-header {
|
|
8
|
-
.oy-nav-mixed .oy-nav-groups { display: flex; flex: 1; min-width: 0;
|
|
9
|
-
.oy-nav-mixed .oy-nav-groups .oy-nav-item { min-height: var(--pod-nav-top-tab-height, 40px); padding: var(--pod-nav-top-tab-item-padding, 0 12px); max-width: var(--pod-nav-top-tab-item-max-width, 240px); }
|
|
10
|
-
.oy-nav-mixed .oy-nav-groups .oy-nav-item > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
7
|
+
.oy-nav-mixed .oy-nav-header { display: flex; flex-wrap: wrap; align-items: center; gap: var(--pod-nav-l-header-gap, 24px); padding: var(--pod-nav-l-header-padding, 8px 16px); border-bottom: 1px solid var(--pod-nav-sub-divider-color, var(--color-line1-1, #ddd)); }
|
|
8
|
+
.oy-nav-mixed .oy-nav-groups { display: flex; flex: 1; min-width: 0; overflow-x: auto; }
|
|
11
9
|
.oy-nav-mixed .oy-nav-body { display: flex; flex: 1; }
|
|
12
|
-
.oy-canvas-nav.oy-nav-mixed .oy-nav-sidebar { padding: var(--pod-nav-l-aside-padding, 8px); }
|
|
13
10
|
.oy-nav-mixed .oy-nav-content { flex: 1; }
|
|
14
|
-
.oy-nav-mixed .oy-nav-menu { display: flex; flex-direction: column; gap: var(--pod-nav-
|
|
11
|
+
.oy-nav-mixed .oy-nav-menu { display: flex; flex-direction: column; gap: var(--pod-nav-slide-aside-gap, 12px); }
|
|
12
|
+
.oy-nav-mixed .oy-nav-item[aria-current="page"] { box-shadow: inset 0 -2px var(--pod-nav-tab-line-selected-color, var(--color-brand1-6, #1677ff)); }
|
|
15
13
|
@media (max-width: 767px) {
|
|
16
14
|
.oy-nav-mixed .oy-nav-groups { flex-basis: 100%; }
|
|
17
15
|
.oy-nav-mixed .oy-nav-body { display: block; }
|
|
@@ -14,12 +14,12 @@ const CANVAS_NAV_CSS = `
|
|
|
14
14
|
.oy-canvas-nav .oy-nav-brand > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
15
15
|
.oy-canvas-nav .oy-nav-item {
|
|
16
16
|
box-sizing: border-box; display: flex; flex-shrink: 0; align-items: center; gap: var(--pod-nav-logo-gap, 8px);
|
|
17
|
-
min-height: var(--pod-nav-menu-item-height, 40px); padding: var(--pod-nav-
|
|
18
|
-
border:
|
|
19
|
-
color: var(--pod-nav-item-text-color, var(--color-text1-4, #1f2329)); font: inherit; font-size: var(--pod-nav-menu-font-size, 14px);
|
|
17
|
+
min-height: var(--pod-nav-menu-item-height, 40px); padding: var(--pod-nav-top-tab-item-padding, 0 12px);
|
|
18
|
+
border: 0; border-radius: var(--pod-nav-menu-item-radius, 8px); background: transparent;
|
|
19
|
+
color: var(--pod-nav-item-text-color, var(--color-text1-4, #1f2329)); font: inherit; font-size: var(--pod-nav-menu-font-size, 14px); text-decoration: none; text-align: start; cursor: pointer;
|
|
20
20
|
}
|
|
21
|
-
.oy-canvas-nav .oy-nav-item:hover:not(:disabled) {
|
|
22
|
-
.oy-canvas-nav .oy-nav-item[aria-current="page"]
|
|
21
|
+
.oy-canvas-nav .oy-nav-item:hover:not(:disabled) { background: var(--pod-nav-menu-bg-hover-color, var(--color-fill1-2, #f2f3f5)); color: var(--pod-nav-item-text-hover-color, inherit); }
|
|
22
|
+
.oy-canvas-nav .oy-nav-item[aria-current="page"] { background: var(--pod-nav-menu-bg-selected-color, var(--color-brand1-1, #e8f2ff)); color: var(--pod-nav-item-text-selected-color, var(--color-brand1-6, #1677ff)); font-weight: var(--pod-nav-menu-item-selected-font-weight, 600); }
|
|
23
23
|
.oy-canvas-nav .oy-nav-item:disabled { color: var(--pod-nav-item-text-disabled-color, var(--color-text1-1, #999)); cursor: not-allowed; }
|
|
24
24
|
.oy-canvas-nav .oy-nav-item:focus-visible { outline: 2px solid var(--pod-nav-tab-line-selected-color, var(--color-brand1-6, #1677ff)); outline-offset: -2px; }
|
|
25
25
|
.oy-canvas-nav .oy-nav-item svg { flex-shrink: 0; width: var(--pod-nav-platform-action-icon-size, 18px); height: var(--pod-nav-platform-action-icon-size, 18px); }
|
|
@@ -5,7 +5,8 @@ function CanvasNav({ items = [], activeKey, onSelect, title, logo, actions, chil
|
|
|
5
5
|
.oy-nav-side { display: flex; }
|
|
6
6
|
.oy-nav-side .oy-nav-content { flex: 1; }
|
|
7
7
|
.oy-nav-side .oy-nav-brand { min-height: var(--pod-nav-platform-header-height, 48px); }
|
|
8
|
-
.oy-nav-side .oy-nav-menu { display: flex; flex-direction: column; gap: var(--pod-nav-
|
|
8
|
+
.oy-nav-side .oy-nav-menu { display: flex; flex-direction: column; gap: var(--pod-nav-slide-aside-gap, 12px); }
|
|
9
|
+
.oy-nav-side .oy-nav-item[aria-current="page"] { box-shadow: inset 3px 0 var(--pod-nav-tab-line-selected-color, var(--color-brand1-6, #1677ff)); }
|
|
9
10
|
@media (max-width: 767px) { .oy-nav-side { display: block; } }
|
|
10
11
|
`}</style>
|
|
11
12
|
<CanvasSidebar title={title} logo={logo} actions={actions} activeKey={activeKey} defaultWidth={sidebarWidth} defaultCollapsed={defaultCollapsed}>
|
|
@@ -41,7 +41,7 @@ function CanvasSidebar({ children, title, logo, actions, activeKey, defaultWidth
|
|
|
41
41
|
onClick={event => { if (mobile && event.target.closest('.oy-nav-menu .oy-nav-item')) setMobileOpen(false); }}
|
|
42
42
|
style={{ '--oy-sidebar-width': width === null ? (typeof defaultWidth === 'number' ? `${defaultWidth}px` : defaultWidth) : `${clamp(width)}px`, '--oy-sidebar-max-width': `${maxWidth}px` }}>
|
|
43
43
|
<style>{`
|
|
44
|
-
.oy-canvas-nav .oy-nav-sidebar { position: relative; box-sizing: border-box; flex: 0 0 auto; min-width: 0; width: clamp(180px, var(--oy-sidebar-width, var(--shell-dark-aside-width, 216px)), var(--oy-sidebar-max-width, 400px)); padding: var(--pod-nav-
|
|
44
|
+
.oy-canvas-nav .oy-nav-sidebar { position: relative; box-sizing: border-box; flex: 0 0 auto; min-width: 0; width: clamp(180px, var(--oy-sidebar-width, var(--shell-dark-aside-width, 216px)), var(--oy-sidebar-max-width, 400px)); padding: var(--pod-nav-l-aside-padding, 8px); border-right: 1px solid var(--pod-nav-sub-divider-color, var(--color-line1-1, #ddd)); }
|
|
45
45
|
.oy-canvas-nav .oy-sidebar-toggle { margin-left: auto; flex-shrink: 0; justify-content: center; padding: 0 8px; }
|
|
46
46
|
.oy-canvas-nav .oy-sidebar-items { min-width: 0; }
|
|
47
47
|
.oy-canvas-nav .oy-nav-sidebar .oy-nav-item > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
import { Menu } from 'lucide-react';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
function CanvasNav({ items = [], activeKey, onSelect, title, logo, actions, children, floating =
|
|
3
|
+
/** 顶部导航默认使用浮导;floating=false 时使用贴边通栏,窄屏通过按钮展开菜单。 */
|
|
4
|
+
function CanvasNav({ items = [], activeKey, onSelect, title, logo, actions, children, floating = true }) {
|
|
5
5
|
const [expanded, setExpanded] = React.useState(false);
|
|
6
6
|
const menuId = React.useId();
|
|
7
7
|
React.useEffect(() => setExpanded(false), [activeKey]);
|
|
8
|
-
return <div className={'oy-canvas-nav oy-nav-top' + (floating ? ' is-floating' : '')
|
|
8
|
+
return <div className={'oy-canvas-nav oy-nav-top' + (floating ? ' is-floating' : '')}>
|
|
9
9
|
<style>{CANVAS_NAV_CSS + `
|
|
10
|
-
.oy-nav-top .oy-nav-header {
|
|
11
|
-
.oy-nav-top.is-header-only { min-height: 0; background: transparent; }
|
|
12
|
-
.openyida-nav-layout[data-layout="document"][data-scrolled="false"] .oy-nav-top.is-overlay .oy-nav-header:not(.is-expanded) { background: transparent; color: var(--openyida-navigation-overlay-color, #fff); border-color: transparent; }
|
|
13
|
-
.openyida-nav-layout[data-layout="document"][data-scrolled="false"] .oy-nav-top.is-overlay .oy-nav-header:not(.is-expanded) .oy-nav-brand,
|
|
14
|
-
.openyida-nav-layout[data-layout="document"][data-scrolled="false"] .oy-nav-top.is-overlay .oy-nav-header:not(.is-expanded) .oy-nav-item:not(:disabled) { color: inherit; }
|
|
15
|
-
.openyida-nav-layout[data-layout="document"][data-scrolled="false"] .oy-nav-top.is-overlay .oy-nav-header:not(.is-expanded) .oy-nav-item:is(:hover,[aria-current="page"]):not(:disabled) { background: var(--openyida-navigation-overlay-active-bg, rgba(255,255,255,.16)); }
|
|
10
|
+
.oy-nav-top .oy-nav-header { display: flex; flex-wrap: wrap; align-items: center; gap: var(--pod-nav-top-header-gap, 24px); padding: var(--pod-nav-top-header-padding, 8px 16px); border-bottom: 1px solid var(--pod-nav-sub-divider-color, var(--color-line1-1, #ddd)); }
|
|
16
11
|
.oy-nav-top.is-floating { padding-top: 16px; box-sizing: border-box; }
|
|
17
|
-
.oy-nav-top.is-floating .oy-nav-header { position: sticky; top: 16px; z-index: 10; margin: 0 16px; border: 1px solid var(--pod-nav-sub-divider-color, var(--color-line1-1, #ddd)); border-radius: var(--pod-
|
|
18
|
-
.oy-nav-top .oy-nav-menu { display: flex; flex: 1; min-width: 0;
|
|
19
|
-
.oy-nav-top .oy-nav-
|
|
20
|
-
.oy-nav-top .oy-nav-menu .oy-nav-item > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
12
|
+
.oy-nav-top.is-floating .oy-nav-header { position: sticky; top: 16px; z-index: 10; margin: 0 16px; border: 1px solid var(--pod-nav-sub-divider-color, var(--color-line1-1, #ddd)); border-radius: var(--pod-nav-menu-container-radius, 16px); box-shadow: var(--pod-nav-popup-shadow, 0 8px 24px rgba(0,0,0,.12)); }
|
|
13
|
+
.oy-nav-top .oy-nav-menu { display: flex; flex: 1; min-width: 0; overflow-x: auto; }
|
|
14
|
+
.oy-nav-top .oy-nav-item[aria-current="page"] { box-shadow: inset 0 -2px var(--pod-nav-tab-line-selected-color, var(--color-brand1-6, #1677ff)); }
|
|
21
15
|
.oy-nav-top .oy-nav-toggle { display: none; margin-left: auto; }
|
|
22
16
|
@media (max-width: 767px) {
|
|
23
17
|
.oy-nav-top .oy-nav-header { gap: var(--pod-nav-logo-gap, 8px); }
|
|
@@ -26,12 +20,12 @@ function CanvasNav({ items = [], activeKey, onSelect, title, logo, actions, chil
|
|
|
26
20
|
.oy-nav-top .oy-nav-menu:not(.is-expanded) { display: none; }
|
|
27
21
|
}
|
|
28
22
|
`}</style>
|
|
29
|
-
<header className=
|
|
23
|
+
<header className="oy-nav-header oy-nav-surface">
|
|
30
24
|
<div className="oy-nav-brand">{logo}<span>{title}</span></div>
|
|
31
25
|
<button className="oy-nav-item oy-nav-toggle" type="button" aria-label={expanded ? '收起导航' : '展开导航'} aria-controls={menuId} aria-expanded={expanded} onClick={() => setExpanded(!expanded)}><Menu aria-hidden="true" /></button>
|
|
32
26
|
<nav id={menuId} aria-label="应用导航" className={'oy-nav-menu' + (expanded ? ' is-expanded' : '')}>{items.map(item => <CanvasNavItem key={item.key} item={item} activeKey={activeKey} onSelect={onSelect ? (selected) => { setExpanded(false); onSelect(selected); } : undefined} />)}</nav>
|
|
33
27
|
{actions}
|
|
34
28
|
</header>
|
|
35
|
-
|
|
29
|
+
<main className="oy-nav-content" aria-label={items.find(item => item.key === activeKey)?.label}>{children}</main>
|
|
36
30
|
</div>;
|
|
37
31
|
}
|
|
@@ -110,10 +110,86 @@ function getBridgeState(props) {
|
|
|
110
110
|
return { ready: true, reason: '', writeBridge, fieldMap };
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
// @openyida-canvas-theme:start
|
|
114
|
+
// Standalone samples keep this fragment identical; see canvas-theme.test.js.
|
|
115
|
+
function readCanvasTheme(root, fallback) {
|
|
116
|
+
const roles = {
|
|
117
|
+
colorPrimary: '--color-brand1-6', colorLink: '--color-brand1-6',
|
|
118
|
+
colorPrimaryHover: '--color-brand1-5', colorPrimaryActive: '--color-brand1-9',
|
|
119
|
+
colorBgLayout: ['--pod-page-bg-color', '--color-white'],
|
|
120
|
+
colorBgContainer: ['--pod-card-bg-color', '--color-white'],
|
|
121
|
+
colorBgElevated: ['--pod-card-bg-color', '--color-white'], colorText: '--color-text1-4',
|
|
122
|
+
colorTextHeading: '--color-text1-4', colorTextSecondary: '--color-text1-3',
|
|
123
|
+
colorTextDescription: '--color-text1-3', colorTextPlaceholder: '--color-text1-10',
|
|
124
|
+
colorBorder: '--color-line1-2', colorBorderSecondary: '--color-line1-1',
|
|
125
|
+
colorFillAlter: '--color-fill1-1', colorFillSecondary: '--color-fill1-2',
|
|
126
|
+
};
|
|
127
|
+
const token = { ...fallback };
|
|
128
|
+
if (!root) return token;
|
|
129
|
+
const doc = root.ownerDocument;
|
|
130
|
+
const view = doc.defaultView;
|
|
131
|
+
const scope = view.getComputedStyle(root);
|
|
132
|
+
const probe = doc.createElement('span');
|
|
133
|
+
probe.style.cssText = 'position:absolute;visibility:hidden;pointer-events:none;';
|
|
134
|
+
root.appendChild(probe);
|
|
135
|
+
try {
|
|
136
|
+
Object.keys(roles).forEach((role) => {
|
|
137
|
+
const names = Array.isArray(roles[role]) ? roles[role] : [roles[role]];
|
|
138
|
+
const value = names.map((name) => scope.getPropertyValue(name).trim()).find(Boolean) || '';
|
|
139
|
+
if (!value || !view.CSS.supports('color', value)) return;
|
|
140
|
+
probe.style.color = value;
|
|
141
|
+
const color = view.getComputedStyle(probe).color;
|
|
142
|
+
if (color) token[role] = color;
|
|
143
|
+
});
|
|
144
|
+
} finally {
|
|
145
|
+
probe.remove();
|
|
146
|
+
}
|
|
147
|
+
return token;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function useCanvasTheme(fallback) {
|
|
151
|
+
const rootRef = React.useRef(null);
|
|
152
|
+
const fallbackRef = React.useRef(fallback);
|
|
153
|
+
const [token, setToken] = React.useState(fallback);
|
|
154
|
+
React.useLayoutEffect(() => {
|
|
155
|
+
const root = rootRef.current;
|
|
156
|
+
if (!root) return undefined;
|
|
157
|
+
const doc = root.ownerDocument;
|
|
158
|
+
const view = doc.defaultView;
|
|
159
|
+
let frame;
|
|
160
|
+
const refresh = () => {
|
|
161
|
+
const next = readCanvasTheme(root, fallbackRef.current);
|
|
162
|
+
setToken((previous) => JSON.stringify(previous) === JSON.stringify(next) ? previous : next);
|
|
163
|
+
};
|
|
164
|
+
const schedule = () => {
|
|
165
|
+
view.cancelAnimationFrame(frame);
|
|
166
|
+
frame = view.requestAnimationFrame(refresh);
|
|
167
|
+
};
|
|
168
|
+
refresh();
|
|
169
|
+
// Observe only theme-bearing ancestors and stylesheet changes, not business DOM.
|
|
170
|
+
const observer = new view.MutationObserver(schedule);
|
|
171
|
+
for (let node = root; node; node = node.parentElement) {
|
|
172
|
+
observer.observe(node, { attributes: true });
|
|
173
|
+
}
|
|
174
|
+
if (doc.head) observer.observe(doc.head, { subtree: true, childList: true, characterData: true, attributes: true });
|
|
175
|
+
doc.addEventListener('load', schedule, true);
|
|
176
|
+
view.addEventListener('resize', schedule);
|
|
177
|
+
view.addEventListener('openyida:theme-change', schedule);
|
|
178
|
+
return () => {
|
|
179
|
+
observer.disconnect();
|
|
180
|
+
view.cancelAnimationFrame(frame);
|
|
181
|
+
doc.removeEventListener('load', schedule, true);
|
|
182
|
+
view.removeEventListener('resize', schedule);
|
|
183
|
+
view.removeEventListener('openyida:theme-change', schedule);
|
|
184
|
+
};
|
|
185
|
+
}, []);
|
|
186
|
+
return { rootRef, token };
|
|
187
|
+
}
|
|
188
|
+
// @openyida-canvas-theme:end
|
|
114
189
|
|
|
115
|
-
function
|
|
190
|
+
function YidaComp(props) {
|
|
116
191
|
const [modal, modalContextHolder] = Modal.useModal();
|
|
192
|
+
const { rootRef, token } = useCanvasTheme({ colorPrimary: "#1677ff", borderRadius: 9 });
|
|
117
193
|
const formUuid = props && props.formUuid ? props.formUuid : 'sample-unbound';
|
|
118
194
|
const draftKey = 'openyida_canvas_table_form_draft_' + formUuid;
|
|
119
195
|
const [rows, setRows] = useState(() => loadDraft(draftKey));
|
|
@@ -383,7 +459,9 @@ function PageContent(props) {
|
|
|
383
459
|
const pendingCount = rows.filter((row) => row._status !== 'submitted').length;
|
|
384
460
|
|
|
385
461
|
return (
|
|
386
|
-
|
|
462
|
+
<ConfigProvider
|
|
463
|
+
theme={{ token }}
|
|
464
|
+
>
|
|
387
465
|
<style>{`
|
|
388
466
|
.canvas-table-page {
|
|
389
467
|
display: flow-root;
|
|
@@ -425,7 +503,7 @@ function PageContent(props) {
|
|
|
425
503
|
}
|
|
426
504
|
`}</style>
|
|
427
505
|
|
|
428
|
-
<div className="canvas-table-page">
|
|
506
|
+
<div ref={rootRef} className="canvas-table-page">
|
|
429
507
|
{modalContextHolder}
|
|
430
508
|
<div className="canvas-table-shell">
|
|
431
509
|
<div className="canvas-table-header">
|
|
@@ -498,12 +576,8 @@ function PageContent(props) {
|
|
|
498
576
|
</div>
|
|
499
577
|
</div>
|
|
500
578
|
</div>
|
|
501
|
-
|
|
579
|
+
</ConfigProvider>
|
|
502
580
|
);
|
|
503
581
|
}
|
|
504
582
|
|
|
505
|
-
function YidaComp(props) {
|
|
506
|
-
return <CanvasThemeProvider><PageContent {...props} /></CanvasThemeProvider>;
|
|
507
|
-
}
|
|
508
|
-
|
|
509
583
|
export default YidaComp;
|