@beehexa/design-rules 2611.3.3 → 2611.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +1 -1
  2. package/dist/AGENTS.md +1 -7
  3. package/dist/catalog.json +153 -125
  4. package/dist/docs/scripts/color-pairs.mjs +5 -1
  5. package/dist/docs/scripts/token-utils.mjs +16 -1
  6. package/dist/docs/src/components/ColorDemo.astro +5 -5
  7. package/dist/docs/src/components/ElevationDemo.astro +196 -0
  8. package/dist/docs/src/components/LayoutDemo.astro +1 -1
  9. package/dist/docs/src/components/OpacityDemo.astro +95 -0
  10. package/dist/docs/src/components/ShapeDemo.astro +11 -10
  11. package/dist/docs/src/components/ShapePin.astro +5 -3
  12. package/dist/docs/src/components/ZIndexDemo.astro +102 -0
  13. package/dist/docs/src/content/foundations/styles/border.mdx +3 -3
  14. package/dist/docs/src/content/foundations/styles/color/usage.mdx +11 -4
  15. package/dist/docs/src/content/foundations/styles/data-visualization.mdx +74 -6
  16. package/dist/docs/src/content/foundations/styles/elevation.mdx +66 -3
  17. package/dist/docs/src/content/foundations/styles/icons/usage.mdx +9 -6
  18. package/dist/docs/src/content/foundations/styles/layout/app-frame.mdx +10 -0
  19. package/dist/docs/src/content/foundations/styles/opacity.mdx +43 -5
  20. package/dist/docs/src/content/foundations/styles/size-and-density.mdx +7 -0
  21. package/dist/docs/src/content/foundations/styles/typography/code.mdx +1 -1
  22. package/dist/docs/src/content/foundations/styles/z-index.mdx +63 -5
  23. package/dist/docs/src/content/tools/ant-design-vue-theme.mdx +125 -18
  24. package/dist/docs/src/content/tools/application-content.mdx +42 -0
  25. package/dist/docs/src/content/tools/editors.mdx +27 -0
  26. package/dist/docs/src/content/tools/mermaid.mdx +95 -0
  27. package/dist/docs/src/content/tools/vueflow.mdx +121 -0
  28. package/dist/docs/src/content-vi/foundations/styles/border.mdx +3 -3
  29. package/dist/docs/src/content-vi/foundations/styles/color/usage.mdx +11 -4
  30. package/dist/docs/src/content-vi/foundations/styles/data-visualization.mdx +75 -6
  31. package/dist/docs/src/content-vi/foundations/styles/elevation.mdx +75 -0
  32. package/dist/docs/src/content-vi/foundations/styles/icons/usage.mdx +9 -6
  33. package/dist/docs/src/content-vi/foundations/styles/layout/app-frame.mdx +10 -0
  34. package/dist/docs/src/content-vi/foundations/styles/opacity.mdx +43 -5
  35. package/dist/docs/src/content-vi/foundations/styles/size-and-density.mdx +7 -0
  36. package/dist/docs/src/content-vi/foundations/styles/typography/code.mdx +1 -1
  37. package/dist/docs/src/content-vi/foundations/styles/z-index.mdx +63 -5
  38. package/dist/docs/src/lib/token-descriptions-vi.ts +21 -5
  39. package/dist/docs/src/styles/chrome.css +14 -14
  40. package/dist/docs/src/styles/color.css +19 -32
  41. package/dist/docs/src/styles/docs.css +18 -34
  42. package/dist/docs/src/styles/elevation.css +83 -0
  43. package/dist/docs/src/styles/global.css +1 -10
  44. package/dist/docs/src/styles/icons.css +11 -15
  45. package/dist/docs/src/styles/kit.css +112 -0
  46. package/dist/docs/src/styles/layout.css +1 -6
  47. package/dist/docs/src/styles/opacity.css +43 -0
  48. package/dist/docs/src/styles/shapes.css +15 -19
  49. package/dist/docs/src/styles/tokens.css +1282 -3
  50. package/dist/docs/src/styles/tokens.js +358 -3
  51. package/dist/docs/src/styles/typography.css +4 -7
  52. package/dist/docs/src/styles/zindex.css +56 -0
  53. package/dist/docs/tokens/border.json +1 -1
  54. package/dist/docs/tokens/color.json +57 -3
  55. package/dist/docs/tokens/content.json +19 -0
  56. package/dist/docs/tokens/diagram.json +48 -0
  57. package/dist/docs/tokens/editor.json +129 -0
  58. package/dist/docs/tokens/elevation.json +15 -5
  59. package/dist/docs/tokens/flow.json +497 -0
  60. package/dist/docs/tokens/opacity.json +9 -0
  61. package/dist/docs/tokens/resize.json +67 -0
  62. package/dist/docs/tokens/size.json +6 -0
  63. package/dist/docs/tokens/spacing.json +4 -4
  64. package/dist/docs/tokens/typography.json +5 -0
  65. package/dist/docs/tokens/visualization.json +123 -0
  66. package/dist/docs/tokens/z-index.json +49 -0
  67. package/dist/index.js +153 -125
  68. package/package.json +1 -1
@@ -4,7 +4,11 @@ description: Make Ant Design Vue components use Beehexa design tokens, breakpoin
4
4
  order: 3
5
5
  ---
6
6
 
7
- Tokens and full rules are available as local `@beehexa/design-tokens` and `@beehexa/design-rules` packages. They are not released to npm yet. There is no exported `/antdv` theme subpath: keep a framework adapter in your application and derive its values from the installed token package.
7
+ `@beehexa/ant-design-vue-tokens` owns the reusable Ant Design Vue 4 adapter.
8
+ Use its typed ESM API and companion CSS, backed by `@beehexa/design-tokens`.
9
+ Frameworks are peers: `ant-design-vue@^4.2.6` and `vue@^3.3.0`; neither is bundled.
10
+ Unreleased `0.0.0` packages use explicit local development references; only the authorized
11
+ release runner stamps real package versions. Do not copy a theme palette into an application.
8
12
 
9
13
  **Beehexa tokens are the source of truth. Ant Design Vue only reads them.**
10
14
 
@@ -13,32 +17,77 @@ This page is the only place where the Beehexa foundations meet Ant Design Vue. T
13
17
  ## Usage
14
18
 
15
19
  ```vue
16
- <script setup>
17
- import { tokens } from '@beehexa/design-tokens';
20
+ <script setup lang="ts">
21
+ import { computed, watchEffect } from 'vue';
22
+ import { createAntDesignVueTheme, getAntDesignVuePopupContainer } from '@beehexa/ant-design-vue-tokens';
18
23
  import '@beehexa/design-tokens/css';
19
-
20
- // The framework adapter selects semantic roles, not a new application palette.
21
- const theme = {
22
- token: {
23
- colorPrimary: tokens.light['color.background.neutral.bold'],
24
- colorText: tokens.light['color.text'],
25
- colorBorder: tokens.light['color.border'],
26
- fontFamily: tokens.light['font.family.sans'],
27
- },
28
- };
24
+ import '@beehexa/ant-design-vue-tokens/css';
25
+
26
+ const props = defineProps<{ dark: boolean; locale: 'en' | 'vi' }>();
27
+ const theme = computed(() => createAntDesignVueTheme({
28
+ dark: props.dark, locale: props.locale
29
+ }));
30
+ watchEffect(() => {
31
+ if (typeof document === 'undefined') return;
32
+ document.documentElement.dataset.theme = props.dark ? 'dark' : 'light';
33
+ document.documentElement.lang = props.locale;
34
+ });
29
35
  </script>
30
36
 
31
37
  <template>
32
- <a-config-provider :theme="theme">
38
+ <a-config-provider :theme="theme" :get-popup-container="getAntDesignVuePopupContainer">
33
39
  <App />
34
40
  </a-config-provider>
35
41
  </template>
36
42
  ```
37
43
 
38
- This light-mode colour/font example is not the complete theme recipe. Apply the mappings below
39
- in your adapter, resolve `rem` to pixels at numeric API boundaries, and recompute from
40
- `{ ...tokens.light, ...tokens.dark }` for dark mode and the `tokens.vi` typography alternatives
41
- for Vietnamese. Read the installed rule documents before implementing states or components.
44
+ `createAntDesignVueTheme({ dark = false, locale = 'en' } = {})` returns
45
+ the native `ThemeConfig`. Recompute on theme/language changes; each call
46
+ returns a fresh object. `locale` selects source typography, not translated AntD messages.
47
+ Pass the appropriate AntD language pack through `ConfigProvider.locale`, and configure the
48
+ date library separately. Render native `useMessage`, `useNotification` and `useModal`
49
+ holders in a feedback host inside the sole root provider. Bind application notify facades
50
+ to those hook APIs; never use detached raw static feedback APIs. The factory sets
51
+ `hashed: false` because AntD4 contextual message/notification holders otherwise retain
52
+ stale hashes across theme/locale changes. Keep an existing notice open while switching
53
+ dark/Vietnamese to light/English; its typography and paint must follow the active theme.
54
+
55
+ Keep document `data-theme` and `lang` synchronized for teleported overlays. Import
56
+ companion CSS after application/framework styles. Use a native 16px root and 14px body;
57
+ numeric APIs resolve source rem at 16px. The pixel entrypoint is not the dashboard path.
58
+
59
+ ## Overlay ownership and bounded native content
60
+
61
+ Triggered popups use `getAntDesignVuePopupContainer` to stay inside their nearest native
62
+ Modal/Drawer or custom `data-bh-overlay-owner` host. Native Modal/Drawer roots remain
63
+ body-hosted for viewport geometry. Provider-bound modal facades default their invocation
64
+ `zIndex` through `getAntDesignVueModalZIndex()` while preserving explicit caller values;
65
+ this keeps keyboard/awaited confirmations above their live owner. Nested drawers use
66
+ `getAntDesignVueOverlayZIndex(fullscreen, ownerZIndex)` as `rootStyle.zIndex` so
67
+ surface and mask move together; AntD4's `zIndex` prop styles only the content wrapper.
68
+ Body-teleported fullscreen editors/images and fullscreen native Modals capture
69
+ `getAntDesignVueFullscreenZIndex()` before mounting their root. This combines the
70
+ fullscreen role with above-owner ordering; a fixed450 must not fall below a nested
71
+ native Drawer451. Mark custom roots only once they are active, avoiding self-counting.
72
+ Tour's inline native default also requires its public
73
+ `zIndex` prop bound to `z-index.spotlight`.
74
+
75
+ The companion CSS provides opt-in native structural contracts, not application selectors:
76
+
77
+ - `bh-ant-fill-drawer` / `bh-ant-drawer-flush`: bounded body, intrinsic header/footer,
78
+ optional zero body padding; bind through `rootClassName`.
79
+ - `bh-ant-fill-tabs`: bounded native wrappers and active pane. Nested tabs opt in separately;
80
+ `bh-ant-fill-tabs--scroll` enables pane scrolling and `bh-ant-tabs-mobile-inset` adds the
81
+ source mobile inset. Inactive panes stay hidden.
82
+ - `bh-ant-fill-spin` / `bh-ant-fill-card`: carry an existing bounded host through native wrappers.
83
+ - `bh-ant-inspection-descriptions`: source desktop label minimum and mobile stacked rows.
84
+ - `bh-ant-data-table`: generic pending/success/error row classes plus public `customCell`
85
+ markers `data-bh-cell-interaction="editable|readonly"` and `data-bh-cell-state="changed"`.
86
+ Native selection outranks operational row paint; changed cells keep diff paint on hover.
87
+ `bh-ant-table-nowrap` is an independent horizontal-content opt-in.
88
+
89
+ Keep custom business content and host geometry in the consumer. Do not recreate these
90
+ native selectors through per-page `:deep(.ant-*)`, global overrides or priority escalation.
42
91
 
43
92
  ## Token mapping
44
93
 
@@ -50,6 +99,64 @@ for Vietnamese. Read the installed rule documents before implementing states or
50
99
  | `borderRadius` | `radius.100` |
51
100
  | `fontFamily` | `font.family.sans` |
52
101
 
102
+ The adapter also pins semantic hover/pressed/disabled/link/status/selection/focus roles instead
103
+ of allowing a framework-generated blue palette to leak through. Inputs, selects, checkboxes
104
+ and radios use `color.border.bold` while cards/tables use `color.border`. Layout header and
105
+ sider and mobile navigation drawer share `color.surface.subtle`; there is no separate shell palette or nested isolated
106
+ theme. Use `font.body.default` for table data, `font.label.small` for headers/tags,
107
+ `font.heading.medium` for modal titles and `font.heading.small` for drawer titles.
108
+
109
+ ### Ant Design Vue 4 component contracts
110
+
111
+ - Table reads `colorFillAlter`, `colorTextHeading`, `controlItemBgActive` and
112
+ `controlItemBgActiveHover`. AntD5 names such as `headerBg` and `headerColor` are ignored
113
+ by AntD Vue 4.2.6 and must not be used.
114
+ - Menu reads `colorItem*`, `radiusItem`, `radiusSubMenuItem` and `colorActiveBar*`.
115
+ Explicit `theme="dark"` menus receive the same source roles. Selection has a visible bar,
116
+ not a heavier label that shifts its neighbours or merely a changed fill.
117
+ - Form controls share source outline/focus/disabled roles. Validation retains danger/warning
118
+ text/icons and native state semantics. Do not replace meaningful input borders with divider
119
+ hairlines.
120
+ - Tag status presets are `success`, `processing`, `warning`, `error`; default is neutral.
121
+ They use source foreground and outline pairs. Arbitrary hue presets are not status names.
122
+ Badge counts are neutral; error/processing status dots retain their semantics.
123
+ - Tooltip and Message use the inverse surface/text pair. Modal/Drawer content uses surface,
124
+ scrim and overlay elevation. Progress is neutral by default and semantic on success/error.
125
+
126
+ ### Companion CSS and structural classes
127
+
128
+ Use component tokens first. The package CSS fills actual AntD4 gaps: semantic label/header/title
129
+ typography, hard-coded submenu fill, selected bar colors, keyboard focus offsets, safe areas,
130
+ responsive Tour placement, reduced motion and neutral Badge count without recoloring error dots.
131
+ Application selectors and palette overrides belong neither in that CSS nor in a dashboard theme.
132
+ Consumers retain genuine portal layout and scrolling mechanics only. Framework paint
133
+ and typography fixes belong to the package, not duplicated consumer overrides.
134
+
135
+ `bh-ant-tag-large` on a Tag selects the source large label (24px minimum, 8px inline padding);
136
+ the default is 20px minimum/6px. Both grow for Vietnamese line boxes rather than clipping marks.
137
+ `bh-ant-tree-fill` on a Tree opts into a bounded flex host and virtual-list height; intrinsic
138
+ trees must not use it.
139
+
140
+ For data inspection, bind `width="var(--bh-ant-overlay-width)"` and apply
141
+ `bh-ant-inspection-modal` or Drawer `rootClassName="bh-ant-inspection-drawer"`.
142
+ Add `bh-ant-inspection-modal--wide` / `bh-ant-inspection-drawer--wide` only for an explicit
143
+ content-heavy variant. The variable selects `layout.overlay.default` / `.wide`, and `.mobile`
144
+ below `breakpoint.lg`. Short confirmations and navigation drawers retain their own widths.
145
+ Fullscreen modes are Modal `wrapClassName="full-screen"` and Drawer
146
+ `rootClassName="fullscreen"`; AntD4 Modal has no `rootClassName` prop. These preserve
147
+ bounded scroll mechanics, not decoration.
148
+
149
+ ### Verify the actual framework
150
+
151
+ Exercise light/dark × English/Vietnamese with the real CSS imported: buttons and validated
152
+ inputs/selects, ordinary/selected/hovered table row checkboxes, sorting/filter portals,
153
+ expanded/collapsed/horizontal and submenu navigation, form help/error, Tooltip/Message,
154
+ Modal/Drawer and default/wide/fullscreen inspection at 1023/1024px. Check keyboard focus,
155
+ touch hit areas, reduced motion, narrow Tour and focus return. Use
156
+ **ỔN ĐỊNH · ẤN ĐỘ · ẪM · Ở ĐÂY CÓ ƯU ĐÃI** in controls, tags and rows.
157
+ Compilation alone does not establish those rendering/interaction outcomes.
158
+
159
+
53
160
  ## Spacing
54
161
 
55
162
  Ant Design Vue sizes come from `sizeUnit` and `sizeStep`. Keep both at 4, so `size` is 16 px. The theme then sets each size from a [spacing](/foundations/styles/spacing/) token.
@@ -0,0 +1,42 @@
1
+ ---
2
+ title: Application content
3
+ description: Source-backed partner marks, person identities, neutral labels and empty-state illustration containers in product content.
4
+ order: 5
5
+ ---
6
+
7
+ ## Identity is not status
8
+
9
+ A connection name, provider name or person identifies an entity. Use its readable
10
+ name with a neutral themed tag, avatar or logo container. Do not hash names into a
11
+ local colour palette or borrow success/warning/danger roles to distinguish names.
12
+ Use operational status colours only when the displayed value actually represents
13
+ that status. Selected, hovered and focused identities use the ordinary interaction
14
+ roles; the identity does not gain a second competing palette.
15
+
16
+ ## Partner and system marks
17
+
18
+ Keep actual brand assets and their aspect ratio. Use a neutral `surface.subtle`
19
+ container, a `border` edge when needed, and `text` for textual initials. Do not
20
+ recreate a partner brand by colouring a fallback initial.
21
+
22
+ | Content part | Source role |
23
+ |---|---|
24
+ | Standard partner-logo tile | `content.partner-logo.size` (40 px) |
25
+ | Contained partner mark | `content.partner-logo.image-size` (28 px maximum) |
26
+ | Person or permission-member avatar | `content.avatar.size` (40 px) |
27
+ | System/provider identity container | `content.identity-mark.size` (44 px) |
28
+ | Contained system/provider glyph | `content.identity-mark.image-size` (24 px) |
29
+
30
+ These dimensions describe the visual identity, not the interactive target. If the
31
+ identity is actionable, apply the source target-size and focus rules separately.
32
+ A compact text-initial tile may use the normal control size instead of introducing
33
+ a one-off identity dimension. Numeric component/image APIs convert these source
34
+ roles at their boundary; do not duplicate their values in consumer constants.
35
+
36
+ ## Empty states
37
+
38
+ `content.empty-illustration.size` is a 96 px illustration container. Standard UI
39
+ icons inside it retain the 16/20/24/32 px icon sizes described by the icon guidance;
40
+ the container does not authorize an arbitrary 40 px icon. Use source typography,
41
+ spacing and semantic colours for the explanation and recovery action. Decorative
42
+ illustrations must not be the only explanation that a list is empty or unavailable.
@@ -0,0 +1,27 @@
1
+ ---
2
+ title: Editors and resize controls
3
+ description: Source-backed editor syntax, diff pairs, numeric font boundaries and accessible resize handles.
4
+ order: 6
5
+ ---
6
+
7
+ ## Editor canvas and syntax
8
+
9
+ Editors use `editor.background` and `editor.text`, a theme-aware reading canvas. This is deliberately different from static fenced code blocks (`color.code.background` / `color.code.text`), whose dark canvas has its own paired text. Never combine the editor syntax foregrounds with that static code-block canvas.
10
+
11
+ Use `editor.syntax.comment`, `.string`, `.number`, `.keyword`, `.type` and `.delimiter` for language tokens. These aliases reuse readable semantic foregrounds on the editor surface in both themes. Syntax coloring names language constructs, not operational status: a green string is not a successful operation. Keep language punctuation and text available without color. Editor gutter, line numbers, selection, line highlight and cursor have their own `editor.*` roles. Selection must retain a caret, native selection range or another non-color cue.
12
+
13
+ ## Diff inspection
14
+
15
+ Inserted lines use `editor.diff.inserted.background` with the inserted `text` annotation; removed lines use the removed pair. Keep native + / − gutter markers and accessible diff navigation. Do not add transparency to these pairs or interpret a changed value as an application failure. Ordinary code within either line keeps the theme-aware syntax foregrounds.
16
+
17
+ ## Numeric framework APIs
18
+
19
+ Monaco and similar frameworks require resolved values, not CSS `var()` strings. Resolve the installed token mode (light plus dark overrides, and Vietnamese typography alternatives) at the framework boundary. Convert `rem` dimensions to nominal pixels using 16 px/rem while the consumer uses the package's explicit pixel CSS compatibility entrypoint; do not copy a downstream token table. `editor.font.family`, `.size`, `.lineHeight` and `.weight` carry the complete `font.code.default` recipe (14/20, Vietnamese 14/24). Configure all four, not just font size. Theme definitions must be updated when app mode changes. Preserve legitimate editor settings such as read-only, wrapping, language workers, cancellation and diff layout.
20
+
21
+ ## Resize controls
22
+
23
+ `resize.divider` is the visible line, not its interaction area. The handle uses `resize.handle.width`, `.height`, `.radius`, `.background`, `resize.color` and `resize.grip`. Hover, focus and drag use `resize.active` on the divider; the handle uses `resize.handle.activeBackground` with `resize.activeGrip`. Keep a visible keyboard focus ring. Extend the hit region to `resize.target` and, for touch, `resize.touchTarget` without moving panel content or changing the visible divider. Keyboard-enabled separators retain orientation, value, min/max and arrow-key behavior. Do not add a decorative transition while dragging.
24
+
25
+ ## Fullscreen and popup ordering
26
+
27
+ Fullscreen editors, code viewers and image inspection use `z-index.fullscreen` (450) with isolation. Monaco completion, hover and parameter-hint widgets use `z-index.tooltip` (600); ordinary in-page popups keep framework layers inside their owner via the adapter's contextual container. Mark custom fullscreen hosts with `data-bh-overlay-owner`. Native confirmations resolve invocation-time ordering through `getAntDesignVueModalZIndex`, and nested drawers use `getAntDesignVueOverlayZIndex` with their live owner layer. Blocking global loading uses `z-index.loading` (650), below always-visible toast feedback (700). See [Z-index](/foundations/styles/z-index/) for the complete ordering. Avoid a new local z-index scale or a glass effect; custom fullscreen surfaces use semantic surfaces and image inspection uses one `color.surface.scrim` layer. Layering does not replace focus containment, Escape handling, focus return, scroll locking or reachable controls.
@@ -0,0 +1,95 @@
1
+ ---
2
+ title: Mermaid and execution diagrams
3
+ description: Source-backed Mermaid configuration, descriptive execution states, interaction and image export.
4
+ order: 6
5
+ ---
6
+
7
+ Use `@beehexa/mermaid-tokens` for every Mermaid initialization. It returns a fresh
8
+ `MermaidConfig` from `@beehexa/design-tokens`; Mermaid remains a peer dependency.
9
+ Pass the active `dark` and `locale` on every render. A theme or language change
10
+ requires rendering again: SVG paint and text measurements do not update from CSS alone.
11
+
12
+ ```ts
13
+ import { createMermaidConfig, createCanvasTheme } from '@beehexa/mermaid-tokens';
14
+
15
+ mermaid.initialize(createMermaidConfig({ dark: true, locale: 'vi' }));
16
+ const canvas = createCanvasTheme({ dark: true, locale: 'vi' });
17
+ ```
18
+
19
+ The factory secures `theme`, `look`, `themeVariables`, `themeCSS`, `fontFamily`,
20
+ `fontSize` and `htmlLabels` before `layout`. Mermaid 12 appends this secure array
21
+ to its own default security keys. Definition init CSS must not replace rich-card
22
+ token fonts; topology, definition-owned state styles and unrelated layout directives
23
+ remain available. This configuration contract is not a claim that a rendered smoke
24
+ matrix has passed.
25
+
26
+ ## Meaning before colour
27
+
28
+ `diagram.*` roles describe an operational execution graph, not an explanatory
29
+ brand schematic or a chart series palette. The same roles apply to the drawing,
30
+ its inspector and its exported artifact.
31
+
32
+ - Default and indeterminate nodes use `node-*` neutral pairs.
33
+ - `state-ran-ok` means **ran without a reported failure**, not a verified business
34
+ success. Neutral solid paint preserves this distinction from success status,
35
+ successful HTTP response, and warning. An HTTP response or business outcome
36
+ still uses the appropriate success/danger role in its own status label.
37
+ - Failed nodes use `fail-*`, with a failure marker and state text.
38
+ - Never-reached nodes use `unreached-*` and an explicit state label; they are not
39
+ disabled controls. Not-taken branches use `nottaken-*` plus a dashed boundary.
40
+ - Repeat counts use the neutral `badge-*` pair. Repetition alone is not a warning.
41
+ - Category glyphs use `tile-*`. They identify step type, not run state.
42
+ - Selection and hover use `selection-ring` as **separate geometry outside the
43
+ node boundary**. Never repaint a failed node to indicate that it is selected.
44
+ - Field labels use `code-key`, values `code-value`, on `code-bg`. These descriptive
45
+ fields are not links. Full code blocks retain the existing `color.code.*` pair.
46
+
47
+ Always keep labels, markers, shapes or dash patterns: colour alone is not evidence.
48
+ Pair foregrounds only with their named fills. Validate actual SVG text and meaningful
49
+ line contrast in both themes; token existence does not certify a rendered diagram.
50
+
51
+ ## Type, space and interaction
52
+
53
+ `diagram.node-font` aliases `font.body.default`, including taller Vietnamese lines.
54
+ Use complete source font styles for node labels, inspector titles, metadata and code.
55
+ Do not replace their weight or line height with component-specific recipes. Let
56
+ Vietnamese marks and long labels wrap without clipping. `diagram.padding` is internal
57
+ node padding; `diagram.export-padding` frames fitted/exported drawing bounds. Graph
58
+ coordinates and existing layout topology are not spacing-scale choices.
59
+
60
+ The adapter's SVG stylesheet also adapts renderer-owned execution-card labels.
61
+ It replaces their inline 11px/650-weight recipes with `font.heading.xsmall` and
62
+ `font.body.small`, and removes category-tile translucent tints and inset shadows.
63
+ `diagram.card-width`, `diagram.tile-size` and `diagram.glyph-size` retain the
64
+ measurable fixed card and symbol geometry; these are not marketing display type.
65
+ This narrowly scoped stylesheet is the framework gap boundary, not permission for
66
+ page CSS to override definition-owned run-state paint.
67
+ Embedded SVG CSS also supplies opaque source edge-label pairs and explicit
68
+ `"cv05", "cv08"` features alongside the complete font shorthand; SVG/export must
69
+ not depend on the document's universal font-feature rule.
70
+
71
+ Authoring previews use `diagram.preview-height` for both split panels and
72
+ `diagram.minimum-height` for the drawing viewport; fullscreen fills the enclosing
73
+ host instead. Read-only split diagrams retain a zero minimum so they shrink with
74
+ their host. Structured evidence viewers use `diagram.evidence-height`; multiple
75
+ request-body panes use `diagram.evidence-minimum-height` to keep every part reachable.
76
+
77
+
78
+ Use a flat opaque sheet. No gradients, glass, decorative animation, animated
79
+ traversal or state transitions. Retain zoom, fit, fullscreen/escape and PNG export
80
+ controls. Interaction must not overwrite definition-owned fill, stroke, dashes or
81
+ failure markers. Controls stay outside the captured SVG host.
82
+
83
+ ## Export the rendered theme
84
+
85
+ Resolve literal token values when drawing: Mermaid style statements cannot resolve
86
+ CSS variables. Snapshot the rendered theme and opaque canvas background on the SVG
87
+ host. Export the live, fully decorated drawing at its natural bounds with
88
+ `exportPadding`, not the transformed viewport. Preserve the snapshot even if the
89
+ application theme changes before the new drawing lands. Fonts, locale line height,
90
+ state paint and outer selection geometry must survive SVG/PNG capture. A transparent
91
+ image or white sheet behind dark labels is not a valid fallback.
92
+
93
+ All package source is in `tokens/diagram.json`; consumers must not maintain a
94
+ second palette or copy generated token values. Local package references are for
95
+ local development only until an authorized release exists.
@@ -0,0 +1,121 @@
1
+ ---
2
+ title: VueFlow theme
3
+ description: Source-backed operational graph categories, paired themes, fixed geometry and VueFlow 1 integration.
4
+ order: 5
5
+ ---
6
+
7
+ `@beehexa/vueflow-tokens` adapts the authoritative tokens to VueFlow 1. It does not copy
8
+ VueFlow source, bundle Vue, generate graph data, or change relationship direction.
9
+
10
+ ## Install and apply
11
+
12
+ Install this package, `@beehexa/design-tokens`, Vue 3, and the VueFlow 1 core, controls and
13
+ minimap peers. Load upstream core, theme, controls and minimap CSS in the lazy graph
14
+ entry before adapter CSS; load native design-token CSS once with a 16px root/14px body.
15
+ Local source packages remain private `0.0.0`; that is not a registry release.
16
+
17
+ ```vue
18
+ <script setup lang="ts">
19
+ import { computed } from 'vue'
20
+ import { VueFlow } from '@vue-flow/core'
21
+ import { Background } from '@vue-flow/background'
22
+ import { Controls } from '@vue-flow/controls'
23
+ import { MiniMap } from '@vue-flow/minimap'
24
+ import { createVueFlowTheme } from '@beehexa/vueflow-tokens'
25
+ import '@beehexa/design-tokens/css'
26
+ import '@vue-flow/core/dist/style.css'
27
+ import '@vue-flow/core/dist/theme-default.css'
28
+ import '@vue-flow/controls/dist/style.css'
29
+ import '@vue-flow/minimap/dist/style.css'
30
+ import '@beehexa/vueflow-tokens/css'
31
+
32
+ const props = defineProps<{ dark: boolean; locale: 'en' | 'vi' }>()
33
+ const theme = computed(() => createVueFlowTheme(props))
34
+ // nodes and edges remain application graph data; never recreate their IDs on theme changes.
35
+ </script>
36
+
37
+ <template>
38
+ <VueFlow :class="theme.class" :style="theme.style" v-bind="theme.flowOptions">
39
+ <Background v-bind="theme.background" />
40
+ <Controls />
41
+ <MiniMap v-bind="theme.minimap" />
42
+ </VueFlow>
43
+ </template>
44
+ ```
45
+
46
+ The factory returns scoped variables, viewport bindings typed with `FlowProps` (not deprecated `FlowOptions`), and Background/MiniMap bindings.
47
+ It resolves light plus dark overrides and Vietnamese typography alternatives from the token
48
+ package. Recompute when theme or locale changes. Keep ready/error handlers and fit the graph
49
+ with padding `0.2` when the host becomes measurable or changes size. VueFlow 1's actual
50
+ `fitViewOnInit` option is used; do not pass invented viewport option names.
51
+
52
+ ## Operational categories are not statuses
53
+
54
+ `flow.category.*` identifies the existing product's node kinds: task blue, dependency red,
55
+ transformation green, validation deep red, push step gold, decision cyan, loop magenta and
56
+ grouped nodes purple. These categorical identities must not be interpreted as success,
57
+ failure or warning. Keep the node's type label and icon; colour is never its sole identity.
58
+ A category colour does not certify the state of an execution.
59
+
60
+ Each category supplies `foreground`, `background`, `border` and `hover` as an opaque paired
61
+ light/dark role. Use `getNodeColorPalette(category)` for CSS-backed bindings and
62
+ `getNodeColor(nodeType)` for the frame/edge identity. These source roles replace historical
63
+ application-owned palettes, alpha overlays, gradients and palette-adjustment functions.
64
+ Never append hex alpha suffixes to a CSS variable, or lighten a resolved role downstream.
65
+
66
+ Selection uses `color.border.selected` plus the selected outline; keyboard focus separately
67
+ uses `color.border.focus`, the focused border width and `state.focus.offset`. Errors use the
68
+ danger frame plus dashed/non-colour indication and a readable error label. Selection or focus
69
+ must not overwrite category identity, hide an error, or be conveyed only through colour.
70
+ Resting handles use the neutral icon role. Focus color is reserved for actual focus,
71
+ not an always-on connector decoration.
72
+
73
+ ## Custom content and geometry
74
+
75
+ Use `getFlowNodeStyles(NodeType, state)` for custom node bodies. It binds semantic fonts,
76
+ spacing, shape, categorical pairs and source dimensions. Keep custom icons, connector logos,
77
+ labels, handles, accessibility semantics and events in the application. Meaningful loading
78
+ indicators may move; decorative node entrances, pulsing identities, rotating idle icons,
79
+ hover transforms, flowing edge dashes, gradients and glass are not part of the theme.
80
+
81
+ `NODE_DIMENSIONS`, `GRID_SPACING` and `TASK_DATA_LAYOUT` read `tokens/flow.json`. The scoped
82
+ operational matrix is: task, task dependency, task transformation and task data **450×130**;
83
+ three groups **350×130**; validation, transformation and push step **200×130**;
84
+ decision **160×160**, loop **120×120**, profile **240×100**. Do not confuse task-transformation
85
+ cards with individual transformation steps. Rendering, layout and half-dimension centering
86
+ must use the same source. Preserve existing graph coordinates during theme adoption.
87
+
88
+ Graph layout coordinates, intrinsic sizing, flex/grid mechanics and viewport transforms are
89
+ not palette values. Do not arbitrarily round them to the spacing scale. Category adaptation
90
+ must not mutate the graph's IDs, expansion state, saved positions or relationship semantics.
91
+
92
+ ## Edges, controls and export
93
+
94
+ `styleTargetEdge(edge, nodes)` preserves the directed edge's target identity on both stroke
95
+ and marker, keeps other edge data, and disables decorative traversal motion. The application
96
+ may retain dashed lines to communicate transformation or conditional semantics. The custom
97
+ edge renderer must consume the supplied stroke rather than replace it with an unrelated
98
+ edge palette. `FLOW_EDGE` centralizes widths, marker size, path radius and handle size.
99
+
100
+ The CSS companion addresses actual VueFlow core/default nodes, handles, edge labels, selection,
101
+ Controls buttons and MiniMap surfaces. Controls preserve normal, hover, disabled and focus
102
+ states and enlarge to source touch targets for coarse pointers. Import it after upstream CSS;
103
+ remove competing consumer-wide core/controls/minimap paint rules rather than escalating specificity.
104
+
105
+ Export the current theme and font from the measured graph surface. Do not force a white
106
+ background or independent system-font palette. Preserve snapshot/fit/restore, overlay filtering,
107
+ resolution feedback and capture fallback handling. Check the real exported image, not just a
108
+ successful capture call.
109
+
110
+ Graph fullscreen uses an isolated local stacking context at `z-index.modal` (400), not
111
+ `z-index.fullscreen` (450), so global inspectors remain above it. Private child chrome
112
+ ordering such as z10/z15 stays inside that context; do not assign global1001/1002
113
+ to graph controls. Verify real inspector/dialog ordering, Escape and focus return.
114
+
115
+ ## Verification
116
+
117
+ Exercise light and dark, English and Vietnamese, selected plus focused and error nodes,
118
+ long labels, every fixed dimension, target-coloured arrows, zoom/snap/fitting, expanded groups,
119
+ cycles, narrow and fullscreen hosts, ESC exit, Controls, MiniMap and export. Calculate contrast
120
+ for the actual paired foreground/background and meaningful borders in each rendered theme;
121
+ source tokens and typed configuration alone are not accessibility or visual proof.
@@ -36,7 +36,7 @@ Focus ring, màu `color.border.focus`, vẽ cách phần tử 2 px về phía ng
36
36
 
37
37
  ### `border.width.accent` · 4 px
38
38
 
39
- Thanh trạng thái hoặc nhấn mạnh ở một cạnh: alert và banner, dòng bảng bị lỗi, callout và trích dẫn. Hộp vẫn bo đủ bốn góc và thanh chạy theo đường cong.
39
+ Thanh trạng thái hoặc nhấn mạnh ở một cạnh: dòng bảng bị lỗi, callout và trích dẫn. Banner không dùng thanh này mà dùng nền nhạt theo trạng thái (xem [Cách dùng màu](/vi/foundations/styles/color/usage/)). Hộp vẫn bo đủ bốn góc và thanh chạy theo đường cong.
40
40
 
41
41
  <ShapeDemo kind="border-use" item="accent" />
42
42
 
@@ -60,13 +60,13 @@ Không báo trạng thái chỉ bằng màu. Đang chọn và đang focus còn
60
60
  ## Code
61
61
 
62
62
  ```css
63
- .alert {
63
+ .callout {
64
64
  position: relative;
65
65
  overflow: hidden;
66
66
  border: var(--bh-border-width-default) solid var(--bh-color-border);
67
67
  border-radius: var(--bh-radius-100);
68
68
  }
69
- .alert::before {
69
+ .callout::before {
70
70
  content: "";
71
71
  position: absolute;
72
72
  inset: 0 auto 0 0;
@@ -14,8 +14,9 @@ import ColorDemo from '../../../../components/ColorDemo.astro';
14
14
  | Tôi cần | Dùng |
15
15
  |---|---|
16
16
  | Nền trang | `surface.page` |
17
- | Card, panel, dialog | `surface`, viền `border` |
18
- | Sidebar, header của bảng, vùng nền nhạt | `surface.subtle` |
17
+ | Card, panel | `surface`, viền `border` |
18
+ | Menu, popover, dialog, drawer | `surface.overlay`; mục bên trong dùng `surface.overlay.hover`, `.pressed`, `.selected` |
19
+ | Header toàn cục và sidebar (cùng bề mặt khung ứng dụng), drawer điều hướng mobile, header của bảng, vùng nền nhạt | `surface.subtle` |
19
20
  | Chữ nội dung, tiêu đề, nhãn | `text` |
20
21
  | Mô tả, cột phụ của bảng, điều hướng | `text.subtle` |
21
22
  | Metadata, mốc thời gian, chữ hướng dẫn, breadcrumb | `text.subtlest` |
@@ -34,7 +35,11 @@ import ColorDemo from '../../../../components/ColorDemo.astro';
34
35
  | Lỗi dưới một trường nhập | `text.danger`, `icon.danger` |
35
36
  | Banner báo trạng thái | `background.{role}.subtle`, `border.{role}.subtle`, `text`, `icon.{role}` |
36
37
  | Trạng thái trong một dòng của bảng | Một [nhãn](#nhãn) |
37
- | Tooltip, toast | `surface.inverse`, `text.inverse` |
38
+ | Tooltip | `surface.inverse`, `text.inverse` |
39
+ | Toast | `surface.overlay`, `text`, `icon.{role}`, bóng `elevation.shadow.overlay`; không viền |
40
+ | Switch | Bật: `background.neutral.bold`; tắt: `background.neutral`, viền `border.bold`; núm `surface` |
41
+ | Avatar chữ cái đầu | `background.neutral`, `text` |
42
+ | Số thứ tự, số đếm | `background.neutral.bold`, `text.inverse` |
38
43
  | Lớp phủ sau dialog hoặc drawer | `surface.scrim` |
39
44
  | Khung chờ khi đang tải | `skeleton`, vệt sáng `skeleton.subtle` |
40
45
  | Khối code | `code.background`, `code.text` |
@@ -87,7 +92,9 @@ Cảnh báo dùng màu cam, không dùng màu vàng, vì màu vàng là màu th
87
92
  |---|---|---|
88
93
  | Hình thức | Viền theo `border` của vai trò, chữ theo `text` của vai trò | Nền theo `bold` của vai trò, chữ và icon theo `text.on-bold` |
89
94
  | Kích thước | Cao 20 px, padding 6 px; cỡ lớn 24 px, 8 px | Cao 32 px, padding 12 px |
90
- | Dùng | Nhiều nhãn trên một màn hình: dòng trong bảng, tag | Một nhãn trên mỗi trang: trạng thái chính của trang đó |
95
+ | Dùng | Nhiều nhãn trên một màn hình: trạng thái trong dòng bảng và danh sách | Một nhãn trên mỗi trang: trạng thái chính của trang đó |
96
+
97
+ Tag không phải là nhãn. Tag là thứ người dùng thêm vào hoặc gỡ ra, như bộ lọc hay từ khóa: cao 24 px, bo góc 4 px, `border` và `text`, có nút gỡ. Nhãn cho biết trạng thái, người dùng không gỡ được.
91
98
 
92
99
  ## Trạng thái tương tác
93
100
 
@@ -2,10 +2,79 @@
2
2
  title: "Biểu đồ dữ liệu"
3
3
  description: "Màu, chữ và quy tắc cho biểu đồ, ô KPI và các cách hiển thị dữ liệu khác."
4
4
  order: 13
5
- planned:
6
- - "Bảng màu cho các chuỗi dữ liệu, đủ tương phản ở light và dark"
7
- - "Màu trạng thái trong biểu đồ"
8
- - "Các loại biểu đồ và khi nào dùng"
9
- - "Trục, chú giải, tooltip và định dạng số"
10
- - "Biểu đồ dễ tiếp cận: không chỉ dựa vào màu, có phần mô tả bằng chữ"
11
5
  ---
6
+
7
+ ## Chọn theo câu hỏi
8
+
9
+ Dùng biểu đồ đường cho giá trị theo thời gian, đường xu hướng nhỏ chỉ khi đặt cạnh
10
+ giá trị hiện tại, thanh tỷ lệ cho các phần của một tổng đã ghi rõ, và dòng thời gian
11
+ để thể hiện thời điểm thực thi. Vòng sức khỏe phải có cả điểm số và nhận định bằng
12
+ chữ. Không dùng vùng tô trang trí, chuyển sắc, hiệu ứng kính hoặc nhấp nháy lỗi.
13
+
14
+ ## Chỉ số, loại và trạng thái là ba ý nghĩa khác nhau
15
+
16
+ `visualization.metric.*` định nghĩa các chuỗi vận hành có tên: tổng phiên chạy,
17
+ hoàn tất, thất bại, tỷ lệ thành công, phiên đang chạy, thời gian thực thi trung bình
18
+ và độ sâu hàng đợi. Số lượng và thời gian tự chúng không phải cảnh báo. Luôn hiện
19
+ đơn vị, ngưỡng và tên chỉ số.
20
+
21
+ `visualization.job-type.*` định danh các loại queue-status, sync-history,
22
+ polling-jobs và generic-jobs, không biểu thị thành công, cảnh báo hay thất bại.
23
+ Các bí danh màu nền tảng tự thích ứng với giao diện sáng và tối. Luôn kèm tên loại
24
+ hoặc biểu tượng riêng. Ở chế độ kết hợp của dòng thời gian, dấu ngoài thể hiện loại
25
+ phiên và dấu trong thể hiện trạng thái; chú giải phải giải thích cả hai. Ở chế độ
26
+ trạng thái, dùng `color.text.success`, `danger`, `info`, `warning` hoặc chữ trung
27
+ tính theo trạng thái thực tế. Giữ nhãn trạng thái và biểu tượng kết quả.
28
+
29
+ `visualization.priority.1` đến `.5` thể hiện mức khẩn cấp của hàng đợi, luôn ghi
30
+ P1–P5. Độ ưu tiên không phải kết quả thực thi. P1 cao nhất, P5 thấp nhất. Không
31
+ dùng màu ưu tiên để khẳng định thành công hay thất bại.
32
+
33
+ ## Hình học và chữ
34
+
35
+ Dùng `visualization.line-width`, `sparkline-width`, `grid-width`, `point-radius`
36
+ và `hover-point-radius` cho đường và điểm SVG. Độ dày tính bằng pixel CSS; dùng
37
+ viewBox theo kích thước đo được hoặc nét không co giãn để tránh méo.
38
+ `timeline-track-height` và `activity-track-height` quy định độ dày thanh tỷ lệ.
39
+ `ring-size` là kích thước CSS; `ring-width` là phần trăm theo API Ant Design;
40
+ `ring-gap` tính bằng độ. Chỉ đổi kích thước thành số tại ranh giới API.
41
+ Tọa độ dữ liệu và kích thước vùng chứa đo được vẫn là dữ liệu, không phải token.
42
+
43
+ `timeline-node-size` và `timeline-node-inner-size` quy định dấu ngoài cho loại và
44
+ dấu trong cho trạng thái. Các biến thể `touch` và `tablet` giữ khả năng đọc, không
45
+ đổi cách mã hóa. `timeline-cluster-size` quy định dấu tổng hợp số lượng; tô viền
46
+ theo loại hoặc trạng thái, giữ số bằng chữ thường trên nền thường, không đặt chữ
47
+ trắng trên màu sáng đã thích ứng với giao diện tối. Vùng tương tác dùng
48
+ `size.target.touch`, độc lập với kích thước dấu nhìn thấy.
49
+ `chart-height`, `chart-initial-width`, `sparkline-height`,
50
+ `sparkline-compact-height` và `sparkline-initial-width` quy định vùng vẽ; chiều rộng
51
+ ban đầu được thay bằng số đo thực tế. `sparkline-point-radius` là bán kính điểm cuối
52
+ nhỏ. Các kích thước này không phải thang dữ liệu hay giá trị trục.
53
+
54
+ Dùng `font.heading.large` cùng chữ số có độ rộng bằng nhau cho KPI,
55
+ `font.body.small` cho siêu dữ liệu, trục và tooltip; `font.label.small` cho chú giải.
56
+ Dùng `color.border` cho lưới trang trí, `color.text.subtle` cho nhãn và cặp màu nền
57
+ đảo/chữ đảo cho tooltip. Dấu dữ liệu có ý nghĩa cần tương phản ít nhất 3:1 trên nền
58
+ thực tế; chữ thường cần 4,5:1. Kiểm tra từng cặp màu trong từng giao diện, không
59
+ coi việc dùng bí danh là bằng chứng tương phản khi hiển thị.
60
+
61
+ ## Nhãn, định dạng và tương tác
62
+
63
+ Giữ định dạng số, thời điểm và thời lượng theo ngôn ngữ nhất quán với bảng bên
64
+ cạnh. Hiện đơn vị và khoảng thời gian; giữ ngữ cảnh múi giờ. Không âm thầm đổi số
65
+ đếm thành tỷ lệ hoặc cắt ngắn thời lượng. Chú giải phải đặt tên mọi chuỗi đang hiện;
66
+ chuỗi được chọn cần dấu hiệu ngoài màu sắc. Tooltip phải nằm trong vùng biểu đồ
67
+ và không được là cách duy nhất để đọc giá trị. Cung cấp số tổng hợp hoặc bảng
68
+ cùng dữ liệu bên cạnh và tên biểu đồ cho công nghệ hỗ trợ. Điều khiển chú giải
69
+ bằng bàn phím phải giữ chỉ báo lấy nét rõ ràng.
70
+
71
+ ## Dải đánh giá lưu lượng
72
+
73
+ `visualization.traffic.{healthy,attention,degraded,critical,unavailable,fault}.{fill,outline}`
74
+ cung cấp cặp màu tô và viền. Healthy là lưu lượng được chấp nhận; attention, degraded
75
+ và critical thể hiện các ngưỡng tỷ lệ yêu cầu bị từ chối tăng dần. Ghi ngưỡng trong
76
+ nhãn hoặc tooltip. Attention và degraded dùng chung màu cảnh báo: phân biệt bằng
77
+ nét đứt và nhãn rõ ràng, không chỉ bằng màu. Unavailable nghĩa là không có yêu cầu
78
+ để đánh giá. Fault là lỗi xử lý yêu cầu nội bộ/máy chủ, không phải ngưỡng tỷ lệ
79
+ đã đo; hiện số lỗi riêng, nhãn hoặc biểu tượng và họa tiết gạch chéo. Lỗi lấy dữ liệu là lỗi riêng. Không đổi
80
+ dữ liệu thiếu thành số không hay kết quả tốt. Dùng `color.text` trên nền tô nhạt.