@beehexa/vueflow-tokens 2611.6.1 → 2611.8.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.
- package/README.md +102 -39
- package/dist/index.d.ts +41 -67
- package/dist/index.js +53 -96
- package/dist/styles.css +112 -11
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -24,47 +24,110 @@ host/dimension changes. The factory uses VueFlow 1's real `fitViewOnInit` option
|
|
|
24
24
|
|
|
25
25
|
## Public contracts
|
|
26
26
|
|
|
27
|
-
- `createVueFlowTheme({ dark?, locale? })`: scoped source variables, real VueFlow
|
|
28
|
-
viewport settings, background and minimap bindings.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- `
|
|
37
|
-
|
|
27
|
+
- `createVueFlowTheme({ dark?, locale?, nodeTone? })`: scoped source variables, real VueFlow
|
|
28
|
+
viewport settings, background and minimap bindings. `nodeTone(node)` picks each MiniMap
|
|
29
|
+
node's tone (`blue`, VueFlow's default-node colour, when omitted).
|
|
30
|
+
- `FLOW_TONES` / `FlowTone`: the generic colour tones `blue`, `red`, `green`, `crimson`,
|
|
31
|
+
`yellow`, `teal`, `magenta` and `purple`. Each tone reads one existing foundation
|
|
32
|
+
`flow.category.*` role set (foundation names unchanged); the package gives a tone no
|
|
33
|
+
meaning, and the consumer owns which of its concepts takes which tone. Tones identify
|
|
34
|
+
kinds, never execution status.
|
|
35
|
+
- `getFlowTonePalette(tone)`: CSS-backed paired tone roles, live across theme switches.
|
|
36
|
+
- `getFlowToneStyles(tone, part?)`: custom content role binding; `foreground` (default)
|
|
37
|
+
sets tone text, `border` sets border colour and `background` sets the tone surface.
|
|
38
|
+
- `getFlowNodeStyles({ tone, width, height, shape? }, { hovered?, selected?, dashed? })`:
|
|
39
|
+
typed custom node body/content/icon/label/logo styles over consumer-owned geometry,
|
|
40
|
+
without decorative motion or gradients. `shape: 'circle'` rounds the body fully.
|
|
41
|
+
- `styleTargetEdge(edge, nodes, toneOf?)`: directed edge identity from the target node's
|
|
42
|
+
tone (`blue` when omitted); target stroke and marker remain paired.
|
|
38
43
|
- `FLOW_EDGE`, `FLOW_ICON`: numeric source values at VueFlow/icon API boundaries.
|
|
39
|
-
- `
|
|
40
|
-
`foreground` (default) sets category text, `border` sets border colour and
|
|
41
|
-
`background` sets the category surface.
|
|
42
|
-
- `getFlowIconStyles(type, { size?, color?, disabled? })`: category-border glyphs
|
|
44
|
+
- `getFlowIconStyles(toneOrRole, { size?, color?, disabled? })`: tone-border glyphs
|
|
43
45
|
or separate `status-success|warning|error|info|loading` / `control-expand|collapse|help`
|
|
44
|
-
icon roles.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
- Public option, category, dimension, node-state, style and theme interfaces are emitted
|
|
46
|
+
icon roles. Sizes accept `small|medium|large` or a numeric API size; explicit colours
|
|
47
|
+
must already be source-resolved semantic roles.
|
|
48
|
+
- `getFlowEdgeStyles(tone, suppliedStyle?)`: SVG width, non-scaling stroke and no fill.
|
|
49
|
+
A supplied directed target stroke wins over the tone fallback, and a supplied static
|
|
50
|
+
dash is kept; the consumer owns what a dash means.
|
|
51
|
+
- Public option, tone, node-look, node-state, style and theme interfaces are emitted
|
|
51
52
|
in `dist/index.d.ts`; CSS has a typed `./css` export.
|
|
52
53
|
|
|
53
54
|
Use public source typography/content markers and graph presentation factories in
|
|
54
|
-
custom
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
custom content. Keep kind labels and icons, selected outline, separate keyboard focus
|
|
56
|
+
and readable error messages. Do not append hexadecimal alpha suffixes to CSS
|
|
57
|
+
variables. Do not animate idle graph nodes, rotate kind icons, add glass/gradients,
|
|
58
|
+
or override core controls in each consumer.
|
|
58
59
|
Preserve graph IDs, stored coordinates and relationship direction on theme changes.
|
|
59
60
|
Exports must capture the current graph surface/font rather than force white/system fonts.
|
|
60
61
|
|
|
62
|
+
Native `.bh-workflow-canvas` consumers may opt into the `WorkflowEdge.tone` values
|
|
63
|
+
`blue`, `red` and `green`. The companion binds `--wf-edge-tone-<tone>` to the existing
|
|
64
|
+
foundation border roles `--bh-flow-category-task-border`, `-dependency-border` and
|
|
65
|
+
`-transformation-border` (foundation names unchanged), with solid, short-dash (`2 4`) and
|
|
66
|
+
dash-dot (`9 3 2 3`) cues through `--wf-edge-tone-<tone>-dash`. Tone is categorical,
|
|
67
|
+
independent of failure; native stroke/arrowhead, interaction states and jump swatches
|
|
68
|
+
share it. The consumer maps its own relation kinds onto these tones. PNG export reuses
|
|
69
|
+
the native exporter's DOM/stylesheet serialization, with no tone-specific path.
|
|
70
|
+
Omitting tone retains existing native styling. Do not add consumer edge renderers.
|
|
71
|
+
|
|
72
|
+
Possible, context and toned-failure edges keep tone ink and dash in every state;
|
|
73
|
+
their cues are native shapes, never new dashes or opacity. `certainty: 'possible'`
|
|
74
|
+
draws a hollow source-end diamond (BPMN conditional flow). `context: true` draws an
|
|
75
|
+
open arrowhead and the thinner resting stroke `--wf-edge-context-width`, a package-owned
|
|
76
|
+
variable bound to the foundation `border.width.default`. A toned failure keeps its
|
|
77
|
+
tone dash and adds the Lucide `CircleX` mark in `color.icon.danger`
|
|
78
|
+
(`--wf-edge-failure-icon`) beside the label; an untoned failure keeps the failure dash.
|
|
79
|
+
Pass the localized group name as `familyLabel` for `{family} jump to {target}` names,
|
|
80
|
+
and localize the whole name/numbering through the viewer's `texts.jumps` (`WorkflowJumpTexts`).
|
|
81
|
+
|
|
82
|
+
`NodeLook.sizing: 'content'` opts ordinary native cards into intrinsic width:
|
|
83
|
+
minimum `diagram.card.width`, maximum twice that source role. The native theme owns
|
|
84
|
+
only that width rule; this companion owns the roles
|
|
85
|
+
`--wf-node-content-min-width` / `--wf-node-content-max-width` and the presentation
|
|
86
|
+
recipe (title/kind wrap, growing head, logos bounded without hiding any), with no
|
|
87
|
+
declaration duplicated in the native theme. Other cards retain their existing
|
|
88
|
+
fixed sizing; stadium, diamond and ellipse cards ignore the opt-in.
|
|
89
|
+
Native measurement/router and endpoint spreading are unchanged. Light/dark,
|
|
90
|
+
long title/many-logo, interaction and exported-PNG acceptance remains manual.
|
|
91
|
+
|
|
92
|
+
Native group frames (`WorkflowNode.group`, the built-in `wf-group` node) take the
|
|
93
|
+
package-owned `--wf-group-*` variables, each bound to an existing foundation role:
|
|
94
|
+
border `color.border`, border width `border.width.default`, radius `radius.card`, fill
|
|
95
|
+
`color.surface.subtle`, nested fill `color.background.neutral`, padding `space.stack`
|
|
96
|
+
and header gap `space.150`; high contrast draws the border in text ink. No flow-specific
|
|
97
|
+
foundation token backs them. The native layout reads padding and header gap from the
|
|
98
|
+
canvas, so both stay plain lengths.
|
|
99
|
+
Diamond and ellipse titles and kind captions wrap at word boundaries and are never
|
|
100
|
+
truncated (no `overflow-wrap: anywhere`, no ellipsis); only a single word wider than the
|
|
101
|
+
content box breaks. Other cards may still break a long unbroken title anywhere. Frame
|
|
102
|
+
look, toggle and exported-PNG acceptance remain manual.
|
|
103
|
+
|
|
104
|
+
The native Shift + drag selection box takes `--wf-selection-*` from the same selection
|
|
105
|
+
recipe as `.bh-vue-flow .vue-flow__selection`: transparent (no fill, so swept cards stay visible), a
|
|
106
|
+
dashed `border.width.selected` border in `color.border.focus`, in both themes. Its look remains
|
|
107
|
+
manual acceptance.
|
|
108
|
+
|
|
109
|
+
The native find box (`WorkflowFind`, the viewer's `/` search) takes `--wf-find-*` and the
|
|
110
|
+
shared `--wf-list-*` roles: an overlay (`color.surface.overlay`, `elevation.shadow.overlay`,
|
|
111
|
+
`radius.overlay`, no border) with a `color.border` divider under the field. Field and empty
|
|
112
|
+
state `font.body.default` (placeholder `color.text.subtlest`, empty state `color.text.subtle`);
|
|
113
|
+
rows `font.label.default`, `space.075` / `space.item.x` padding, `size.control.default` minimum
|
|
114
|
+
height (`size.target.touch` on coarse pointers and below 768px), `radius.item`; the kind label
|
|
115
|
+
`font.body.small` in `color.text.subtle`; an unnamed node's id `font.code.default`. Names wrap at
|
|
116
|
+
word boundaries, never truncated. Row states: hover `color.surface.overlay.hover`; the
|
|
117
|
+
keyboard-active row `color.surface.overlay.selected` plus the `border.width.selected` /
|
|
118
|
+
`color.border.selected` start bar; that row hovered `color.surface.overlay.selected.hover`.
|
|
119
|
+
Focus is the field ring (`--wf-focus-outline`) around the box. The canvas previews the pointed
|
|
120
|
+
row's node with its hover state and outer ring, without changing selection, trace or viewport.
|
|
121
|
+
The `--wf-list-*` roles also paint the native jump list and dock menu rows. Look and contrast
|
|
122
|
+
in both themes remain manual acceptance.
|
|
123
|
+
|
|
61
124
|
Ordinary nodes, MiniMap cards and outer Controls/dock frames use `radius.100`
|
|
62
125
|
(8px). Individual compact control Buttons and menu items retain `radius.050` (4px);
|
|
63
126
|
floating zoom-menu surfaces use `radius.overlay` (8px), independently of those items.
|
|
64
127
|
MiniMap fills clip; Controls retain exposed focus rings. Native legend popovers
|
|
65
128
|
keep `radius.100`, while the native keyboard-shortcuts Dialog uses `radius.150`
|
|
66
|
-
(12px), independently of its control Buttons.
|
|
67
|
-
`radius.075` (6px).
|
|
129
|
+
(12px), independently of its control Buttons. Node logos retain nested
|
|
130
|
+
`radius.075` (6px). Circular nodes and graph handles keep their circular
|
|
68
131
|
geometry; `FLOW_EDGE.radius` remains edge-path geometry. Consumer-owned inspector
|
|
69
132
|
Cards use `radius.100`; dialogs/drawers use `radius.150`.
|
|
70
133
|
|
|
@@ -77,18 +140,18 @@ same host for the existing user accessibility settings (1.125em node text;
|
|
|
77
140
|
1.6 line-height / 0.02em letter-spacing). These are opt-in adaptations, not new
|
|
78
141
|
default typography. `bh-flow-icon[data-bh-loading="true"]` animates only an
|
|
79
142
|
actual loading glyph and respects reduced motion.
|
|
80
|
-
`bh-flow-
|
|
81
|
-
|
|
143
|
+
`bh-flow-tone-mark[data-bh-tone="<FlowTone>"]` is a labelled 6px circular
|
|
144
|
+
relationship marker in the tone's border role (`blue` when unset), never a status dot.
|
|
82
145
|
|
|
83
|
-
For a native
|
|
84
|
-
`
|
|
85
|
-
|
|
86
|
-
|
|
146
|
+
For a native kind Tag, bind the cached immutable result of
|
|
147
|
+
`getFlowToneBadgeStyles(tone)` to its public `style` prop and omit its `color` prop.
|
|
148
|
+
This pairs tone foreground, background and border; a frame/edge stroke from
|
|
149
|
+
`getFlowTonePalette(tone).border` is not a filled badge background. Both themes'
|
|
87
150
|
small-text pairs are checked at WCAG AA 4.5:1 and demonstrated with real native
|
|
88
|
-
Tags in the Ant Design Vue family.
|
|
151
|
+
Tags in the Ant Design Vue family. Tones are not execution status.
|
|
89
152
|
|
|
90
|
-
Resting handles use the neutral icon role, not keyboard-focus color.
|
|
91
|
-
|
|
153
|
+
Resting handles use the neutral icon role, not keyboard-focus color. Graph
|
|
154
|
+
fullscreen uses an isolated local stacking context at `z-index.modal` (400), allowing
|
|
92
155
|
global inspectors above it. Child chrome may use private z10/z15 within that context,
|
|
93
156
|
not global1001/1002. Editor takeovers use the same `z-index.modal` layer.
|
|
94
157
|
|
|
@@ -97,10 +160,10 @@ not global1001/1002. Editor takeovers use the same `z-index.modal` layer.
|
|
|
97
160
|
The shared `build-runtime-packages.mjs` compiles strict NodeNext source and checks generated
|
|
98
161
|
output. Actual packed-consumer checks exercise exports/CSS with strict TypeScript and
|
|
99
162
|
`skipLibCheck` at the upstream vendor-declaration boundary. Source version `0.0.0`
|
|
100
|
-
stays private; only the authorized runner stamps real package
|
|
163
|
+
stays private; only the authorized runner stamps real versions for this package and its internal requirements.
|
|
101
164
|
|
|
102
165
|
Full authored guidance lives in `src/content/tools/vueflow.mdx` and ships through
|
|
103
166
|
`@beehexa/design-rules`. Verify real light/dark and English/Vietnamese surfaces,
|
|
104
|
-
contrast,
|
|
167
|
+
contrast, consumer-owned dimensions, long labels, selection/focus/error, target-coloured
|
|
105
168
|
markers, controls/minimap, zoom/snap/fit, expanded/cyclic graphs, fullscreen/ESC and PNG
|
|
106
169
|
export. Typed configuration is not visual or accessibility proof.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,61 +1,25 @@
|
|
|
1
1
|
import type { CSSProperties } from 'vue';
|
|
2
2
|
import { type FlowProps, type Node, type Edge, type Styles } from '@vue-flow/core';
|
|
3
|
+
/**
|
|
4
|
+
* Generic colour tones. Each tone reads one existing foundation `flow.category.<key>` role set;
|
|
5
|
+
* the foundation keys keep their names and the package gives a tone no domain meaning. The
|
|
6
|
+
* consumer decides which of its own concepts takes which tone.
|
|
7
|
+
*/
|
|
8
|
+
export declare const FLOW_TONES: readonly ["blue", "red", "green", "crimson", "yellow", "teal", "magenta", "purple"];
|
|
9
|
+
export type FlowTone = typeof FLOW_TONES[number];
|
|
3
10
|
export interface VueFlowThemeOptions {
|
|
4
11
|
dark?: boolean;
|
|
5
12
|
locale?: 'en' | 'vi';
|
|
13
|
+
/** Tone of a MiniMap node; `blue` when omitted. */
|
|
14
|
+
nodeTone?: (node: Node) => FlowTone;
|
|
6
15
|
}
|
|
7
|
-
export
|
|
8
|
-
export type FlowEdgeCategory = 'dependency' | 'transformation' | 'dataFlow' | 'conditional';
|
|
9
|
-
export interface FlowNodePalette {
|
|
16
|
+
export interface FlowTonePalette {
|
|
10
17
|
primary: string;
|
|
11
18
|
text: string;
|
|
12
19
|
background: string;
|
|
13
20
|
border: string;
|
|
14
21
|
hover: string;
|
|
15
|
-
connector: {
|
|
16
|
-
bg: string;
|
|
17
|
-
border: string;
|
|
18
|
-
logoBorder: string;
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
export declare enum NodeType {
|
|
22
|
-
MAIN_TASK = "task",
|
|
23
|
-
TASK_DEPENDENCY = "task_dependency",
|
|
24
|
-
TASK_TRANSFORMATION = "task_transformation",
|
|
25
|
-
TASK_DATA = "task_data",
|
|
26
|
-
TRANSFORMATION_GROUP = "transformationGroup",
|
|
27
|
-
VALIDATION_GROUP = "validationGroup",
|
|
28
|
-
PUSH_STEPS_GROUP = "pushStepsGroup",
|
|
29
|
-
TRANSFORMATION = "transformation",
|
|
30
|
-
VALIDATION = "validation",
|
|
31
|
-
PUSH_STEP = "push_step",
|
|
32
|
-
DECISION = "decision",
|
|
33
|
-
LOOP = "loop",
|
|
34
|
-
PROFILE = "profile"
|
|
35
|
-
}
|
|
36
|
-
export interface FlowDimensions {
|
|
37
|
-
width: number;
|
|
38
|
-
height: number;
|
|
39
22
|
}
|
|
40
|
-
export declare const NODE_DIMENSIONS: Record<NodeType, FlowDimensions>;
|
|
41
|
-
export declare const GRID_SPACING: {
|
|
42
|
-
readonly HORIZONTAL: number;
|
|
43
|
-
readonly VERTICAL: number;
|
|
44
|
-
readonly TASK_DATA_X_GAP: number;
|
|
45
|
-
readonly GROUP_Y_OFFSET: number;
|
|
46
|
-
};
|
|
47
|
-
export declare const TASK_DATA_LAYOUT: {
|
|
48
|
-
readonly VALIDATION_NODE_Y_GAP: number;
|
|
49
|
-
readonly TRANSFORMATION_NODE_Y_GAP: number;
|
|
50
|
-
readonly PUSH_STEP_NODE_Y_GAP: number;
|
|
51
|
-
readonly PUSH_STEP_NODE_X_GAP: number;
|
|
52
|
-
readonly PUSH_STEP_BRANCH_X_GAP: number;
|
|
53
|
-
readonly EXPANDED_GROUP_X: number;
|
|
54
|
-
readonly EXPANDED_GROUP_Y_START: number;
|
|
55
|
-
readonly TREE_LEVEL_Y_GAP: number;
|
|
56
|
-
readonly TREE_SIBLING_X_GAP: number;
|
|
57
|
-
readonly TREE_MIN_WIDTH: number;
|
|
58
|
-
};
|
|
59
23
|
export declare const FLOW_EDGE: {
|
|
60
24
|
readonly width: number;
|
|
61
25
|
readonly marker: number;
|
|
@@ -68,24 +32,25 @@ export declare const FLOW_ICON: {
|
|
|
68
32
|
readonly large: number;
|
|
69
33
|
};
|
|
70
34
|
/** CSS bindings stay reactive to the source theme/locale without rebuilding a graph. */
|
|
71
|
-
export declare function
|
|
72
|
-
export
|
|
73
|
-
/**
|
|
74
|
-
export declare function
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
export declare function getFlowCategoryStyles(type: string, part?: FlowCategoryPart): CSSProperties;
|
|
78
|
-
/** Paired native Tag paint; a category stroke is not an on-bold background. */
|
|
79
|
-
export declare function getFlowCategoryBadgeStyles(type: string): Readonly<CSSProperties>;
|
|
35
|
+
export declare function getFlowTonePalette(tone: FlowTone): FlowTonePalette;
|
|
36
|
+
export type FlowTonePart = 'foreground' | 'border' | 'background';
|
|
37
|
+
/** Apply a tone role to custom content without a consumer-owned recipe. */
|
|
38
|
+
export declare function getFlowToneStyles(tone: FlowTone, part?: FlowTonePart): CSSProperties;
|
|
39
|
+
/** Paired native Tag paint; a tone stroke is not an on-bold background. */
|
|
40
|
+
export declare function getFlowToneBadgeStyles(tone: FlowTone): Readonly<CSSProperties>;
|
|
80
41
|
export interface FlowIconOptions {
|
|
81
42
|
size?: keyof typeof FLOW_ICON | number;
|
|
82
43
|
color?: string;
|
|
83
44
|
disabled?: boolean;
|
|
84
45
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
46
|
+
export type FlowIconRole = 'status-success' | 'status-warning' | 'status-error' | 'status-info' | 'status-loading' | 'control-expand' | 'control-collapse' | 'control-help';
|
|
47
|
+
/** Tone glyphs take the tone's border role; status/control glyphs keep their own source roles. */
|
|
48
|
+
export declare function getFlowIconStyles(role: FlowIconRole | FlowTone, options?: FlowIconOptions): CSSProperties;
|
|
49
|
+
/**
|
|
50
|
+
* SVG presentation recipe for a custom edge path. A supplied directed target stroke wins over
|
|
51
|
+
* the tone fallback; a supplied static dash is kept (the consumer owns what a dash means).
|
|
52
|
+
*/
|
|
53
|
+
export declare function getFlowEdgeStyles(tone: FlowTone, suppliedStyle?: CSSProperties): Styles;
|
|
89
54
|
export declare const FLOW_VIEWPORT: {
|
|
90
55
|
minZoom: number;
|
|
91
56
|
maxZoom: number;
|
|
@@ -109,12 +74,23 @@ export interface VueFlowTheme {
|
|
|
109
74
|
}
|
|
110
75
|
/** Apply to the actual VueFlow host; import the CSS companion after upstream styles. */
|
|
111
76
|
export declare function createVueFlowTheme(options?: VueFlowThemeOptions): VueFlowTheme;
|
|
112
|
-
/**
|
|
113
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Preserve target identity for both the visible stroke and arrow marker. `toneOf` resolves the
|
|
79
|
+
* target node's tone (`blue` when omitted, or when the target is missing).
|
|
80
|
+
*/
|
|
81
|
+
export declare function styleTargetEdge(edge: Edge, nodes: readonly Node[], toneOf?: (node: Node) => FlowTone): Edge;
|
|
82
|
+
/** A custom node body: its tone and the consumer-owned fixed geometry. */
|
|
83
|
+
export interface FlowNodeLook {
|
|
84
|
+
tone: FlowTone;
|
|
85
|
+
width: number;
|
|
86
|
+
height: number;
|
|
87
|
+
/** `circle` rounds the body fully; `rectangle` (default) uses `radius.100`. */
|
|
88
|
+
shape?: 'rectangle' | 'circle';
|
|
89
|
+
}
|
|
114
90
|
export interface FlowNodeState {
|
|
115
91
|
hovered?: boolean;
|
|
116
92
|
selected?: boolean;
|
|
117
|
-
|
|
93
|
+
dashed?: boolean;
|
|
118
94
|
}
|
|
119
95
|
export interface FlowNodeStyles {
|
|
120
96
|
container: Styles;
|
|
@@ -123,11 +99,9 @@ export interface FlowNodeStyles {
|
|
|
123
99
|
label: CSSProperties;
|
|
124
100
|
text: CSSProperties;
|
|
125
101
|
loadingIcon: CSSProperties;
|
|
126
|
-
|
|
127
|
-
connectorFlow: CSSProperties;
|
|
128
|
-
connectorArrow: CSSProperties;
|
|
102
|
+
logo: CSSProperties;
|
|
129
103
|
}
|
|
130
|
-
/** Custom content and layout share fixed
|
|
131
|
-
export declare function getFlowNodeStyles(
|
|
104
|
+
/** Custom content and layout share fixed consumer geometry, not viewport-dependent sizing. */
|
|
105
|
+
export declare function getFlowNodeStyles(look: FlowNodeLook, state?: FlowNodeState): FlowNodeStyles;
|
|
132
106
|
/** Minimal detail removes costly decoration, never semantic contrast or graph data. */
|
|
133
107
|
export declare function getFlowDetailStyles(level: 'minimal' | 'basic' | 'detailed', suppliedStyle: Styles): Styles;
|
package/dist/index.js
CHANGED
|
@@ -1,46 +1,23 @@
|
|
|
1
1
|
import { tokens } from '@beehexa/design-tokens';
|
|
2
2
|
import { MarkerType } from '@vue-flow/core';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
NodeType["PROFILE"] = "profile";
|
|
18
|
-
})(NodeType || (NodeType = {}));
|
|
3
|
+
/**
|
|
4
|
+
* Generic colour tones. Each tone reads one existing foundation `flow.category.<key>` role set;
|
|
5
|
+
* the foundation keys keep their names and the package gives a tone no domain meaning. The
|
|
6
|
+
* consumer decides which of its own concepts takes which tone.
|
|
7
|
+
*/
|
|
8
|
+
export const FLOW_TONES = ['blue', 'red', 'green', 'crimson', 'yellow', 'teal', 'magenta', 'purple'];
|
|
9
|
+
/** Tone → existing foundation role set (unchanged foundation names). */
|
|
10
|
+
const toneRoles = {
|
|
11
|
+
blue: 'flow.category.task', red: 'flow.category.dependency', green: 'flow.category.transformation',
|
|
12
|
+
crimson: 'flow.category.validation', yellow: 'flow.category.pushStep', teal: 'flow.category.decision',
|
|
13
|
+
magenta: 'flow.category.loop', purple: 'flow.category.grouped'
|
|
14
|
+
};
|
|
15
|
+
/** VueFlow's default node colour; the fallback tone wherever the consumer supplies none. */
|
|
16
|
+
const DEFAULT_TONE = 'blue';
|
|
19
17
|
const numberToken = (name) => {
|
|
20
18
|
const value = tokens.light[name];
|
|
21
19
|
return Number.parseFloat(value) * (value.endsWith('rem') ? 16 : 1);
|
|
22
20
|
};
|
|
23
|
-
export const NODE_DIMENSIONS = Object.fromEntries(Object.values(NodeType).map(type => [type, {
|
|
24
|
-
width: numberToken(`flow.geometry.${type}.width`),
|
|
25
|
-
height: numberToken(`flow.geometry.${type}.height`)
|
|
26
|
-
}]));
|
|
27
|
-
export const GRID_SPACING = {
|
|
28
|
-
HORIZONTAL: numberToken('flow.grid.HORIZONTAL'), VERTICAL: numberToken('flow.grid.VERTICAL'),
|
|
29
|
-
TASK_DATA_X_GAP: numberToken('flow.grid.TASK_DATA_X_GAP'),
|
|
30
|
-
GROUP_Y_OFFSET: numberToken('flow.grid.GROUP_Y_OFFSET')
|
|
31
|
-
};
|
|
32
|
-
export const TASK_DATA_LAYOUT = {
|
|
33
|
-
VALIDATION_NODE_Y_GAP: numberToken('flow.layout.VALIDATION_NODE_Y_GAP'),
|
|
34
|
-
TRANSFORMATION_NODE_Y_GAP: numberToken('flow.layout.TRANSFORMATION_NODE_Y_GAP'),
|
|
35
|
-
PUSH_STEP_NODE_Y_GAP: numberToken('flow.layout.PUSH_STEP_NODE_Y_GAP'),
|
|
36
|
-
PUSH_STEP_NODE_X_GAP: numberToken('flow.layout.PUSH_STEP_NODE_X_GAP'),
|
|
37
|
-
PUSH_STEP_BRANCH_X_GAP: numberToken('flow.layout.PUSH_STEP_BRANCH_X_GAP'),
|
|
38
|
-
EXPANDED_GROUP_X: numberToken('flow.layout.EXPANDED_GROUP_X'),
|
|
39
|
-
EXPANDED_GROUP_Y_START: numberToken('flow.layout.EXPANDED_GROUP_Y_START'),
|
|
40
|
-
TREE_LEVEL_Y_GAP: numberToken('flow.layout.TREE_LEVEL_Y_GAP'),
|
|
41
|
-
TREE_SIBLING_X_GAP: numberToken('flow.layout.TREE_SIBLING_X_GAP'),
|
|
42
|
-
TREE_MIN_WIDTH: numberToken('flow.layout.TREE_MIN_WIDTH')
|
|
43
|
-
};
|
|
44
21
|
export const FLOW_EDGE = {
|
|
45
22
|
width: numberToken('flow.edge.width'), marker: numberToken('flow.edge.marker'),
|
|
46
23
|
radius: numberToken('flow.edge.radius'), handle: numberToken('flow.edge.handle')
|
|
@@ -49,51 +26,32 @@ export const FLOW_ICON = {
|
|
|
49
26
|
small: numberToken('size.icon.default'), medium: numberToken('size.icon.medium'),
|
|
50
27
|
large: numberToken('size.icon.large')
|
|
51
28
|
};
|
|
52
|
-
const nodeCategories = {
|
|
53
|
-
task: 'task', task_data: 'task', profile: 'task', dependency: 'dependency', task_dependency: 'dependency',
|
|
54
|
-
task_transformation: 'transformation', transformation: 'transformation',
|
|
55
|
-
transformationGroup: 'transformation', validation: 'validation',
|
|
56
|
-
validationGroup: 'validation', push_step: 'pushStep', pushStep: 'pushStep',
|
|
57
|
-
pushStepsGroup: 'pushStep', decision: 'decision', loop: 'loop', grouped: 'grouped'
|
|
58
|
-
};
|
|
59
29
|
const variable = (name) => `var(--bh-${name.replaceAll('.', '-')})`;
|
|
60
|
-
const palettes = Object.fromEntries(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const role = (part) => variable(`flow.category.${category}.${part}`);
|
|
64
|
-
return [category, {
|
|
30
|
+
const palettes = Object.fromEntries(FLOW_TONES.map(tone => {
|
|
31
|
+
const role = (part) => variable(`${toneRoles[tone]}.${part}`);
|
|
32
|
+
return [tone, {
|
|
65
33
|
primary: role('border'), text: role('foreground'), background: role('background'),
|
|
66
|
-
border: role('border'), hover: role('hover')
|
|
67
|
-
connector: { bg: role('background'), border: role('border'), logoBorder: role('border') }
|
|
34
|
+
border: role('border'), hover: role('hover')
|
|
68
35
|
}];
|
|
69
36
|
}));
|
|
70
37
|
/** CSS bindings stay reactive to the source theme/locale without rebuilding a graph. */
|
|
71
|
-
export function
|
|
72
|
-
return palettes[
|
|
38
|
+
export function getFlowTonePalette(tone) {
|
|
39
|
+
return palettes[tone];
|
|
73
40
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
/** Unknown/custom node types retain the task category, matching VueFlow's default node. */
|
|
79
|
-
export function getNodeColor(type) {
|
|
80
|
-
return palettes[nodeCategories[type] ?? 'task'].border;
|
|
81
|
-
}
|
|
82
|
-
/** Apply a category role to custom semantic content without a consumer-owned recipe. */
|
|
83
|
-
export function getFlowCategoryStyles(type, part = 'foreground') {
|
|
84
|
-
const palette = palettes[nodeCategories[type] ?? 'task'];
|
|
41
|
+
/** Apply a tone role to custom content without a consumer-owned recipe. */
|
|
42
|
+
export function getFlowToneStyles(tone, part = 'foreground') {
|
|
43
|
+
const palette = palettes[tone];
|
|
85
44
|
if (part === 'border')
|
|
86
45
|
return { borderColor: palette.border };
|
|
87
46
|
if (part === 'background')
|
|
88
47
|
return { backgroundColor: palette.background };
|
|
89
48
|
return { color: palette.text };
|
|
90
49
|
}
|
|
91
|
-
const
|
|
92
|
-
/** Paired native Tag paint; a
|
|
93
|
-
export function
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
return categoryBadgeStyles[category] ??= Object.freeze({
|
|
50
|
+
const toneBadgeStyles = {};
|
|
51
|
+
/** Paired native Tag paint; a tone stroke is not an on-bold background. */
|
|
52
|
+
export function getFlowToneBadgeStyles(tone) {
|
|
53
|
+
const palette = palettes[tone];
|
|
54
|
+
return toneBadgeStyles[tone] ??= Object.freeze({
|
|
97
55
|
color: palette.text,
|
|
98
56
|
backgroundColor: palette.background,
|
|
99
57
|
borderColor: palette.border
|
|
@@ -105,25 +63,24 @@ const iconRoles = {
|
|
|
105
63
|
'status-loading': 'color.icon.info', 'control-expand': 'color.icon',
|
|
106
64
|
'control-collapse': 'color.icon', 'control-help': 'color.icon'
|
|
107
65
|
};
|
|
108
|
-
/**
|
|
109
|
-
export function getFlowIconStyles(
|
|
66
|
+
/** Tone glyphs take the tone's border role; status/control glyphs keep their own source roles. */
|
|
67
|
+
export function getFlowIconStyles(role, options = {}) {
|
|
110
68
|
const size = options.size ?? 'medium';
|
|
111
|
-
const category = type.startsWith('edge-') ? type.slice(5) : type;
|
|
112
69
|
return {
|
|
113
70
|
fontSize: `${typeof size === 'number' ? size : FLOW_ICON[size]}px`,
|
|
114
71
|
color: options.disabled ? variable('color.icon.disabled') :
|
|
115
|
-
options.color ?? (iconRoles
|
|
72
|
+
options.color ?? (role in iconRoles ? variable(iconRoles[role]) : palettes[role].border),
|
|
116
73
|
display: 'inline-flex', alignItems: 'center', justifyContent: 'center'
|
|
117
74
|
};
|
|
118
75
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
export function getFlowEdgeStyles(
|
|
76
|
+
/**
|
|
77
|
+
* SVG presentation recipe for a custom edge path. A supplied directed target stroke wins over
|
|
78
|
+
* the tone fallback; a supplied static dash is kept (the consumer owns what a dash means).
|
|
79
|
+
*/
|
|
80
|
+
export function getFlowEdgeStyles(tone, suppliedStyle) {
|
|
124
81
|
return {
|
|
125
|
-
stroke: suppliedStyle?.stroke ??
|
|
126
|
-
strokeWidth: FLOW_EDGE.width, strokeDasharray:
|
|
82
|
+
stroke: suppliedStyle?.stroke ?? palettes[tone].border,
|
|
83
|
+
strokeWidth: FLOW_EDGE.width, strokeDasharray: suppliedStyle?.strokeDasharray,
|
|
127
84
|
fill: 'none', vectorEffect: 'non-scaling-stroke'
|
|
128
85
|
};
|
|
129
86
|
}
|
|
@@ -135,6 +92,7 @@ export const FLOW_VIEWPORT = {
|
|
|
135
92
|
export function createVueFlowTheme(options = {}) {
|
|
136
93
|
const mode = { ...tokens.light, ...(options.dark ? tokens.dark : {}) };
|
|
137
94
|
const typography = options.locale === 'vi' ? { ...mode, ...tokens.vi } : mode;
|
|
95
|
+
const nodeTone = options.nodeTone ?? (() => DEFAULT_TONE);
|
|
138
96
|
return {
|
|
139
97
|
class: 'bh-vue-flow',
|
|
140
98
|
style: {
|
|
@@ -149,16 +107,19 @@ export function createVueFlowTheme(options = {}) {
|
|
|
149
107
|
},
|
|
150
108
|
flowOptions: { ...FLOW_VIEWPORT, snapGrid: [...FLOW_VIEWPORT.snapGrid] },
|
|
151
109
|
minimap: {
|
|
152
|
-
nodeColor: node =>
|
|
110
|
+
nodeColor: node => palettes[nodeTone(node)].border,
|
|
153
111
|
maskColor: variable('color.surface.scrim'), nodeStrokeColor: variable('color.border.bold')
|
|
154
112
|
},
|
|
155
113
|
background: { patternColor: variable('color.border'), bgColor: mode['color.surface.page'] }
|
|
156
114
|
};
|
|
157
115
|
}
|
|
158
|
-
/**
|
|
159
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Preserve target identity for both the visible stroke and arrow marker. `toneOf` resolves the
|
|
118
|
+
* target node's tone (`blue` when omitted, or when the target is missing).
|
|
119
|
+
*/
|
|
120
|
+
export function styleTargetEdge(edge, nodes, toneOf = () => DEFAULT_TONE) {
|
|
160
121
|
const target = nodes.find(node => node.id === edge.target);
|
|
161
|
-
const stroke =
|
|
122
|
+
const stroke = palettes[target ? toneOf(target) : DEFAULT_TONE].border;
|
|
162
123
|
return {
|
|
163
124
|
...edge, animated: false,
|
|
164
125
|
style: { ...(typeof edge.style === 'object' ? edge.style : {}), stroke },
|
|
@@ -170,11 +131,9 @@ export function styleTargetEdge(edge, nodes) {
|
|
|
170
131
|
}
|
|
171
132
|
};
|
|
172
133
|
}
|
|
173
|
-
/** Custom content and layout share fixed
|
|
174
|
-
export function getFlowNodeStyles(
|
|
175
|
-
const
|
|
176
|
-
const palette = palettes[nodeCategories[type] ?? 'task'];
|
|
177
|
-
const round = type === NodeType.LOOP || type === NodeType.DECISION;
|
|
134
|
+
/** Custom content and layout share fixed consumer geometry, not viewport-dependent sizing. */
|
|
135
|
+
export function getFlowNodeStyles(look, state = {}) {
|
|
136
|
+
const palette = palettes[look.tone];
|
|
178
137
|
const label = {
|
|
179
138
|
font: variable('font.label.default'), color: palette.text, textAlign: 'center',
|
|
180
139
|
overflowWrap: 'anywhere', width: '100%'
|
|
@@ -185,12 +144,12 @@ export function getFlowNodeStyles(type, state = {}) {
|
|
|
185
144
|
};
|
|
186
145
|
return {
|
|
187
146
|
container: {
|
|
188
|
-
width: `${
|
|
147
|
+
width: `${look.width}px`, height: `${look.height}px`,
|
|
189
148
|
boxSizing: 'border-box', display: 'flex', flexDirection: 'column',
|
|
190
149
|
alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
|
|
191
150
|
border: `${variable('border.width.selected')} solid ${palette.border}`,
|
|
192
|
-
borderStyle: state.
|
|
193
|
-
borderRadius:
|
|
151
|
+
borderStyle: state.dashed ? 'dashed' : 'solid',
|
|
152
|
+
borderRadius: look.shape === 'circle' ? '50%' : variable('radius.100'),
|
|
194
153
|
background: state.hovered ? palette.hover : palette.background,
|
|
195
154
|
color: palette.text, font: variable('font.body.default'),
|
|
196
155
|
outline: state.selected ? `${variable('border.width.selected')} solid ${variable('color.border.selected')}` : undefined,
|
|
@@ -202,9 +161,7 @@ export function getFlowNodeStyles(type, state = {}) {
|
|
|
202
161
|
padding: variable('space.150'), gap: variable('space.050')
|
|
203
162
|
},
|
|
204
163
|
icon, label, text: label, loadingIcon: icon,
|
|
205
|
-
|
|
206
|
-
connectorFlow: { display: 'flex', alignItems: 'center', gap: variable('space.100') },
|
|
207
|
-
connectorArrow: { color: palette.primary, font: variable('font.label.default') }
|
|
164
|
+
logo: { borderRadius: variable('radius.075'), objectFit: 'contain' }
|
|
208
165
|
};
|
|
209
166
|
}
|
|
210
167
|
/** Minimal detail removes costly decoration, never semantic contrast or graph data. */
|
package/dist/styles.css
CHANGED
|
@@ -71,7 +71,8 @@
|
|
|
71
71
|
.bh-vue-flow .vue-flow__edge-textbg { fill: var(--bh-color-surface); }
|
|
72
72
|
.bh-vue-flow .vue-flow__selection,
|
|
73
73
|
.bh-vue-flow .vue-flow__nodesselection-rect {
|
|
74
|
-
|
|
74
|
+
/* Transparent: the swept cards stay visible through the box; only the dashed focus border marks it. */
|
|
75
|
+
background: transparent;
|
|
75
76
|
border: var(--bh-border-width-selected) dashed var(--bh-color-border-focus);
|
|
76
77
|
}
|
|
77
78
|
.bh-vue-flow .vue-flow__controls {
|
|
@@ -155,8 +156,9 @@
|
|
|
155
156
|
.bh-flow-icon[data-bh-loading='true'] { animation: none; }
|
|
156
157
|
}
|
|
157
158
|
|
|
158
|
-
/* Labelled relationship markers identify
|
|
159
|
-
.
|
|
159
|
+
/* Labelled relationship markers identify a colour tone, never operational status. Tones map
|
|
160
|
+
onto the existing foundation `flow.category.*` border roles (see FlowTone in index.ts). */
|
|
161
|
+
.bh-flow-tone-mark {
|
|
160
162
|
display: inline-block;
|
|
161
163
|
flex: none;
|
|
162
164
|
width: var(--bh-space-075);
|
|
@@ -164,13 +166,13 @@
|
|
|
164
166
|
border-radius: 50%;
|
|
165
167
|
background: var(--bh-flow-category-task-border);
|
|
166
168
|
}
|
|
167
|
-
.bh-flow-
|
|
168
|
-
.bh-flow-
|
|
169
|
-
.bh-flow-
|
|
170
|
-
.bh-flow-
|
|
171
|
-
.bh-flow-
|
|
172
|
-
.bh-flow-
|
|
173
|
-
.bh-flow-
|
|
169
|
+
.bh-flow-tone-mark[data-bh-tone='red'] { background: var(--bh-flow-category-dependency-border); }
|
|
170
|
+
.bh-flow-tone-mark[data-bh-tone='green'] { background: var(--bh-flow-category-transformation-border); }
|
|
171
|
+
.bh-flow-tone-mark[data-bh-tone='crimson'] { background: var(--bh-flow-category-validation-border); }
|
|
172
|
+
.bh-flow-tone-mark[data-bh-tone='yellow'] { background: var(--bh-flow-category-pushStep-border); }
|
|
173
|
+
.bh-flow-tone-mark[data-bh-tone='teal'] { background: var(--bh-flow-category-decision-border); }
|
|
174
|
+
.bh-flow-tone-mark[data-bh-tone='magenta'] { background: var(--bh-flow-category-loop-border); }
|
|
175
|
+
.bh-flow-tone-mark[data-bh-tone='purple'] { background: var(--bh-flow-category-grouped-border); }
|
|
174
176
|
|
|
175
177
|
/* Native workflow-canvas theme variables are its public styling API. Scope the host
|
|
176
178
|
protocol here; never change application-wide primary/text variables. */
|
|
@@ -200,6 +202,19 @@
|
|
|
200
202
|
--wf-edge: var(--bh-diagram-edge);
|
|
201
203
|
--wf-edge-active: var(--bh-diagram-selection-ring);
|
|
202
204
|
--wf-edge-failure: var(--bh-diagram-fail-stroke);
|
|
205
|
+
/* Possible/context/toned-failure cues are shapes, never new dashes or opacity: context is a thinner resting
|
|
206
|
+
stroke (with the native open arrowhead); a toned failure keeps its tone dash and adds a circle-x mark.
|
|
207
|
+
Package-owned variable: it reads the foundation border width, no flow-specific token. */
|
|
208
|
+
--wf-edge-context-width: var(--bh-border-width-default);
|
|
209
|
+
--wf-edge-failure-icon: var(--bh-color-icon-danger);
|
|
210
|
+
/* Generic colour tones for `WorkflowEdge.tone`, mapped onto the existing foundation category border roles.
|
|
211
|
+
Tones are categorical, never execution/failure states; each keeps its static non-colour dash cue. */
|
|
212
|
+
--wf-edge-tone-blue: var(--bh-flow-category-task-border);
|
|
213
|
+
--wf-edge-tone-blue-dash: none;
|
|
214
|
+
--wf-edge-tone-red: var(--bh-flow-category-dependency-border);
|
|
215
|
+
--wf-edge-tone-red-dash: 2 4;
|
|
216
|
+
--wf-edge-tone-green: var(--bh-flow-category-transformation-border);
|
|
217
|
+
--wf-edge-tone-green-dash: 9 3 2 3;
|
|
203
218
|
--wf-label-bg: var(--bh-diagram-edge-label-bg);
|
|
204
219
|
--wf-label-fg: var(--bh-diagram-edge-label-text);
|
|
205
220
|
--wf-label-border: var(--bh-color-border);
|
|
@@ -210,6 +225,8 @@
|
|
|
210
225
|
--wf-dock-height: calc(var(--bh-size-control-default) + var(--bh-space-100) + 2 * var(--bh-border-width-default));
|
|
211
226
|
--wf-chrome-radius: var(--bh-radius-050);
|
|
212
227
|
--wf-node-width: var(--bh-diagram-card-width);
|
|
228
|
+
--wf-node-content-min-width: var(--bh-diagram-card-width);
|
|
229
|
+
--wf-node-content-max-width: calc(2 * var(--bh-diagram-card-width));
|
|
213
230
|
--wf-node-bg: var(--bh-diagram-node-fill);
|
|
214
231
|
--wf-node-fg: var(--bh-diagram-node-title);
|
|
215
232
|
--wf-node-muted: var(--bh-diagram-node-desc);
|
|
@@ -227,6 +244,19 @@
|
|
|
227
244
|
--wf-tone-fg: var(--bh-diagram-tile-glyph);
|
|
228
245
|
--wf-node-kind-bg: var(--bh-diagram-node-fill);
|
|
229
246
|
--wf-node-kind-fg: var(--bh-diagram-node-desc);
|
|
247
|
+
/* Group frames (the native `wf-group` node). Package-owned variables over foundation roles; the native layout
|
|
248
|
+
reads padding and header gap from here, so both stay plain lengths. */
|
|
249
|
+
--wf-group-border: var(--bh-color-border);
|
|
250
|
+
--wf-group-border-width: var(--bh-border-width-default);
|
|
251
|
+
--wf-group-radius: var(--bh-radius-card);
|
|
252
|
+
--wf-group-bg: var(--bh-color-surface-subtle);
|
|
253
|
+
--wf-group-nested-bg: var(--bh-color-background-neutral);
|
|
254
|
+
--wf-group-padding: var(--bh-space-stack);
|
|
255
|
+
--wf-group-header-gap: var(--bh-space-150);
|
|
256
|
+
/* The Shift + drag selection box: the same recipe as `.bh-vue-flow .vue-flow__selection` (transparent, dashed). */
|
|
257
|
+
--wf-selection-bg: transparent;
|
|
258
|
+
--wf-selection-border: var(--bh-color-border-focus);
|
|
259
|
+
--wf-selection-border-width: var(--bh-border-width-selected);
|
|
230
260
|
}
|
|
231
261
|
/* Opt-in graph contrast uses theme-resolved semantic ink, not a fixed light-mode
|
|
232
262
|
palette. Preserve selection/failure colours and native edge/arrow pairing. */
|
|
@@ -241,6 +271,7 @@
|
|
|
241
271
|
--wf-node-muted: var(--bh-color-text);
|
|
242
272
|
--wf-node-kind-fg: var(--bh-color-text);
|
|
243
273
|
--wf-tone-fg: var(--bh-color-text);
|
|
274
|
+
--wf-group-border: var(--bh-color-text);
|
|
244
275
|
}
|
|
245
276
|
/* Execution belongs to the node outline/content; the independent outer ring
|
|
246
277
|
continues to carry selection, hover and keyboard focus. */
|
|
@@ -292,9 +323,21 @@
|
|
|
292
323
|
.bh-workflow-canvas .wf-node.wf-node--shape-stadium { width: max-content; }
|
|
293
324
|
.bh-workflow-canvas .wf-node__title {
|
|
294
325
|
white-space: normal;
|
|
295
|
-
overflow-wrap: anywhere;
|
|
296
326
|
font: var(--bh-font-heading-xsmall);
|
|
297
327
|
}
|
|
328
|
+
/* A card may break a long unbroken title anywhere. A diamond or ellipse wraps its title and its kind caption at word
|
|
329
|
+
boundaries and never truncates them: its side padding follows its width, so a mid-word break reads as two words and
|
|
330
|
+
an ellipsis hides the node's own name. Only a single word wider than the whole content box breaks. */
|
|
331
|
+
.bh-workflow-canvas .wf-node:not(.wf-node--shape-diamond, .wf-node--shape-ellipse) .wf-node__title {
|
|
332
|
+
overflow-wrap: anywhere;
|
|
333
|
+
}
|
|
334
|
+
.bh-workflow-canvas :is(.wf-node--shape-diamond, .wf-node--shape-ellipse) :is(.wf-node__title, .wf-node__kind) {
|
|
335
|
+
max-width: 100%;
|
|
336
|
+
white-space: normal;
|
|
337
|
+
overflow: visible;
|
|
338
|
+
overflow-wrap: break-word;
|
|
339
|
+
text-overflow: clip;
|
|
340
|
+
}
|
|
298
341
|
.bh-workflow-canvas .wf-node__head { height: auto; }
|
|
299
342
|
.bh-workflow-canvas .wf-node__subtitle {
|
|
300
343
|
font: var(--bh-font-body-default);
|
|
@@ -310,6 +353,18 @@
|
|
|
310
353
|
width: auto;
|
|
311
354
|
flex: none;
|
|
312
355
|
}
|
|
356
|
+
/* Opt-in ordinary-card recipe. The native theme owns the content width mechanism within the
|
|
357
|
+
`--wf-node-content-*` roles bound above; the head and logo flex are global rules here. Title/kind
|
|
358
|
+
wrap and the logo bound keep long titles and every logo readable. */
|
|
359
|
+
.bh-workflow-canvas .wf-node[data-sizing='content']:not(.wf-node--shape-diamond, .wf-node--shape-ellipse)
|
|
360
|
+
:is(.wf-node__title, .wf-node__kind) {
|
|
361
|
+
white-space: normal;
|
|
362
|
+
overflow: visible;
|
|
363
|
+
overflow-wrap: anywhere;
|
|
364
|
+
}
|
|
365
|
+
.bh-workflow-canvas .wf-node[data-sizing='content'] .wf-node__logos > img {
|
|
366
|
+
max-width: 100%;
|
|
367
|
+
}
|
|
313
368
|
.bh-workflow-canvas .wf-node__execution > svg,
|
|
314
369
|
.bh-workflow-canvas .wf-node__indicators svg {
|
|
315
370
|
width: auto;
|
|
@@ -359,11 +414,57 @@
|
|
|
359
414
|
width: auto;
|
|
360
415
|
height: var(--bh-size-icon-default);
|
|
361
416
|
}
|
|
417
|
+
/* Native find box (WorkflowFind, the viewer's `/` search). It is an overlay holding a
|
|
418
|
+
search field and result rows: surface.overlay with elevation.shadow.overlay and
|
|
419
|
+
radius.overlay, no border (overlays are set apart by surface and shadow), a
|
|
420
|
+
color.border divider under the field. Rows take the overlay item states one step
|
|
421
|
+
apart: hover surface.overlay.hover; the keyboard-active row (aria-selected)
|
|
422
|
+
surface.overlay.selected plus the border.selected start bar as its non-colour cue;
|
|
423
|
+
that row hovered surface.overlay.selected.hover. Text keeps color.text in every
|
|
424
|
+
state. The shared --wf-list-* roles also paint the jump list and dock menu rows. */
|
|
425
|
+
.bh-workflow-canvas .wf-canvas {
|
|
426
|
+
--wf-list-bg: var(--bh-color-surface-overlay);
|
|
427
|
+
--wf-list-fg: var(--bh-color-text);
|
|
428
|
+
--wf-list-muted: var(--bh-color-text-subtle);
|
|
429
|
+
--wf-list-border: var(--bh-color-border);
|
|
430
|
+
--wf-list-hover: var(--bh-color-surface-overlay-hover);
|
|
431
|
+
--wf-list-active: var(--bh-color-surface-overlay-selected);
|
|
432
|
+
--wf-list-active-hover: var(--bh-color-surface-overlay-selected-hover);
|
|
433
|
+
--wf-list-indicator: var(--bh-color-border-selected);
|
|
434
|
+
--wf-list-indicator-width: var(--bh-border-width-selected);
|
|
435
|
+
--wf-list-failure: var(--bh-color-text-danger);
|
|
436
|
+
--wf-find-border-width: 0;
|
|
437
|
+
--wf-find-radius: var(--bh-radius-overlay);
|
|
438
|
+
--wf-find-input-padding: var(--bh-space-075) var(--bh-space-control-x);
|
|
439
|
+
--wf-find-placeholder: var(--bh-color-text-subtlest);
|
|
440
|
+
--wf-find-list-padding: var(--bh-space-overlay);
|
|
441
|
+
--wf-find-option-padding: var(--bh-space-075) var(--bh-space-item-x);
|
|
442
|
+
--wf-find-option-min-height: var(--bh-size-control-default);
|
|
443
|
+
--wf-find-option-radius: var(--bh-radius-item);
|
|
444
|
+
--wf-find-empty-padding: var(--bh-space-075) var(--bh-space-control-x);
|
|
445
|
+
}
|
|
446
|
+
/* Search field and empty state body.default, result name label.default, the id of a
|
|
447
|
+
node without a name code.default, the kind label body.small in color.text.subtle
|
|
448
|
+
(--wf-list-muted). Names wrap at word boundaries and are never truncated. Focus is
|
|
449
|
+
the field's ring around the whole box (the companion's --wf-focus-outline). */
|
|
450
|
+
.bh-workflow-canvas .wf-find {
|
|
451
|
+
font: var(--bh-font-body-default);
|
|
452
|
+
}
|
|
453
|
+
.bh-workflow-canvas .wf-find__text {
|
|
454
|
+
font: var(--bh-font-label-default);
|
|
455
|
+
}
|
|
456
|
+
.bh-workflow-canvas .wf-find__id {
|
|
457
|
+
font: var(--bh-font-code-default);
|
|
458
|
+
}
|
|
459
|
+
.bh-workflow-canvas .wf-find__detail {
|
|
460
|
+
font: var(--bh-font-body-small);
|
|
461
|
+
}
|
|
362
462
|
@media (pointer: coarse), (width < 768px) {
|
|
363
463
|
.bh-workflow-canvas {
|
|
364
464
|
--wf-control-height: var(--bh-size-target-touch);
|
|
365
465
|
}
|
|
366
466
|
.bh-workflow-canvas .wf-canvas {
|
|
367
467
|
--wf-dock-height: calc(var(--bh-size-target-touch) + var(--bh-space-100) + 2 * var(--bh-border-width-default));
|
|
468
|
+
--wf-find-option-min-height: var(--bh-size-target-touch);
|
|
368
469
|
}
|
|
369
470
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beehexa/vueflow-tokens",
|
|
3
|
-
"version": "2611.
|
|
4
|
-
"description": "Source-backed Beehexa theme
|
|
3
|
+
"version": "2611.8.1",
|
|
4
|
+
"description": "Source-backed Beehexa theme and generic colour tones for VueFlow 1",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/beehexacorp/beehexa.design.git",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"./package.json": "./package.json"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@beehexa/design-tokens": "2611.
|
|
32
|
+
"@beehexa/design-tokens": "2611.8.1"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"@vue-flow/core": "^1.0.0",
|