@djangocfg/ui-tools 2.1.157 → 2.1.159

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 (42) hide show
  1. package/README.md +164 -3
  2. package/dist/{Mermaid.client-KMNEPBQJ.cjs → Mermaid.client-2TAFAXPW.cjs} +100 -143
  3. package/dist/Mermaid.client-2TAFAXPW.cjs.map +1 -0
  4. package/dist/{Mermaid.client-3WPNJ4DF.mjs → Mermaid.client-HG24D5KB.mjs} +100 -143
  5. package/dist/Mermaid.client-HG24D5KB.mjs.map +1 -0
  6. package/dist/index.cjs +4 -9
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +2 -2
  9. package/dist/index.d.ts +2 -2
  10. package/dist/index.mjs +4 -9
  11. package/dist/index.mjs.map +1 -1
  12. package/package.json +11 -6
  13. package/src/tools/Mermaid/Mermaid.client.tsx +40 -56
  14. package/src/tools/Mermaid/Mermaid.story.tsx +195 -110
  15. package/src/tools/Mermaid/builders/FlowDiagram/FlowDiagram.ts +96 -0
  16. package/src/tools/Mermaid/builders/FlowDiagram/functions/getEdges.ts +50 -0
  17. package/src/tools/Mermaid/builders/FlowDiagram/functions/getNodes.ts +43 -0
  18. package/src/tools/Mermaid/builders/FlowDiagram/functions/getStyles.ts +90 -0
  19. package/src/tools/Mermaid/builders/FlowDiagram/functions/index.ts +8 -0
  20. package/src/tools/Mermaid/builders/FlowDiagram/index.ts +16 -0
  21. package/src/tools/Mermaid/builders/FlowDiagram/types.ts +130 -0
  22. package/src/tools/Mermaid/builders/JourneyDiagram/JourneyDiagram.ts +88 -0
  23. package/src/tools/Mermaid/builders/JourneyDiagram/index.ts +12 -0
  24. package/src/tools/Mermaid/builders/JourneyDiagram/types.ts +48 -0
  25. package/src/tools/Mermaid/builders/SequenceDiagram/SequenceDiagram.ts +123 -0
  26. package/src/tools/Mermaid/builders/SequenceDiagram/functions/getActivations.ts +30 -0
  27. package/src/tools/Mermaid/builders/SequenceDiagram/functions/getBlocks.ts +112 -0
  28. package/src/tools/Mermaid/builders/SequenceDiagram/functions/getMessages.ts +85 -0
  29. package/src/tools/Mermaid/builders/SequenceDiagram/functions/getNotes.ts +94 -0
  30. package/src/tools/Mermaid/builders/SequenceDiagram/functions/index.ts +16 -0
  31. package/src/tools/Mermaid/builders/SequenceDiagram/index.ts +17 -0
  32. package/src/tools/Mermaid/builders/SequenceDiagram/types.ts +147 -0
  33. package/src/tools/Mermaid/builders/core/DiagramStore.ts +138 -0
  34. package/src/tools/Mermaid/builders/core/index.ts +8 -0
  35. package/src/tools/Mermaid/builders/core/sanitize.ts +78 -0
  36. package/src/tools/Mermaid/builders/core/theme.ts +42 -0
  37. package/src/tools/Mermaid/builders/core/types.ts +183 -0
  38. package/src/tools/Mermaid/builders/index.ts +96 -0
  39. package/src/tools/Mermaid/components/MermaidFullscreenModal.tsx +78 -54
  40. package/src/tools/Mermaid/index.tsx +51 -12
  41. package/dist/Mermaid.client-3WPNJ4DF.mjs.map +0 -1
  42. package/dist/Mermaid.client-KMNEPBQJ.cjs.map +0 -1
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Message builder functions for SequenceDiagram
3
+ * @module Mermaid/builders/SequenceDiagram/functions/getMessages
4
+ */
5
+
6
+ import { DiagramStore } from '../../core/DiagramStore';
7
+ import { MESSAGE_ARROWS } from '../../core/types';
8
+ import { sanitizeLabel } from '../../core/sanitize';
9
+ import type { MessageBuilder, MessageAction, MessageTarget, MessageArrows } from '../types';
10
+
11
+ /**
12
+ * Create message actions for a specific from -> arrow -> to combination
13
+ */
14
+ function createMessageAction(
15
+ store: DiagramStore,
16
+ from: string,
17
+ arrow: string,
18
+ to: string,
19
+ ): MessageAction {
20
+ return {
21
+ msg(text: string) {
22
+ store.add(`${from}${arrow}${to}: ${sanitizeLabel(text)}`);
23
+ },
24
+ activate(text: string) {
25
+ store.add(`${from}${arrow}+${to}: ${sanitizeLabel(text)}`);
26
+ },
27
+ deactivate(text: string) {
28
+ store.add(`${from}${arrow}-${to}: ${sanitizeLabel(text)}`);
29
+ },
30
+ };
31
+ }
32
+
33
+ /**
34
+ * Create message target for a specific from -> arrow combination
35
+ */
36
+ function createMessageTarget<P extends string>(
37
+ store: DiagramStore,
38
+ from: string,
39
+ arrow: string,
40
+ participants: readonly P[],
41
+ ): MessageTarget<P> {
42
+ const target = {} as MessageTarget<P>;
43
+
44
+ participants.forEach((to) => {
45
+ target[to] = createMessageAction(store, from, arrow, to);
46
+ });
47
+
48
+ return target;
49
+ }
50
+
51
+ /**
52
+ * Create arrow selector for a specific from participant
53
+ */
54
+ function createMessageArrows<P extends string>(
55
+ store: DiagramStore,
56
+ from: P,
57
+ participants: readonly P[],
58
+ ): MessageArrows<P> {
59
+ return {
60
+ sync: createMessageTarget(store, from, MESSAGE_ARROWS.sync, participants),
61
+ syncReply: createMessageTarget(store, from, MESSAGE_ARROWS.syncReply, participants),
62
+ async: createMessageTarget(store, from, MESSAGE_ARROWS.async, participants),
63
+ asyncReply: createMessageTarget(store, from, MESSAGE_ARROWS.asyncReply, participants),
64
+ solid: createMessageTarget(store, from, MESSAGE_ARROWS.solid, participants),
65
+ dotted: createMessageTarget(store, from, MESSAGE_ARROWS.dotted, participants),
66
+ cross: createMessageTarget(store, from, MESSAGE_ARROWS.cross, participants),
67
+ crossDotted: createMessageTarget(store, from, MESSAGE_ARROWS.crossDotted, participants),
68
+ };
69
+ }
70
+
71
+ /**
72
+ * Create the full message builder for all participants
73
+ */
74
+ export function createMessageBuilder<P extends string>(
75
+ store: DiagramStore,
76
+ participants: readonly P[],
77
+ ): MessageBuilder<P> {
78
+ const builder = {} as MessageBuilder<P>;
79
+
80
+ participants.forEach((from) => {
81
+ builder[from] = createMessageArrows(store, from, participants);
82
+ });
83
+
84
+ return builder;
85
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Note builder functions for SequenceDiagram
3
+ * @module Mermaid/builders/SequenceDiagram/functions/getNotes
4
+ */
5
+
6
+ import { DiagramStore } from '../../core/DiagramStore';
7
+ import { sanitizeLabel } from '../../core/sanitize';
8
+ import type { NoteBuilder, NoteAction, NoteSideTarget, NoteOverTarget } from '../types';
9
+
10
+ /**
11
+ * Create a single note action
12
+ */
13
+ function createNoteAction(
14
+ store: DiagramStore,
15
+ position: string,
16
+ ): NoteAction {
17
+ return {
18
+ msg(text: string) {
19
+ store.add(`Note ${position}: ${sanitizeLabel(text)}`);
20
+ },
21
+ };
22
+ }
23
+
24
+ /**
25
+ * Create note targets for left/right positions
26
+ */
27
+ function createNoteSideTarget<P extends string>(
28
+ store: DiagramStore,
29
+ position: 'left' | 'right',
30
+ participants: readonly P[],
31
+ ): NoteSideTarget<P> {
32
+ const target = {} as NoteSideTarget<P>;
33
+
34
+ participants.forEach((p) => {
35
+ target[p] = createNoteAction(store, `${position} of ${p}`);
36
+ });
37
+
38
+ return target;
39
+ }
40
+
41
+ /**
42
+ * Create note targets for "over" position (can span multiple participants)
43
+ */
44
+ function createNoteOverTarget<P extends string>(
45
+ store: DiagramStore,
46
+ participants: readonly P[],
47
+ ): NoteOverTarget<P> {
48
+ const target = {} as NoteOverTarget<P>;
49
+
50
+ participants.forEach((first) => {
51
+ // Create object with msg for single participant note
52
+ const obj = {
53
+ msg(text: string) {
54
+ store.add(`Note over ${first}: ${sanitizeLabel(text)}`);
55
+ },
56
+ } as NoteAction & { [K in P]: NoteAction };
57
+
58
+ // Add targets for spanning to other participants
59
+ participants.forEach((second) => {
60
+ if (first !== second) {
61
+ (obj as Record<string, NoteAction>)[second] = {
62
+ msg(text: string) {
63
+ store.add(`Note over ${first},${second}: ${sanitizeLabel(text)}`);
64
+ },
65
+ };
66
+ } else {
67
+ // Self-reference just does single note
68
+ (obj as Record<string, NoteAction>)[second] = {
69
+ msg(text: string) {
70
+ store.add(`Note over ${first}: ${sanitizeLabel(text)}`);
71
+ },
72
+ };
73
+ }
74
+ });
75
+
76
+ target[first] = obj;
77
+ });
78
+
79
+ return target;
80
+ }
81
+
82
+ /**
83
+ * Create the full note builder
84
+ */
85
+ export function createNoteBuilder<P extends string>(
86
+ store: DiagramStore,
87
+ participants: readonly P[],
88
+ ): NoteBuilder<P> {
89
+ return {
90
+ leftOf: createNoteSideTarget(store, 'left', participants),
91
+ rightOf: createNoteSideTarget(store, 'right', participants),
92
+ over: createNoteOverTarget(store, participants),
93
+ };
94
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * SequenceDiagram function exports
3
+ * @module Mermaid/builders/SequenceDiagram/functions
4
+ */
5
+
6
+ export { createMessageBuilder } from './getMessages';
7
+ export { createNoteBuilder } from './getNotes';
8
+ export { createActivationBuilder } from './getActivations';
9
+ export {
10
+ createLoopBuilder,
11
+ createAltBuilder,
12
+ createParBuilder,
13
+ createRectBuilder,
14
+ createCriticalBuilder,
15
+ createBreakBuilder,
16
+ } from './getBlocks';
@@ -0,0 +1,17 @@
1
+ /**
2
+ * SequenceDiagram builder exports
3
+ * @module Mermaid/builders/SequenceDiagram
4
+ */
5
+
6
+ export { SequenceDiagram } from './SequenceDiagram';
7
+ export type {
8
+ ParticipantsObject,
9
+ SequenceDiagramOptions,
10
+ SequenceDiagramBuilder,
11
+ MessageBuilder,
12
+ MessageArrows,
13
+ MessageTarget,
14
+ MessageAction,
15
+ NoteBuilder,
16
+ ActivationBuilder,
17
+ } from './types';
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Types for SequenceDiagram builder
3
+ * @module Mermaid/builders/SequenceDiagram/types
4
+ */
5
+
6
+ import type { ParticipantType, MessageArrowType } from '../core/types';
7
+
8
+ /**
9
+ * Participants definition object
10
+ */
11
+ export type ParticipantsObject<P extends string> = {
12
+ readonly [K in P]: ParticipantType | { type: ParticipantType; alias?: string };
13
+ };
14
+
15
+ /**
16
+ * Options for SequenceDiagram builder
17
+ */
18
+ export interface SequenceDiagramOptions {
19
+ /** Enable auto-numbering of messages */
20
+ autoNumber?: boolean;
21
+ }
22
+
23
+ /**
24
+ * Message action builder
25
+ */
26
+ export interface MessageAction {
27
+ /** Add a message with text */
28
+ msg(text: string): void;
29
+ /** Add a message that activates the target */
30
+ activate(text: string): void;
31
+ /** Add a message that deactivates the target */
32
+ deactivate(text: string): void;
33
+ }
34
+
35
+ /**
36
+ * Target participant selector for messages
37
+ */
38
+ export type MessageTarget<P extends string> = {
39
+ [K in P]: MessageAction;
40
+ };
41
+
42
+ /**
43
+ * Arrow type selector for messages
44
+ */
45
+ export type MessageArrows<P extends string> = {
46
+ /** Synchronous call ->> */
47
+ sync: MessageTarget<P>;
48
+ /** Synchronous reply -->> */
49
+ syncReply: MessageTarget<P>;
50
+ /** Async call -) */
51
+ async: MessageTarget<P>;
52
+ /** Async reply --) */
53
+ asyncReply: MessageTarget<P>;
54
+ /** Solid line -> */
55
+ solid: MessageTarget<P>;
56
+ /** Dotted line --> */
57
+ dotted: MessageTarget<P>;
58
+ /** Cross (failure) -x */
59
+ cross: MessageTarget<P>;
60
+ /** Dotted cross --x */
61
+ crossDotted: MessageTarget<P>;
62
+ };
63
+
64
+ /**
65
+ * Message builder - from participant to arrow type to target
66
+ */
67
+ export type MessageBuilder<P extends string> = {
68
+ [K in P]: MessageArrows<P>;
69
+ };
70
+
71
+ /**
72
+ * Note position types
73
+ */
74
+ export type NotePosition = 'leftOf' | 'rightOf' | 'over';
75
+
76
+ /**
77
+ * Single note action
78
+ */
79
+ export interface NoteAction {
80
+ msg(text: string): void;
81
+ }
82
+
83
+ /**
84
+ * Note target for "over" position (can span multiple participants)
85
+ */
86
+ export type NoteOverTarget<P extends string> = {
87
+ [K in P]: NoteAction & {
88
+ /** Span to another participant */
89
+ [K2 in P]: NoteAction;
90
+ };
91
+ };
92
+
93
+ /**
94
+ * Note target for left/right positions
95
+ */
96
+ export type NoteSideTarget<P extends string> = {
97
+ [K in P]: NoteAction;
98
+ };
99
+
100
+ /**
101
+ * Note builder
102
+ */
103
+ export interface NoteBuilder<P extends string> {
104
+ leftOf: NoteSideTarget<P>;
105
+ rightOf: NoteSideTarget<P>;
106
+ over: NoteOverTarget<P>;
107
+ }
108
+
109
+ /**
110
+ * Activation builder
111
+ */
112
+ export type ActivationBuilder<P extends string> = {
113
+ [K in P]: {
114
+ activate(): void;
115
+ deactivate(): void;
116
+ };
117
+ };
118
+
119
+ /**
120
+ * Main SequenceDiagram builder result
121
+ */
122
+ export interface SequenceDiagramBuilder<P extends string> {
123
+ /** Message builder (d.Alice.sync.Bob.msg("Hello")) */
124
+ d: MessageBuilder<P>;
125
+ /** Note builder (note.over.Alice.msg("Thinking")) */
126
+ note: NoteBuilder<P>;
127
+ /** Activation builder (activate.Alice.activate()) */
128
+ activate: ActivationBuilder<P>;
129
+ /** Loop block */
130
+ loop(label: string, fn: () => void): void;
131
+ /** Optional/alternative block */
132
+ alt(label: string, fn: () => void): { else(label: string, fn: () => void): void };
133
+ /** Parallel block */
134
+ par(label: string, fn: () => void): { and(label: string, fn: () => void): void };
135
+ /** Colored rectangle box */
136
+ rect(color: string, fn: () => void): void;
137
+ /** Critical region */
138
+ critical(label: string, fn: () => void): { option(label: string, fn: () => void): void };
139
+ /** Break */
140
+ break(label: string, fn: () => void): void;
141
+ /** Add a comment */
142
+ comment(text: string): void;
143
+ /** Add blank line */
144
+ blank(): void;
145
+ /** Get the Mermaid string */
146
+ toString(): string;
147
+ }
@@ -0,0 +1,138 @@
1
+ /**
2
+ * DiagramStore - Base class for building Mermaid diagrams
3
+ * Accumulates diagram lines with proper indentation
4
+ * @module Mermaid/builders/core/DiagramStore
5
+ */
6
+
7
+ export interface DiagramStoreOptions {
8
+ /** Indentation string (default: ' ' - two spaces) */
9
+ indent?: string;
10
+ }
11
+
12
+ const DEFAULT_OPTIONS: Required<DiagramStoreOptions> = {
13
+ indent: ' ',
14
+ };
15
+
16
+ /**
17
+ * Base store for accumulating Mermaid diagram code
18
+ * Handles indentation and line management
19
+ */
20
+ export class DiagramStore {
21
+ protected lines: string[] = [];
22
+ protected indentLevel = 0;
23
+ protected options: Required<DiagramStoreOptions>;
24
+
25
+ constructor(header: string, options: DiagramStoreOptions = {}) {
26
+ this.options = { ...DEFAULT_OPTIONS, ...options };
27
+ this.lines.push(header);
28
+ }
29
+
30
+ /**
31
+ * Add a line to the diagram with current indentation
32
+ */
33
+ add(line: string): this {
34
+ const indent = this.options.indent.repeat(this.indentLevel);
35
+ this.lines.push(indent + line);
36
+ return this;
37
+ }
38
+
39
+ /**
40
+ * Add a raw line without indentation
41
+ */
42
+ addRaw(line: string): this {
43
+ this.lines.push(line);
44
+ return this;
45
+ }
46
+
47
+ /**
48
+ * Add an empty line
49
+ */
50
+ addBlank(): this {
51
+ this.lines.push('');
52
+ return this;
53
+ }
54
+
55
+ /**
56
+ * Add a comment line
57
+ */
58
+ addComment(comment: string): this {
59
+ return this.add(`%% ${comment}`);
60
+ }
61
+
62
+ /**
63
+ * Increase indentation level
64
+ */
65
+ indent(): this {
66
+ this.indentLevel++;
67
+ return this;
68
+ }
69
+
70
+ /**
71
+ * Decrease indentation level
72
+ */
73
+ dedent(): this {
74
+ if (this.indentLevel > 0) {
75
+ this.indentLevel--;
76
+ }
77
+ return this;
78
+ }
79
+
80
+ /**
81
+ * Execute a callback within an indented block
82
+ * @param header - Block header line
83
+ * @param fn - Callback to execute inside the block
84
+ * @param footer - Block footer line (default: 'end')
85
+ */
86
+ block(header: string, fn: () => void, footer = 'end'): this {
87
+ this.add(header);
88
+ this.indent();
89
+ fn();
90
+ this.dedent();
91
+ this.add(footer);
92
+ return this;
93
+ }
94
+
95
+ /**
96
+ * Execute a callback within a subgraph block
97
+ * @param name - Subgraph name/title
98
+ * @param fn - Callback to execute inside the subgraph
99
+ */
100
+ subgraph(name: string, fn: () => void): this {
101
+ return this.block(`subgraph ${name}`, fn);
102
+ }
103
+
104
+ /**
105
+ * Add direction directive (for subgraphs)
106
+ */
107
+ direction(dir: 'TB' | 'BT' | 'LR' | 'RL'): this {
108
+ return this.add(`direction ${dir}`);
109
+ }
110
+
111
+ /**
112
+ * Get the current indentation string
113
+ */
114
+ getIndent(): string {
115
+ return this.options.indent.repeat(this.indentLevel);
116
+ }
117
+
118
+ /**
119
+ * Get the current indentation level
120
+ */
121
+ getIndentLevel(): number {
122
+ return this.indentLevel;
123
+ }
124
+
125
+ /**
126
+ * Convert the diagram to a Mermaid string
127
+ */
128
+ toString(): string {
129
+ return this.lines.join('\n');
130
+ }
131
+
132
+ /**
133
+ * Get all lines (for debugging)
134
+ */
135
+ getLines(): readonly string[] {
136
+ return this.lines;
137
+ }
138
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Core exports for Mermaid builders
3
+ * @module Mermaid/builders/core
4
+ */
5
+
6
+ export { DiagramStore, type DiagramStoreOptions } from './DiagramStore';
7
+ export * from './types';
8
+ export * from './theme';
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Sanitization utilities for Mermaid diagrams
3
+ * @module Mermaid/builders/core/sanitize
4
+ */
5
+
6
+ /**
7
+ * Characters that need to be escaped or removed in Mermaid labels
8
+ */
9
+ const UNSAFE_CHARS = /["\n\r\\<>{}|]/g;
10
+
11
+ /**
12
+ * Mermaid reserved keywords that cannot be used as node IDs
13
+ */
14
+ const RESERVED_WORDS = new Set([
15
+ 'end',
16
+ 'graph',
17
+ 'subgraph',
18
+ 'direction',
19
+ 'click',
20
+ 'style',
21
+ 'class',
22
+ 'classDef',
23
+ 'linkStyle',
24
+ 'callback',
25
+ ]);
26
+
27
+ /**
28
+ * Sanitize a label for use in Mermaid diagrams
29
+ * Removes or escapes characters that could break the diagram syntax
30
+ */
31
+ export function sanitizeLabel(label: string): string {
32
+ return label
33
+ .replace(UNSAFE_CHARS, '')
34
+ .replace(/&/g, '&amp;')
35
+ .replace(/'/g, "'")
36
+ .trim();
37
+ }
38
+
39
+ /**
40
+ * Convert an ID to a valid Mermaid node ID
41
+ * - Removes special characters
42
+ * - Adds optional prefix to ensure uniqueness
43
+ * - Ensures ID starts with a letter
44
+ * - Escapes reserved Mermaid keywords
45
+ */
46
+ export function toNodeId(id: string, prefix = ''): string {
47
+ // Remove special characters and spaces
48
+ const cleanId = id.replace(/[^a-zA-Z0-9_]/g, '_');
49
+
50
+ // Ensure starts with letter
51
+ let safeId = /^[a-zA-Z]/.test(cleanId) ? cleanId : `n${cleanId}`;
52
+
53
+ // Escape reserved words by adding underscore suffix
54
+ if (RESERVED_WORDS.has(safeId.toLowerCase())) {
55
+ safeId = `${safeId}_`;
56
+ }
57
+
58
+ return prefix ? `${prefix}_${safeId}` : safeId;
59
+ }
60
+
61
+ /**
62
+ * Escape a string for use in quoted Mermaid labels
63
+ */
64
+ export function escapeQuoted(str: string): string {
65
+ return str
66
+ .replace(/\\/g, '\\\\')
67
+ .replace(/"/g, '\\"')
68
+ .replace(/\n/g, '<br/>');
69
+ }
70
+
71
+ /**
72
+ * Format a label with optional subtitle using HTML-like syntax
73
+ */
74
+ export function formatLabel(main: string, subtitle?: string): string {
75
+ const sanitized = sanitizeLabel(main);
76
+ if (!subtitle) return sanitized;
77
+ return `${sanitized}<br/><small>${sanitizeLabel(subtitle)}</small>`;
78
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Theme utilities for Mermaid builders
3
+ *
4
+ * Re-exports palette hooks from @djangocfg/ui-core for convenience.
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * import { useStylePresets, useBoxColors } from './theme';
9
+ *
10
+ * function MyDiagram() {
11
+ * const presets = useStylePresets();
12
+ * const boxes = useBoxColors();
13
+ *
14
+ * const flow = FlowDiagram();
15
+ * flow.style.define('success', presets.success);
16
+ *
17
+ * const { rect } = SequenceDiagram({ ... });
18
+ * rect(boxes.primary, () => { ... });
19
+ * }
20
+ * ```
21
+ *
22
+ * @module Mermaid/builders/core/theme
23
+ */
24
+
25
+ // Re-export from ui-core palette
26
+ export {
27
+ // Types
28
+ type ThemePalette,
29
+ type StyleColors,
30
+ type StylePresets,
31
+ type BoxColors,
32
+
33
+ // Hooks
34
+ useThemePalette,
35
+ useStylePresets,
36
+ useBoxColors,
37
+
38
+ // Utils
39
+ hslToHex,
40
+ hslToRgbString,
41
+ hslToRgba,
42
+ } from '@djangocfg/ui-core/styles/palette';